自定义视图:为其阴影构建带圆角的轮廓

3
我希望能在设置布局xml中的高度参数时,为我的自定义视图添加阴影。我已经成功添加了阴影,但它被应用为正方形而不是圆角形状。我不知道在哪里添加代码使其变成圆角。应该在哪里添加代码?如何添加?

现在它看起来像这样:

enter image description here

这是自定义视图:

    public class RoundedFrameLayout extends FrameLayout {
    private final static float CORNER_RADIUS = 15.0f;

    Bitmap maskBitmap;
    private Paint paint, maskPaint;
    private float cornerRadius;

    DisplayMetrics metrics;

    public RoundedFrameLayout(Context context) {
        super(context);
        init(context, null, 0);
    }

    public RoundedFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public RoundedFrameLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {

        metrics = context.getResources().getDisplayMetrics();
        cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS, metrics);

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
        maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

        setWillNotDraw(false);
    }

    @Override
    public void draw(Canvas canvas) {

        cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) canvas.getWidth() * 0.05f, metrics);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

            setOutlineProvider(new CustomOutline(canvas.getWidth(), canvas.getHeight()));
        }

        Bitmap offscreenBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas offscreenCanvas = new Canvas(offscreenBitmap);

        super.draw(offscreenCanvas);

        maskBitmap = createMask(canvas.getWidth(), canvas.getHeight());

        offscreenCanvas.drawBitmap(maskBitmap, 0f, 0f, maskPaint);

        canvas.drawBitmap(offscreenBitmap, 0f, 0f, paint);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private class CustomOutline extends ViewOutlineProvider {

        int width;
        int height;

        CustomOutline(int width, int height) {

            this.width = width;
            this.height = height;
        }

        @Override
        public void getOutline(View view, Outline outline) {

            outline.setRect(0, 0, width, height);
        }
    }

    private Bitmap createMask(int width, int height) {

        Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
        Canvas canvas = new Canvas(mask);

        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.WHITE);

        canvas.drawRect(0, 0, width, height, paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        canvas.drawRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, paint);

        return mask;
    }
}
1个回答

3
我刚刚注意到,只需要在ViewOutlineProvider自定义类中调用不同的方法:
    @Override
    public void getOutline(View view, Outline outline) {

        outline.setRoundRect(0, 0, width, height, radius);
    }

现在它运行得很好。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接