Android 中支持背景颜色的圆角 ImageView?

Round cornered ImageView supporting background color in Android?

我想做一个圆角ImageView。但我希望它有背景颜色(例如,#000)。使用当前的解决方案(构建扩展的圆角视图或绘制圆角位图)背景 属性 会破坏效果,因为视图将位于黑色矩形中(见下图)。

是否可以实现背景区域也是圆角的视图?

PS,为什么我想要背景颜色:我允许用户上传非方形图像,但我的图像查看区域是方形的,所以我想要一种颜色 "align" 它们(参见下图 - 我希望红色部分是圆形的)。

可以使用 Lollipop 的轮廓和 pre-Lollipop 路径来完成圆角。参见:

  1. 准备口罩

    if (cornerRadius > 0) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            setClipToOutline(true);
            setOutlineProvider(ShadowShape.viewOutlineProvider);
        } else {
            cornersMask = new Path();
            cornersMask.addRoundRect(new RectF(0, 0, getWidth(), getHeight()), cornerRadius, cornerRadius, Path.Direction.CW);
            cornersMask.setFillType(Path.FillType.INVERSE_WINDING);
        }
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
            setOutlineProvider(ViewOutlineProvider.BOUNDS);
    }
    
  2. 绘制(Canvas)方法

    if (cornerRadius > 0 && getWidth() > 0 && getHeight() > 0 && Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT_WATCH) {
        int saveFlags = Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG;
        int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, saveFlags);
    
        super.draw(canvas);
    
        paint.setXfermode(pdMode);
        canvas.drawPath(cornersMask, paint);
    
        canvas.restoreToCount(saveCount);
        paint.setXfermode(null);
    } else {
        super.draw(canvas);
    }
    
  3. 和缺少的 viewOutlineProvider

        viewOutlineProvider = new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                ShadowShape shadowShape = ((ShadowView) view).getShadowShape();
                if (shadowShape == RECT) {
                    outline.setRect(0, 0, view.getWidth(), view.getHeight());
                } else if (shadowShape == ROUND_RECT) {
                    outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), ((CornerView) view).getCornerRadius());
                } else if (shadowShape == CIRCLE) {
                    outline.setOval(0, 0, view.getWidth(), view.getHeight());
                }
            }
        };
    

和图像:

您可以随意修改此代码。您可以将图像和背景单独或一起剪切成任何形状。有关详细信息,请查看 github.

上的代码