36

我正在制作一个<layer-list>可绘制的。

我有我的背景图像,我希望第二层更小,但似乎我在我的android:layer_widthand中写什么并不重要android:layer_height

第二层大小还是一样的。

这是我的xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <item
        android:drawable="@drawable/picuser" 
        android:layout_width="50dp"
        android:layout_height="50dp" />

    <item
        android:drawable="@drawable/ic_launcher" 
        android:layout_width="10dp"
        android:layout_height="10dp" />
</layer-list>
4

7 回答 7

37

这是一种解决方法,但它对我有用。
您可以使用填充以使第二个可绘制对象更小。

<item android:drawable="@drawable/circyle" />

<item
    android:drawable="@drawable/plus" 
    android:top="10dp"
    android:bottom="10dp"
    android:right="10dp"
    android:left="10dp" />

于 2013-12-19T13:00:01.343 回答
24

TL;DR:请参阅我更新、更简洁的答案


实际上,与之前所说的不同,还有宽度和高度属性<item>。感谢@Entreco 发布了一个演示。
android:widthand android:heightfor s 与and for Drawables 类似,不同之处在于它们可以设置为 none或,但是您可以通过将属性设置为or (以匹配父级的宽度)或(以匹配父级的高度)来实现相同的行为.android:layout_widthandroid:layout_heightViewmatch_parentwrap_contentmatch_parentandroid:gravityleft|rightstart|endtop|bottom

不幸的是,这些属性仅从 API 级别 23 开始可用。

但是,考虑到我建议的上述方法match_parent和属性可用于元素(必须放在 a 中)而不需要更新的 API 级别,您可以使用一个简单的解决方法:android:widthandroid:height<size><shape>

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

    <item>
        <shape
            android:shape="rectangle">

            <size
                android:width="152dp"
                android:height="152dp"/>

            <solid
                android:color="#00FFFFFF"/>
        </shape>
    </item>

    <item>
        <bitmap
            android:gravity="left|right|top|bottom"
            android:src="@mipmap/ic_launcher"/>
    </item>
</layer-list>

上述解决方案利用了已设置为匹配两个父级尺寸的已调整大小的<item>(带有透明的<shape>)和未调整大小的(带有 a 的)。因此,实际大小将由同一父级中唯一大小的大小决定。<bitmap>android:gravityleft|top|right|bottom<bitmap><item>

编辑:

感谢@Emil S 注意到上述解决方案在用作窗口背景时不起作用。我可以猜测,当系统创建一个由android:windowBackground属性指定的背景的窗口时,没有执行任何布局,因为还没有启动任何进程。因此,我认为,Android 最终会在屏幕尺寸上对可绘制对象进行光栅化,并将其拉伸以填充整个窗口。这将解释这是如何发生的。实际上,我想到的一个可能的解决方案是使用自定义可绘制对象作为窗口背景,但我还没有测试过,不幸的是,仅从 API 级别 24 开始才支持该解决方案。可以通过引用使用自定义可绘制对象的 XML 资源来实现,如下所示. 这样,问题应该得到解决,因为Android在显示窗口之前被迫启动应用程序进程,因此drawable应该正确布局,因为它知道窗口尺寸。然而,这将导致启动时几乎不明显但存在的延迟。

编辑:

@João Carlos 指出我的解决方案在使用自适应图标(由背景和前景组成的支持矢量可绘制对象的那些图标)时不起作用(因为它会导致循环继承)。但是,他的观点没有意义,因为自适应图标需要API 26android:width并且android:height属性可以在启动屏幕或其他东西上使用,因为它们需要API 23
因此,为了让任何东西在任何版本的 Android 中工作,您需要区分两个可绘制对象,前者用于API < 23,使用我发布的解决方案,后者用于API >= 23,使用两个属性正如我在这篇文章开头所说的那样。

于 2017-09-08T11:41:08.323 回答
15

我希望这能让你朝着正确的方向前进:

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

    <item android:drawable="@drawable/picuser"/>

    <item>

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

正如您在此处看到的,<item>没有layout_width/layout_height属性。

于 2012-05-22T17:58:47.807 回答
12

从 API 级别 23 及更高版本开始,您实际上可以设置项目的宽度和高度

<item
    android:drawable="@drawable/splash_logo"
    android:height="100dp"
    android:width="100dp"/>

注意:使用android:widthandandroid:height代替android:layout_widthandandroid:layout_height

于 2017-01-05T08:15:21.343 回答
3

试试这个:

<?xml version="1.0" encoding="utf-8"?>
<!-- The android:opacity=”opaque” line is critical in preventing a flash 
of black as your theme transitions. -->
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:opacity="opaque">

    <!-- The background color, preferably the same as your normal theme -->
    <item android:drawable="@android:color/white" />

    <item
        android:height="100dp"
        android:width="100dp"
        android:gravity="center">

        <bitmap
            android:src="@drawable/ic_launcher_bc_512"/>
    </item>
</layer-list>
于 2018-09-10T15:57:11.953 回答
1

我已经尝试了很多,但我找不到一种可靠的方法来使徽标在 XML 布局中居中。最后,我找到了以下解决方法:

mToolbar.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            ImageView imageView = (ImageView)mToolbar.findViewById(R.id.logo);
            if (mToolbar == null)
                return;
            int toolbarWidth = mToolbar.getWidth();
            int imageWidth = imageView.getWidth();
            imageView.setX((toolbarWidth - imageWidth) / 2);
        }
    });

布局工具栏.xml:

<android.support.v7.widget.Toolbar 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    style="@style/Toolbar"
    android:layout_width="match_parent"
    android:layout_height="@dimen/toolbar_height"                                                                   
    android:background="@drawable/toolbar_background"
    android:focusable="false"                                
    app:titleTextAppearance="@style/AppTheme.Toolbar.Title">

    <ImageView
        android:id="@+id/logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/toolbar_logo" />
</android.support.v7.widget.Toolbar>
于 2016-06-16T06:55:07.153 回答
1

向后兼容的解决方案:

<item>
    <shape
        android:shape="rectangle">

        <size
            android:width="152dp"
            android:height="152dp"/>

        <solid
            android:color="#00FFFFFF"/>
    </shape>
</item>

<item>
    <bitmap
        android:gravity="left|right|top|bottom"
        android:src="@mipmap/ic_launcher"/>
</item>

注意事项和解决方案:

  1. 作为窗口背景,这永远行不通

    • API等级≥24
      对于在窗口背景中使用,可能值得尝试自定义可绘制对象。可以以这样的样式引用它们
    • API 级别 < 24
      我还没有找到任何解决方案。
  2. 这也不适用于自适应图标

    • 参考Entreco 的回答
      由于自适应图标需要 API 级别 26,因此可以使用android:widthandroid:height属性,从 API 级别 23 开始可用。

了解更多信息,
于 2021-07-28T17:09:49.330 回答