如何在不进行缩放的情况下将图层列表中的矢量绘图居中

时间:2016-01-16 19:25:07

标签: android android-drawable layer-list android-vectordrawable

我尝试在VectorDrawable中使用LayerList而不缩放向量。例如:

<layer-list>
    <item android:drawable="@color/grid_item_activated"/>
    <item android:gravity="center" android:drawable="@drawable/ic_check_white_48dp"/>
</layer-list>

drawable ic_check_white_48dp id定义为:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="48dp"
        android:height="48dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</vector>

所需的效果是检查图标在图层可绘制的中心,无需缩放。问题是,上面的图层列表会导致检查图标缩放以适合图层大小。

如果我用每个密度的PNG替换vector drawable并且修改图层列表,可以产生所需的效果:

<layer-list>
    <item android:drawable="@color/grid_item_activated"/>
    <item>
        <bitmap android:gravity="center" android:src="@drawable/ic_check_white_48dp"/>
    </item>
</layer-list>

我有什么办法可以使用VectorDrawable吗?

4 个答案:

答案 0 :(得分:17)

我遇到了同样的问题,试图将矢量drawables放在分层列表中。

我有一个解决方法,它不完全相同但它的工作原理,您需要为整个drawable设置一个大小并向向量项添加填充:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <size android:height="120dp" android:width="120dp"/>
            <solid android:color="@color/grid_item_activated"/>
        </shape>
    </item>
    <item android:top="24dp"
          android:bottom="24dp"
          android:left="24dp"
          android:right="24dp"
          android:drawable="@drawable/ic_check_white_48dp"/>
</layer-list>

上面形状的大小设置了整个drawable的大小,在本例中为120dp,第二个项目的填充,在本例中为24dp,以矢量图像为中心。

它与使用gravity="center"不同,但它在API 21和22中使用向量的工作方式。

答案 1 :(得分:10)

一直在努力解决同样的问题。我找到解决这个问题的唯一方法就是设置可绘制的尺寸并使用重力来对齐它:

<layer-list>
    <item android:drawable="@color/grid_item_activated"/>
     <item
        android:gravity="center"
        android:width="48dp"
        android:height="48dp"
        android:drawable="@drawable/ic_check_white_48dp"/>
</layer-list>

希望它有所帮助!

答案 2 :(得分:10)

经过编辑的解决方案,可使您的SplashScreen在包括API21到API23在内的所有API上都看起来不错

首先阅读this文章,并遵循制作初始屏幕的良好方法。

如果徽标变形或不合适,而您仅针对APIs24 +,则可以直接在其xml文件中直接按比例缩小矢量可绘制对象,如下所示:

<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="640"
android:viewportHeight="640"
android:width="240dp"
android:height="240dp">
<path
    android:pathData="M320.96 55.9L477.14 345L161.67 345L320.96 55.9Z"
    android:strokeColor="#292929"
    android:strokeWidth="24" />
</vector>

在上面的代码中,我将在640x640画布上绘制的可绘制对象重新缩放为240x240。然后像这样将其放在我的启动屏幕可绘制对象中,效果很好:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque"
android:paddingBottom="20dp" android:paddingRight="20dp" android:paddingLeft="20dp" android:paddingTop="20dp">

<!-- The background color, preferably the same as your normal theme -->
<item>
    <shape>
        <size android:height="120dp" android:width="120dp"/>
        <solid android:color="@android:color/white"/>
    </shape>
</item>

<!-- Your product logo - 144dp color version of your app icon -->
<item
    android:drawable="@drawable/logo_vect"
    android:gravity="center">

</item>
</layer-list>

我的代码实际上仅在底部的图片中绘制三角形,但是在这里您可以看到可以实现的目标。与使用位图时获得的像素化边缘相反,分辨率最终是很大的。因此,请务必使用可绘制的矢量(有一个名为vectr的网站,我曾用它来创建我的网站,而无需下载专门软件。)

编辑以使其也可以在API21-22-23上使用

虽然以上解决方案适用于运行API24 +的设备,但在将应用程序安装为运行API22的设备后,我感到非常失望。我注意到启动画面再次试图填充整个视图,看起来像狗屎一样。经过半天的折磨,我终于通过纯粹的意志力强行提出了解决方案。

您需要创建第二个文件,其名称与splashscreen xml完全一样(假设为splash_screen.xml),并将其放入2个名为drawable-v22和drawable-v21的文件夹中,这些文件将在res /文件夹中创建(为了看到他们,您必须将项目视图从Android更改为Project)。每当相关设备运行与可绘制文件夹see this link中的-vXX后缀相对应的API时,这便可以告诉您的手机重定向到这些文件夹中放置的文件。将以下代码放在在这些文件夹中创建的splash_screen.xml文件的“层”列表中:

<item>
<shape>
    <size android:height="120dp" android:width="120dp"/>
    <solid android:color="@android:color/white"/>
</shape>
</item>

<!-- Your product logo - 144dp color version of your app icon -->
<item android:gravity="center">
    <bitmap android:gravity="center"
        android:src="logo_vect"/>

</item>

these is how the folders look

由于这些API的某些原因,您必须将可绘制对象包装在位图中,以使其起作用并进行喷射,最终结果看起来相同。问题是您必须使用带有常规可绘制文件夹的方法,因为第二个版本的splash_screen.xml文件将导致您的启动屏幕在运行高于23的API的设备上根本不显示。您可能还必须放置android默认将splash_screen.xml的第一个版本添加到drawable-v24中,默认为它可以找到资源的最近的drawable-vXX文件夹。

my splashscreen

答案 3 :(得分:0)

我目前正在启动屏幕上,其可绘制矢量在水平和垂直方向上居中。这是我在API级别25上得到的:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">

<!-- background color, same as theme -->
<item android:drawable="@android:color/white"/>

<!-- app logo -->

<item
    android:drawable="@drawable/my_app_logo"
    android:gravity="center_horizontal|center_vertical"
    android:width="200dp"
    android:height="200dp"
    />
</layer-list>

如果要调整矢量可绘制对象的尺寸,请修改上面的android:widthandroid:height属性,而不必修改原始可绘制对象。

此外,我的经验是不要将矢量可绘制对象放在位图标记中,这对我永远都行不通。位图适用于.png,.jpg和.gif格式文件,不适用于可绘制矢量。

参考

https://developer.android.com/guide/topics/resources/drawable-resource#LayerList

https://developer.android.com/guide/topics/resources/more-resources.html#Dimension