美文网首页Android深入
Android 圆角ImageView实现

Android 圆角ImageView实现

作者: 小仙女喂得猪呀 | 来源:发表于2021-11-17 16:06 被阅读0次

    由于项目之前的CircleImageView的实现方式是针对bitmap去操作的,不是很优雅,且在用glide加载gif的时候会偶现一个bitmap的转换异常,所以借此机会尽可能优雅的实现了一个专用的圆角ImageView,分享给各位大佬们,如有不当之处,请多多指点

    for kotlin

    class CircleImageView @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null
    ) : AppCompatImageView(context, attrs) {
    
    
        private var mRadius: Int = 0
        private val viewOutlineProvider: ViewOutlineProvider by lazy {
            @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
            object : ViewOutlineProvider() {
                override fun getOutline(view: View?, outline: Outline?) {
                    val width = width
                    val height = height
                    outline?.setRoundRect(0, 0, width, height, mRadius.toFloat())
                }
    
            }
        }
        private var path: Path?
        private var rect: RectF?
    
    
        init {
            val obtainStyledAttributes =
                context.obtainStyledAttributes(attrs, R.styleable.CircleImageViewV3)
            obtainStyledAttributes.let {
                mRadius =
                    it.getInt(
                        R.styleable.CircleImageViewV3_CustomizeRadiusV3,
                        (getContext().resources.getDimension(R.dimen.dp_10)).toInt()
                    )
                it.recycle()
                path = Path()
                rect = RectF()
                if (ModuleUtils.isRoundCornerMask()) { //只对小度做圆角处理
                    setRound(mRadius)
                }
            }
        }
    
        //设置圆角图片
        fun setRound(radius: Int) = apply {
            val isChange = radius != mRadius
            mRadius = radius
            if (mRadius != 0) {
                if (Build.VERSION_CODES.LOLLIPOP <= Build.VERSION.SDK_INT) {
                    outlineProvider = viewOutlineProvider
                    clipToOutline = true
    
                }
                val width = width.toFloat()
                val height = height.toFloat()
                rect?.set(0f, 0f, width, height)
                path?.reset()
                rect?.let { path?.addRoundRect(it,mRadius.toFloat(),mRadius.toFloat(),Path.Direction.CW) }
            } else {
                if (Build.VERSION_CODES.LOLLIPOP <= Build.VERSION.SDK_INT) {
                    clipToOutline = false
                }
            }
    
            if (isChange) {
                if (Build.VERSION_CODES.LOLLIPOP <= Build.VERSION.SDK_INT) {
                    invalidateOutline()
                }
            }
    
        }
    
        override fun draw(canvas: Canvas?){
            var clip = false
            if (Build.VERSION_CODES.LOLLIPOP > Build.VERSION.SDK_INT && mRadius > 0) {
                clip = true
                canvas?.save()
                path?.let { canvas?.clipPath(it) }
    
            }
            super.draw(canvas)
            if (clip) {
                canvas?.restore()
            }
        }
    
    
    }
    

    for java

    package com.wj.motiondemo;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Outline;
    import android.graphics.Path;
    import android.graphics.RectF;
    import android.os.Build;
    import android.util.AttributeSet;
    import android.view.View;
    import android.view.ViewOutlineProvider;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.appcompat.widget.AppCompatImageView;
    
    /**
     * @Author : jiyajie
     * @Time : On 2021/11/23 09:45
     * @Description : CircleImageViewV2
     */
    public class CircleImageViewV2 extends AppCompatImageView {
    
        private int mRadius;
        private Path mPath;
        private RectF mRectF;
        private ViewOutlineProvider viewOutlineProvider;
    
        public CircleImageViewV2(@NonNull Context context) {
            this(context, null);
        }
    
        public CircleImageViewV2(@NonNull Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public CircleImageViewV2(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context, attrs);
        }
    
        private void init(Context context, AttributeSet attrs) {
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleImageViewV2);
            mRadius = (int) typedArray.getDimension(R.styleable.CircleImageViewV2_CustomizeRadiusV2, 0f);
            typedArray.recycle();
            setmRadius(mRadius);
        }
    
        //更新图片圆角
        public void setmRadius(int radius) {
            boolean isChange = radius != mRadius;
            mRadius = radius;
            if (mPath == null) {
                mPath = new Path();
            }
            if (mRectF == null) {
                mRectF = new RectF();
            }
            if (mRadius != 0) {
                if (Build.VERSION_CODES.LOLLIPOP <= Build.VERSION.SDK_INT) {
                    if (viewOutlineProvider == null) {
                        viewOutlineProvider = new ViewOutlineProvider() {
                            @Override
                            public void getOutline(View view, Outline outline) {
                                int width = getWidth();
                                int height = getHeight();
                                outline.setRoundRect(0,0,width,height,mRadius);
                            }
                        };
                    }
                    setOutlineProvider(viewOutlineProvider);
                    setClipToOutline(true);
                }
                mRectF.set(0, 0, getWidth(), getHeight());
                mPath.reset();
                mPath.addRoundRect(mRectF, mRadius, mRadius, Path.Direction.CW);
            } else {
                if (Build.VERSION_CODES.LOLLIPOP <= Build.VERSION.SDK_INT) {
                    setClipToOutline(false);
                }
            }
    
            if (isChange) {
                if (Build.VERSION_CODES.LOLLIPOP <= Build.VERSION.SDK_INT) {
                    invalidateOutline();
                }
            }
    
        }
    
    
        @Override
        public void draw(Canvas canvas) {
            boolean clip = false;
            if (Build.VERSION_CODES.LOLLIPOP > Build.VERSION.SDK_INT && mRadius > 0) {
                clip = true;
                canvas.save();
                canvas.clipPath(mPath);
            }
            super.draw(canvas);
            if (clip) {
                canvas.restore();
            }
        }
    }
    
    

    效果如图:


    WechatIMG8222.png

    相关文章

      网友评论

        本文标题:Android 圆角ImageView实现

        本文链接:https://www.haomeiwen.com/subject/sbadtrtx.html