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


102

我试图VectorDrawableLayerList不缩放向量的情况下使用a 。例如:

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

可绘制的ic_check_white_48dpID定义为:

<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每个密度的向量可绘制和修改层-列表作为这样:

<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


11
看来这可能只是API 21/22中的错误。我刚刚在API 23设备上进行了测试,可绘制矢量正确居中。
ashughes

1
您应该回答自己的问题并接受。这样一来,它就更加可见,并且问题不会显示为未回答。
MarcinKoziński'16

1
我还没有回答我的问题,因为我还没有关于在API 21/22上做什么的答案。我的临时解决方案是使用PNG而不是矢量。希望仍然能找到一种使向量起作用的方法。
ashughes

1
我在这里打开了一个问题:code.google.com/p/android/issues/detail?
id=219600

该错误已在API 23中修复,因此我猜测您的错误报告将仅被标记为已修复。
ashughes

Answers:


29

我遇到了同样的问题,试图将矢量可绘制对象放在分层列表上。

我有一个解决方法,它不完全相同,但是可以工作,您需要为整个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>

上面形状的大小设置整个可绘制对象的大小(在此示例中为120dp),在第二个项目上的填充(在此示例中为24dp)将矢量图像居中。

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


2
听起来这需要您知道可绘制对象的确切大小(以便设置形状大小),而不是让它以选中的可绘制对象居中放置在设置的整个空间中。
ashughes

1
可能不知道大小,但无法使用此方法更改填充,可以在imageviews中将可绘制对象彼此叠加。正如我所说上面有一个无完美的解决方案gravity="center"在API 21和22
尼古拉斯泰勒

与结合使用时不起作用windowBackground。显式大小在这种情况下不起作用。如果我将图层列表放在另一个图层列表中,那也不起作用。
Vsevolod Ganin

19

一直在努力解决同样的问题。我发现解决此问题并避免可绘制对象放大的唯一方法是设置可绘制对象的大小并使用重力对其进行对齐:

<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>

希望能帮助到你!


34
这在API 21-22上无济于事,因为该width属性在这些API级别上不可用。在API 23上,不需要这些,因为该错误已修复且可绘制对象不再拉伸。
WonderCsabo

3
这对于API 27不能正常工作,图像被拉伸到全屏状态
Konstantin Konopko

8

经过编辑的解决方案,可使您的SplashScreen在所有API(包括API21至API23)上看起来都很棒

首先阅读文章,并按照制作闪屏的好办法。

如果徽标变形或不合适,而您仅针对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),并将其放入将在res /文件夹中创建的2个名为drawable-v22和drawable-v21的文件夹中(以查看它们)必须将项目视图从Android更改为Project)。每当相关设备运行可绘制文件夹中与-vXX后缀相对应的API时,这都可以告诉您的手机重定向到这些文件夹中放置的文件,请参阅此链接。将以下代码放在在这些文件夹中创建的splash_screen.xml文件的Layer-list中:

<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>

这些是文件夹的外观

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

我的启动画面


4

我目前正在使用矢量可绘制的水平和垂直居中启动画面。这是我在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


1
关于矢量可绘制对象的很好的认识,它们需要放在<item>标记而不是<bitmap>标记内。
FrostRocket
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.