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

时间:2016-03-21 01:56:34

标签: android android-custom-view

我希望能够在布局xml中设置高程参数时为我的自定义视图添加阴影。我可以添加阴影,但它被应用为方形而不是圆角形状。我不知道在哪里添加代码以使其四舍五入。它应该在哪里以及如何?

这就是现在的样子:

http://www.codeproject.com/Articles/1086714/A-Template-For-Using-Datagrid-in-Monitoring-UI

这是自定义视图:

    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 个答案:

答案 0 :(得分:1)

我刚刚注意到我只需要在ViewOutlineProvider自定义类中调用另一种方法:

static_assert(ctti::type_id<int>() != ctti::type_id<float>(), "compile-time type-id comparison");

constexpr auto hash = ctti::type_id<int>().hash();

现在它工作正常。