【问题标题】:Create Vector Drawable with Drop Shadow to Overlay an Image创建带有阴影的矢量可绘制对象以覆盖图像
【发布时间】:2017-02-10 17:18:35
【问题描述】:

我想实现一个看起来像“所需”图像的布局,作为通知用户一些基本操作的初始应用状态的一部分。现在我得到了“实际”图像。

我需要任何可绘制/图像的背景图像,该图像具有从左下角到右上角倾斜的叠加层,并且具有任何颜色。这还必须在任何数量的设备、手机或平板电脑上以相同的形状进行扩展,并支持回 SDK 16。

到目前为止,我一直没有使用矢量图像创建倾斜可绘制对象,然后使用FrameLayout 将其覆盖在背景图像之上以获得分层效果。我不确定这是否是实现此目的的最佳方式,但我希望覆盖可绘制为矢量可绘制或九个补丁,这样它就不会在更宽的布局上像素化。

layout/view_layout.xml

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/background_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/bg_image"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="52dp"
        android:layout_gravity="bottom"
        android:background="@drawable/overlay"/>

</FrameLayout>

drawable/overlay.xml

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

    <path
        android:fillColor="#fff"
        android:pathData="M48,0 L48,36 L0,36 L0,32 Z"/>

</vector>

如果有人知道如何向矢量可绘制对象添加阴影(我一直无法找到方法),或者如果有更好的方法,任何帮助或建议将不胜感激。谢谢!

【问题讨论】:

  • 我认为您需要创建一个像这样但圆形(圆形)的图层 -- stackoverflow.com/questions/26356060/…
  • @Tasos 这不是我想要的。似乎所选答案仅使用矩形形状,由于倾斜的工作方式,阴影需要跟随整个倾斜而不会被分离。我也不认为创建附加三个视图是我更愿意做的事情。不过感谢您的建议!

标签: android android-vectordrawable


【解决方案1】:

我最终解决这个问题的方法是扩展ImageView 类并添加自定义绘制逻辑来覆盖图像。它没有像我希望的那样使用 Vector Drawable,但它确实呈现了我希望的确切效果。这是我班级的基本大纲:

public class CoveredImageView extends ImageView {

    static float DENSITY = 1f;
    static final float SHADOW_DISTANCE = 10f;
    static final int SHADOW_COLOR = 0xAA000000;

    Path path;
    Paint paint;

    Point p1, p2, p3;

    public CoveredImageView(Context context) {
        this(context, null);
    }

    public CoveredImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CoveredImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    void init(@NonNull Context context) {
        DENSITY = context.getResources().getDisplayMetrics().density;

        path = new Path();
        paint = new Paint();
        p1 = new Point();
        p2 = new Point();
        p3 = new Point();

        // Required to make the ShadowLayer work properly
        setLayerType(LAYER_TYPE_SOFTWARE, null);
    }

    void updateDrawVariables() {
        int shadowSize = (int)(SHADOW_DISTANCE * DENSITY);

        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.FILL);
        paint.setAntiAlias(true);
        paint.setShadowLayer(shadowSize, 0, -1, SHADOW_COLOR);

        // Offset the actual position by the shadow size so
        int left = 0 - shadowSize;
        int right = getMeasuredWidth() + shadowSize;
        int bottom = getMeasuredHeight();

        p1.set(left, bottom);
        p2.set(right, bottom - (int)(52 * DENSITY));
        p3.set(right, bottom);

        path.setFillType(Path.FillType.EVEN_ODD);
        path.moveTo(p1.x, p1.y);
        path.lineTo(p2.x, p2.y);
        path.lineTo(p3.x, p3.y);
        // Move the path shape down so that the shadow doesn't "fade" at the left and right edges
        path.lineTo(p3.x, p3.y + shadowSize);
        path.lineTo(p1.x, p1.y + shadowSize);
        path.close();
    }

    @Override
    public void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        // Update all the drawing variables if the layout values have changed
        if(changed) {
            updateDrawVariables();
        }
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // Paint the current path values that were set after onLayout()
        canvas.drawPath(path, paint);
    }
}

【讨论】:

  • 你是否尝试过 (android:strokeColor) (android:strokeWidth) 在矢量可绘制的路径中——例如 (android:strokeColor="#50FFFFFF" android:strokeWidth="5") 将给你 50% 的白色透明度,厚度为 5 给你一个围绕向量的盒子阴影developer.android.com/reference/android/graphics/drawable/…
  • @Tasos 是的,实际上我最初尝试过,但问题是笔触颜色无法处理真正的渐变,除非您使用 SDK 24+,否则它只能处理纯色。我的应用程序需要支持 SDK 16+,因此无法正常工作。不过谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-05
  • 2021-07-28
  • 2016-05-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多