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

ash*_*hes 87 android layer-list android-drawable android-vectordrawable

我试图VectorDrawableLayerList没有缩放矢量的情况下使用a .例如:

<layer-list>
    <item android:drawable="@color/grid_item_activated"/>
    <item android:gravity="center" android:drawable="@drawable/ic_check_white_48dp"/>
</layer-list>
Run Code Online (Sandbox Code Playgroud)

drawable 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>
Run Code Online (Sandbox Code Playgroud)

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

如果我用每个密度的PNG替换矢量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>
Run Code Online (Sandbox Code Playgroud)

我有什么方法可以使用VectorDrawable

Nic*_*ler 24

我遇到了同样的问题,试图在分层列表中居中矢量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>
Run Code Online (Sandbox Code Playgroud)

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

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

  • 这听起来好像需要你知道drawable的确切大小(为了设置形状大小),而不是让它填充它设置的整个空间,其中checkable drawable在其中居中. (2认同)

que*_*gre 14

经过编辑的解决方案将使您的 SplashScreen 在包括 API21 到 API23 在内的所有 API 上看起来都很棒

首先阅读这篇文章并遵循制作启动画面的好方法。

如果您的徽标扭曲或不适合并且您仅针对 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>
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我将在 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>
Run Code Online (Sandbox Code Playgroud)

我的代码实际上只是在底部的图片中绘制三角形,但在这里您可以看到使用它可以实现的目标。与使用位图时得到的像素化边缘相比,分辨率终于很棒了。所以一定要使用可绘制的矢量(有一个名为 vectr 的站点,我曾经创建我的站点,而无需下载专门的软件)。

编辑以使其也适用于 API21-22-23

虽然上述解决方案适用于运行 API24+ 的设备,但在将我的应用安装到运行 API22 的设备后,我感到非常失望。我注意到闪屏再次试图填满整个视图并且看起来像狗屎。撕了半天的眉毛,我终于凭着意志力强行解决了。

您需要创建一个与启动画面 xml 完全相同的第二个文件(假设为 splash_screen.xml),并将其放入两个名为 drawable-v22 和 drawable-v21 的文件夹中,您将在 res/ 文件夹中创建该文件夹(以便您查看它们)必须将您的项目视图从 Android 更改为 Project)。这用于告诉您的手机在相关设备运行与 drawable 文件夹中的 -vXX 后缀对应的 API 时重定向到放置在这些文件夹中的文件,请参阅此链接。将以下代码放置在您在这些文件夹中创建的 splash_screen.xml 文件的图层列表中:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:opacity="opaque">

<!-- The background color, preferably the same as your normal theme -->
<item
    android:gravity="center">
    <shape android:shape="rectangle">
        <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="@drawable/logo_vect"/>

</item>
</layer-list>
Run Code Online (Sandbox Code Playgroud)

这些是文件夹的外观

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

我的启动画面

  • 使用 `&lt;bitmap android:src="logo_vect"/&gt;` 您似乎建议在 API 级别 21 和 22 上可以使用矢量可绘制对象作为位图的源。根据我的经验,这总是会导致运行时崩溃:`java.lang.RuntimeException:无法启动活动``android.content.res.Resources$NotFoundException:来自可绘制资源 ID #0x7f080305 的文件 res/drawable-v21/splash.xml ` `由以下原因引起:org.xmlpull.v1.XmlPullParserException:二进制 XML 文件行 #X:&lt;bitmap&gt; 需要有效的 src 属性` (3认同)

Fel*_*rte 13

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

<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>
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!

  • 这对API 21-22没有帮助,因为`width`属性在这些API级别上不可用.在API 23上,不需要这些,因为错误是固定的,并且drawable不再被拉伸. (30认同)
  • 对于API 27不能正常工作,图像被拉伸到全屏 (2认同)

fis*_*ick 8

我目前正在处理带有水平和垂直居中的矢量可绘制的闪屏。这是我在 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>
Run Code Online (Sandbox Code Playgroud)

如果你想调整矢量绘制的尺寸,修改android:widthandroid:height属性上面,不一定修改原来的绘制。

此外,我的经验是不要将矢量 drawable 放在位图标签中,这对我来说永远不起作用。位图适用于 .png、.jpg 和 .gif 格式文件,不适用于可绘制矢量。

参考

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

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

  • 关于矢量绘图需要位于 &lt;item&gt; 标记而不是 &lt;bitmap&gt; 标记内的好消息。 (3认同)