Android基于Fresco实现圆角和圆形图片

Tina ·
更新时间:2024-11-10
· 1133 次阅读

Fresco是FaceBook开源的Android平台图片加载库,可以从网络,从本地文件系统,本地资源加载图片

Fresco本身已经实现了圆角以及圆形图片的功能。

<!--圆形图片,一般用作头像--> <com.facebook.drawee.view.SimpleDraweeView     android:id="@+id/iv_avatar"     android:layout_width="40dp"     android:layout_height="40dp"     app:placeholderImage="@drawable/ic_avatar_default"     app:roundAsCircle="true"/> <!--圆角图片,为了美观大多数图片都会有这样的处理。--> <!--当图片为正方形的时候,将roundedCornerRadius设置为边长的一半,也可以形成圆形图片的效果--> <com.facebook.drawee.view.SimpleDraweeView     android:id="@+id/iv_avatar"     android:layout_width="40dp"     android:layout_height="40dp"     app:placeholderImage="@drawable/ic_avatar_default"     app:roundedCornerRadius="5dp"/>

工作中,遇到圆形头像的时候,UI通常会给我们这样一张图作为默认图片

理论上来讲,只需要加入下列这行代码,就可以完成这部分工作了

app:placeholderImage="@drawable/ic_avatar_default"

然而圆形图片本身已经是圆形的了,在有些机型上就出现了这个样式。

搜索了一波,自带的属性都不能解决这个问题,干脆自己来定义这个圆形的实现吧,同时Fresco自带的圆角效果只能保证使用统一的半径,想要让四个圆角的半径不同,只能在java文件中设置,不够灵活,定义圆角半径的属性也需要做些变更。

思路:自定义RoundImageView继承自 SimpleDraweeVie,具备其所有的功能。
Canvas的clipPath(Path path)可以根据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) {             // 说明用户没有设置四个圆角的有效值,此时四个圆角各自使用自己的值             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 {             // 使用了统一的圆角,因此使用mCornerRadius统一的值             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();         // 如果开启了圆形标记         if (mAsCircle) {             mRadius = Math.min(mWidth / 2, mHeight / 2);         }     }     @Override     protected void onDraw(Canvas canvas) {         // 如果开启了圆形标记,圆形图片的优先级高于圆角图片         if(mAsCircle) {             drawCircleImage(canvas);         } else {             drawCornerImage(canvas);         }         super.onDraw(canvas);     }     /**      * 画中间圆形      * @param canvas      */     private void drawCircleImage(Canvas canvas) {         mPath.addCircle(mWidth / 2, mHeight / 2, mRadius, Path.Direction.CW);         canvas.clipPath(mPath);     }     /**      * 画圆角      * @param canvas      */     private void drawCornerImage(Canvas canvas) {         if (mWidth > mCornerRadius && mHeight > mCornerRadius) {             // 设置四个角的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属性如下

<!--适配android10的图片控件-->     <declare-styleable name="RoundImageView">         <!--圆形图片-->         <attr name="asCircle" format="boolean"/>         <!--左上角圆角半径-->         <attr name="leftTopRadius" format="dimension"/>         <!--右上角圆角半径-->         <attr name="rightTopRadius" format="dimension"/>         <!--右下角圆角半径-->         <attr name="rightBottomRadius" format="dimension"/>         <!--左下角圆角半径-->         <attr name="leftBottomRadius" format="dimension"/>         <!--四个圆角半径,会覆盖上边四个圆角值-->         <attr name="cornerRadius" format="dimension"/> </declare-styleable>



图片 Android

需要 登录 后方可回复, 如果你还没有账号请 注册新账号