網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
Fresco是FaceBook開(kāi)源的Android平臺(tái)圖片加載庫(kù),可以從網(wǎng)絡(luò),從本地文件系統(tǒng),本地資源加載圖片
Fresco本身已經(jīng)實(shí)現(xiàn)了圓角以及圓形圖片的功能。
工作中,遇到圓形頭像的時(shí)候,UI通常會(huì)給我們這樣一張圖作為默認(rèn)圖片
理論上來(lái)講,只需要加入下列這行代碼,就可以完成這部分工作了
app:placeholderImage="@drawable/ic_avatar_default"
然而圓形圖片本身已經(jīng)是圓形的了,在有些機(jī)型上就出現(xiàn)了這個(gè)樣式。
搜索了一波,自帶的屬性都不能解決這個(gè)問(wèn)題,干脆自己來(lái)定義這個(gè)圓形的實(shí)現(xiàn)吧,同時(shí)Fresco自帶的圓角效果只能保證使用統(tǒng)一的半徑,想要讓四個(gè)圓角的半徑不同,只能在java文件中設(shè)置,不夠靈活,定義圓角半徑的屬性也需要做些變更。
思路:自定義RoundImageView繼承自 SimpleDraweeVie,具備其所有的功能。
Canvas的clipPath(Path path)可以根據(jù)Path,將Canvas剪裁成我們想要的圖形。
public class RoundImageView extends SimpleDraweeView { ? ?? ? ? private final static int DEFAULT_VALUE = 0; ? ? private float mWidth; ? ? private float mHeight; ? ? private Path mPath; ? ? // 圓角角度 ? ? private float mCornerRadius; ? ? // 左上角圓角角度 ? ? private float mLeftTopRadius; ? ? // 右上角圓角角度 ? ? private float mRightTopRadius; ? ? // 右下角圓角角度 ? ? private float mRightBottomRadius; ? ? // 左下角圓角角度 ? ? private float mLeftBottomRadius; ? ? // 是否使用圓形圖片 ? ? private boolean mAsCircle; ? ? // 圓形圖片半徑 ? ? private float mRadius; ? ?? ? ? public RoundImageView(Context context) { ? ? ? ? this(context, null); ? ? } ? ? public RoundImageView(Context context, AttributeSet attrs) { ? ? ? ? this(context, attrs, 0); ? ? } ? ? public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) { ? ? ? ? super(context, attrs, defStyleAttr); ? ? ? ? initData(); ? ? ? ? initAttrs(context, attrs); ? ? } ? ?? ? ? private void initData() { ? ? ? ? mPath = new Path(); ? ? } ? ? private void initAttrs(Context context, AttributeSet attrs) { ? ? ? ? TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView); ? ? ? ? mCornerRadius = typedArray.getDimension(R.styleable.RoundImageView_cornerRadius, DEFAULT_VALUE); ? ? ? ? mAsCircle = typedArray.getBoolean(R.styleable.RoundImageView_asCircle, false); ? ? ? ? if (mCornerRadius <= 0) { ? ? ? ? ? ? // 說(shuō)明用戶沒(méi)有設(shè)置四個(gè)圓角的有效值,此時(shí)四個(gè)圓角各自使用自己的值 ? ? ? ? ? ? mLeftTopRadius = typedArray.getDimension(R.styleable.RoundImageView_leftTopRadius, DEFAULT_VALUE); ? ? ? ? ? ? mRightTopRadius = typedArray.getDimension(R.styleable.RoundImageView_rightTopRadius, DEFAULT_VALUE); ? ? ? ? ? ? mRightBottomRadius = typedArray.getDimension(R.styleable.RoundImageView_rightBottomRadius, DEFAULT_VALUE); ? ? ? ? ? ? mLeftBottomRadius = typedArray.getDimension(R.styleable.RoundImageView_leftBottomRadius, DEFAULT_VALUE); ? ? ? ? } else { ? ? ? ? ? ? // 使用了統(tǒng)一的圓角,因此使用mCornerRadius統(tǒng)一的值 ? ? ? ? ? ? mLeftTopRadius = mCornerRadius; ? ? ? ? ? ? mRightTopRadius = mCornerRadius; ? ? ? ? ? ? mRightBottomRadius = mCornerRadius; ? ? ? ? ? ? mLeftBottomRadius = mCornerRadius; ? ? ? ? } ? ? ? ?? ? ? ? ? typedArray.recycle(); ? ? } ? ? @Override ? ? protected void onLayout(boolean changed, int left, int top, int right, int bottom) { ? ? ? ? super.onLayout(changed, left, top, right, bottom); ? ? ? ? mWidth = getWidth(); ? ? ? ? mHeight = getHeight(); ? ? ? ? // 如果開(kāi)啟了圓形標(biāo)記 ? ? ? ? if (mAsCircle) { ? ? ? ? ? ? mRadius = Math.min(mWidth / 2, mHeight / 2); ? ? ? ? } ? ? } ? ? @Override ? ? protected void onDraw(Canvas canvas) { ? ? ? ? // 如果開(kāi)啟了圓形標(biāo)記,圓形圖片的優(yōu)先級(jí)高于圓角圖片 ? ? ? ? if(mAsCircle) { ? ? ? ? ? ? drawCircleImage(canvas); ? ? ? ? } else { ? ? ? ? ? ? drawCornerImage(canvas); ? ? ? ? } ? ? ? ? super.onDraw(canvas); ? ? } ? ? /** ? ? ?* 畫(huà)中間圓形 ? ? ?* @param canvas ? ? ?*/ ? ? private void drawCircleImage(Canvas canvas) { ? ? ? ? mPath.addCircle(mWidth / 2, mHeight / 2, mRadius, Path.Direction.CW); ? ? ? ? canvas.clipPath(mPath); ? ? } ? ? /** ? ? ?* 畫(huà)圓角 ? ? ?* @param canvas ? ? ?*/ ? ? private void drawCornerImage(Canvas canvas) { ? ? ? ? if (mWidth > mCornerRadius && mHeight > mCornerRadius) { ? ? ? ? ? ? // 設(shè)置四個(gè)角的x,y半徑值 ? ? ? ? ? ? float[] radius = {mLeftTopRadius, mLeftTopRadius, mRightTopRadius, mRightTopRadius, mRightBottomRadius, mRightBottomRadius, mLeftBottomRadius, mLeftBottomRadius}; ? ? ? ? ? ? mPath.addRoundRect(new RectF(0,0, mWidth, mHeight), radius, Path.Direction.CW); ? ? ? ? ? ? canvas.clipPath(mPath); ? ? ? ? } ? ? } }
attr屬性如下
? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
原文鏈接:https://blog.csdn.net/YX_BB/article/details/104561359
相關(guān)推薦
- 2022-10-24 React中的生命周期和子組件_React
- 2022-06-29 C#集合之自定義集合類_C#教程
- 2022-09-04 Python中函數(shù)的參數(shù)類型詳解_python
- 2024-03-20 redis閃退的三大解決辦法(windows版本)
- 2022-03-17 解決.Net?Core項(xiàng)目發(fā)布在IIS上訪問(wèn)404的問(wèn)題_實(shí)用技巧
- 2022-07-21 python:實(shí)現(xiàn)balanced parentheses平衡括號(hào)表達(dá)式算法(附完整源碼)
- 2022-09-12 Go1.18新特性工作區(qū)模糊測(cè)試及泛型的使用詳解_Golang
- 2022-08-18 Android新建水平節(jié)點(diǎn)進(jìn)度條示例_Android
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支