Android View自定义ImageView实现圆角

1,420 阅读1分钟

本篇 Blog 记录圆角 ImageView 的实现

先说下思路

  1. 获取配置属性
  2. 判断裁剪方式
  3. 绘制

下面正式开始

获取配置属性

我们现在 attrs 中定义相关属性

	<declare-styleable >
        <attr  />
        <attr  />
        <attr  />
        <attr  />
        <attr  />
    </declare-styleable>

上述属性分别定义了整体圆角和四个单独的圆角

之后分别获取相关属性进行设置。

		// 获取属性
        TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.RoundImageView);
        radius = typedArray.getDimensionPixelOffset(R.styleable.RoundImageView_radius, defaultRadius);
        leftTopRadius = typedArray.getDimensionPixelOffset(R.styleable.RoundImageView_leftTopRadius, defaultRadius);
        rightTopRadius = typedArray.getDimensionPixelOffset(R.styleable.RoundImageView_rightTopRadius, defaultRadius);
        leftBottomRadius = typedArray.getDimensionPixelOffset(R.styleable.RoundImageView_leftBottomRadius, defaultRadius);
        rightBottomRadius = typedArray.getDimensionPixelOffset(R.styleable.RoundImageView_rightBottomRadius, defaultRadius);
        if (radius != 0) {
            if (leftTopRadius == 0) {
                leftTopRadius = radius;
            }
            if (rightTopRadius == 0) {
                rightTopRadius = radius;
            }
            if (leftBottomRadius == 0) {
                leftBottomRadius = radius;
            }
            if (rightBottomRadius == 0) {
                rightBottomRadius = radius;
            }
        }
        typedArray.recycle();

判断裁剪方式

在获取圆角设置之后,我们需要进行图片宽高和圆角值的大小对比。
在图片大于圆角值时再进行裁剪

		// 保证图片宽高大于圆角宽高, 获取圆角的宽高
        // 取横着大的长度
        int maxLeft = Math.max(leftTopRadius, leftBottomRadius);
        int maxRight = Math.max(rightTopRadius, rightBottomRadius);
        int minWidth = maxLeft + maxRight;
        // 取竖着大的长度
        int maxTop = Math.max(leftTopRadius, rightTopRadius);
        int maxBottom = Math.max(leftBottomRadius, rightBottomRadius);
        int minHeight = maxTop + maxBottom;
        if (width > minWidth && height > minHeight) {
            Path path = new Path();
            //四个角:右上,右下,左下,左上
            path.moveTo(leftTopRadius, 0);
            path.lineTo(width - rightTopRadius, 0);
            path.quadTo(width, 0, width, rightTopRadius);

            path.lineTo(width, height - rightBottomRadius);
            path.quadTo(width, height, width - rightBottomRadius, height);

            path.lineTo(leftBottomRadius, height);
            path.quadTo(0, height, 0, height - leftBottomRadius);

            path.lineTo(0, leftTopRadius);
            path.quadTo(0, 0, leftTopRadius, 0);

            canvas.clipPath(path);
        }
        super.onDraw(canvas);

最后调用 super.onDraw(canvas) 进行绘制。

我们在使用时,和调用系统控件一样使用就可以

		<com.xxxx.ui.RoundImageView
            android:id="@+id/riv_adapter_merchant_dishes_image"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_marginStart="10dp"
            android:scaleType="fitXY"
            android:src="@drawable/mine_user_photo"
            app:layout_constraintBottom_toTopOf="@+id/tv_adapter_line"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:leftBottomRadius="10dp"
            app:leftTopRadius="10dp"
            app:rightBottomRadius="10dp"
            app:rightTopRadius="10dp" />

最后附上完整代码地址:

GItHub AndroidCustomView-RoundImageView
顺便帮忙 star 一下更感谢!