Android如何改变<item>的宽度和高度?

41

我正在制作一个<layer-list>用于drawable。

我有我的背景图像,并且我希望第二层更小,但是无论我在android:layer_widthandroid: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>

如果lint提示您必须添加宽度和高度,则将您的XML文件移动到drawable而不是layout! - Mahdi Moqadasi
8个回答

38

虽然这有点绕,但对我来说很有效。
您可以使用填充来使第二个可绘制项变小。

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

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

:一个空的HTML段落元素。

3
我已经点赞了,但现在注意到在我的菜单中似乎没有任何效果。 - lucidbrot

25

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


实际上,与之前的说法不同,<item>也有widthheight属性。感谢@Entreco发表的演示。
对于Drawableandroid:widthandroid:heightViewandroid:layout_widthandroid:layout_height类似,但不能设置为match_parentwrap_content,不过可以通过将属性android:gravity设置为left|rightstart|end(以匹配父级的宽度)或top|bottom(以匹配父级的高度)来实现与match_parent相同的行为。

不幸的是,这些属性仅从API 23开始提供。

然而,考虑到我建议的替代match_parent的方法以及<size>元素(必须放在<shape>中)可用android:widthandroid:height属性(无需新的API级别),您可以使用一个简单的解决方法:

<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>)和一个未设置大小的<bitmap>(其android:gravity设置为left|top|right|bottom以匹配父容器的尺寸),因此,<bitmap>的实际大小将由同一父容器中唯一具有大小的<item>的大小确定。
编辑:感谢@Emil S注意到上述解决方案在用作窗口背景时无法使用。我猜想,在系统使用android:windowBackground属性指定的背景创建窗口时,没有执行布局,因为没有启动进程。因此,Android最终会在屏幕大小上光栅化可绘制对象并将其拉伸以填充整个窗口,我想。这可以解释发生这种情况的原因。确实,我想到的一个可能的解决方案,但我还没有测试过,不幸的是只支持从API级别24开始,那就是使用自定义可绘制对象作为窗口背景。通过引用使用自定义可绘制对象的XML资源(例如这个),它是可能的。通过这种方式,问题应该得到解决,因为Android被迫在显示窗口之前启动应用程序进程,因此应正确布局可绘制对象,因为它知道窗口尺寸。然而,这会导致启动时几乎不可察觉但确实存在的延迟。
编辑:@João Carlos指出,当使用自适应图标(由背景和前景组成的那些图标,支持矢量可绘制对象)时,我的解决方案不起作用(因为它会导致循环继承)。然而,他的观点没有意义,因为自适应图标需要API 26:可以在闪屏或其他地方使用android:widthandroid:height属性,因为它们需要API 23。因此,为了使任何版本的Android都能正常工作,您需要区分两个可绘制对象,前者是 API <23 ,使用我发布的解决方案,后者是 API > = 23 ,使用我在本帖子开头提到的两个属性。

1
如果在Android应用程序中使用了新的ic_launcher图标,该图标由background.xmlforeground.xml定义,那么使用的文件将是位于anydpi-v26文件夹内的文件,而不是.png文件。这会导致XML递归循环并使应用程序崩溃。 - João Carlos
3
只有在支持wrap_content的情况下,使用layer-list才有效。如果你试图将其应用于闪屏界面,它将不起作用。我花了一些时间才弄清楚这一点,所以在这里留下评论,让其他人不必花时间进行故障排查。 - Emil S.

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属性。


3
是的,我看过了,但有没有办法来定义每层的大小呢?这非常重要。 - Asaf Nevo
10
从API 23开始,在item上有width、height、gravity等属性。 - Pauland
请参考@oznus的答案!使用填充可以解决问题,而且更容易。 - User
如果lint提示您必须添加宽度和高度,则将您的xml文件移动到drawable而不是layout! - Mahdi Moqadasi
亲爱的,位图不支持可绘制资源,这个答案没有帮助。 - elliotching

13

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

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

注意: 使用 android:widthandroid:height 替代 android:layout_widthandroid:layout_height


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>

这是迄今为止对这个问题最好的回答。 - John Harrington

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);
        }
    });

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

问题是关于drawable的。使用<ImageView>来解决问题是不相关的话题。 - Davide Cannizzo

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
      作为窗口背景使用时,可以尝试使用自定义 drawable。可以像this一样在样式中引用它们。
    • API 级别 < 24
      我还没有找到任何解决方案。
  2. 自适应图标也不起作用

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

更多信息,请参考:

0

对于 API 级别低于 23 的情况,您可能希望使用以下填充来使项目变小或变大,而不是使用定义的高度和宽度:

<item
    android:state_enabled="true"
    android:drawable="@drawable/your_drawable"
    android:gravity="center"
    android:top="8dp"
    android:left="8dp"
    android:right="8dp"
    android:bottom="8dp">
</item>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接