如何向矢量可绘制对象添加阴影? [英] How to add shadow to vector drawable?

查看:61
本文介绍了如何向矢量可绘制对象添加阴影?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个矢量可绘制对象 (category_bg),我将它用作 FrameLayout 的背景

I have a vector drawable (category_bg) and I'm using it as a background to a FrameLayout

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="200dp"
    android:height="100dp"
    android:viewportWidth="600"
    android:viewportHeight="450">

    <path
        android:fillColor="#FFFFFF"
        android:fillType="evenOdd"
        android:pathData="M24.8,21.4c0,0,73.8-8.1,161.3-8.1c77.7,0,153.9,2,231.9,2c88.5,0,156.3,6,156.3,6c5.6,0,10.1,4.5,10.1,10.1
c0,0,2,41.2,2,134.1c0,68.5,4,77.9,4,139.1c0,65-6,114.9-6,114.9c0,5.6-4.5,10.1-10.1,10.1c0,0-32.1,7.1-80.6,7.1
c-47.5,0-99.6-7.1-164.7-7.1c-77.6,0-160.9,6-219.4,6c-52.8,0-84.7-6-84.7-6c-5.6,0-10.1-4.5-10.1-10.1c0,0-4-46.6-4-111.9
c0-85.8-1-102.9-1-183.5c0-55,5-92.7,5-92.7C14.7,25.9,19.2,21.4,24.8,21.4z" />
</vector>

我想为可绘制的矢量添加阴影

I would like to add shadow to the vector drawable

我的 xml 文件

<FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/category_bg"
        android:padding="3dp">


        <com.shaker.materialComponents.view.MaskableFrameLayout
            android:id="@+id/category"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:mask="@drawable/pic_mask"
            app:porterduffxfermode="DST_IN">

            <com.shaker.materialComponents.view.AspectRatioImageView
                android:id="@+id/image"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:adjustViewBounds="true"
                android:scaleType="centerCrop"
                android:src="@drawable/meal"
                app:aspectRatio="0.75"
                app:aspectRatioEnabled="true"
                app:dominantMeasurement="width"/>


            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                android:background="@drawable/category_gradient_bg"
                android:gravity="center"
                android:orientation="horizontal"
                android:paddingBottom="16dp"
                android:paddingLeft="16dp"
                android:paddingRight="16dp"
                android:paddingTop="20dp">


                <com.shaker.materialComponents.view.MaterialTextView
                    android:id="@+id/name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:ellipsize="end"
                    android:lines="1"
                    android:text="Salads"
                    android:textColor="#fff"
                    android:textSize="18dp"
                    android:textStyle="bold"
                    app:customFont="GothamRounded-Bold.ttf"/>

                <ImageView
                    android:id="@+id/expand_btn"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:src="@drawable/expand_button"/>

            </LinearLayout>

        </com.shaker.materialComponents.view.MaskableFrameLayout>

当前结果

添加阴影后应该是这样的

after adding shadow it should be like this

推荐答案

所有的荣誉都归于 pskink,他在他的评论中将此代码链接到问题.不幸的是,这似乎仍然是唯一的解决方案

All kudos for this goes to pskink, who linked this code in his comment to the question. Unfortunately this still seems to be the only solution out there

// test code
    View v = new View(this);
    setContentView(v);

    Drawable source = getResources().getDrawable(R.drawable.chrome);
    Drawable mask = getResources().getDrawable(R.drawable.chrome_mask);;
    int[] colors = {
            Color.RED, Color.BLACK
    };
    Drawable shadow = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, colors);
    Shape s = new S(this, source, mask, shadow, 8);
    v.setBackground(new ShapeDrawable(s));

// end of test code

~

class S extends Shape {
    Context ctx;
    Drawable source;
    Drawable mask;
    Drawable shadow;
    float shadowRadius;
    Matrix matrix = new Matrix();
    Bitmap bitmap;

    public S(Context ctx, Drawable source, Drawable mask, Drawable shadow, float shadowRadius) {
        this.ctx = ctx;
        this.source = source;
        this.mask = mask;
        this.shadow = shadow;
        this.shadowRadius = shadowRadius;
    }

    @Override
    protected void onResize(float width, float height) {
        int intrinsicWidth = source.getIntrinsicWidth();
        int intrinsicHeight = source.getIntrinsicHeight();
        source.setBounds(0, 0, intrinsicWidth, intrinsicHeight);
        mask.setBounds(0, 0, intrinsicWidth, intrinsicHeight);
        shadow.setBounds(0, 0, intrinsicWidth, intrinsicHeight);

        RectF src = new RectF(0, 0, intrinsicWidth, intrinsicHeight);
        RectF dst = new RectF(0, 0, width, height);
        matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);

        Paint p = new Paint();
        p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bitmap);

        shadow.draw(c);
        c.saveLayer(null, p, Canvas.ALL_SAVE_FLAG);
        mask.draw(c);
        c.restore();
        bitmap = blurRenderScript(bitmap);

        c = new Canvas(bitmap);
        int count = c.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
        source.draw(c);
        c.saveLayer(null, p, Canvas.ALL_SAVE_FLAG);
        mask.draw(c);
        c.restoreToCount(count);
    }

    @Override
    public void draw(Canvas canvas, Paint paint) {
        canvas.drawColor(0xffdddddd);
        canvas.drawBitmap(bitmap, matrix, null);
    }

    Bitmap blurRenderScript(Bitmap input) {
        Bitmap output = Bitmap.createBitmap(input.getWidth(), input.getHeight(), input.getConfig());
        RenderScript rs = RenderScript.create(ctx);
        ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        Allocation inAlloc = Allocation.createFromBitmap(rs, input, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE);
        Allocation outAlloc = Allocation.createFromBitmap(rs, output);
        script.setRadius(shadowRadius);
        script.setInput(inAlloc);
        script.forEach(outAlloc);
        outAlloc.copyTo(output);
        rs.destroy();
        return output;
    }
}

这篇关于如何向矢量可绘制对象添加阴影?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆