形状可绘制对象大小不起作用。

54

我有一个非常简单的形状,我想设置它的宽度:

<shape android:shape="rectangle">
    <solid android:color="@color/orange"/>
    <size android:width="2dp"/>
</shape>

但是,当我将它分配为EditText的背景时,它只显示一个橙色背景,而不是宽度为2dp的矩形。设置大小为什么不起作用?我想创建一个透明的Drawable,在左侧有一个橙色的矩形。我还在一个selector中包装了它:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true">
        <shape android:shape="rectangle">
            <solid android:color="@color/orange"/>
            <size android:width="2dp" android:height="6dp"/>
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/transparent"/>
        </shape>
    </item>
</selector>

我尝试添加高度,看看它是否会改变大小。但它没有改变。就像完全忽略了大小一样。什么鬼?


它为什么对你不起作用?它像魔法一样工作。也许问题在于你的布局设置?看看你的布局是否将高度和宽度设置为wrap_content。 - Daler
1
很简单。 <size [...]/> 被忽略,将始终创建填充视图的形状。 - Tadas S
并不总是这样,特别是在使用drawableTop/Bottom等属性时。 - user153275
@Daler,你所说的只是忽略了大小并填充视图。你应该测试一下。这与布局设置无关。 - Farid
8个回答

39

对我来说,将项目的重力设置为“center”解决了这个问题。例如:

<item android:id="@android:id/progress" android:gravity="center">
    <clip>
        <shape>
            <size android:height="2dp"/>
            <solid android:color="@color/my_color"/>
        </shape>
    </clip>
</item>

最有帮助的答案。非常感谢! - rocknow
2
加冕这个家伙! - ZShock
item 的包装器是什么? - Konstantin Konopko
唯一可行、简单且最佳的答案。 - Vineeth_Bhanukoti

12

它可以与foreground一起使用。似乎您无法设置背景的重力,但可以在前景上设置。我检查了API 21、23和24(好吧,在Studio设计预览中),以下内容会在ImageView上放置一个实心圆点。

<shape android:shape="oval" xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/colorPrimary" />
    <size android:height="8dp" android:width="8dp" />
</shape>

使用布局片段

    <ImageView
            android:foreground="@drawable/list_new_dot"
            android:foregroundGravity="right|center_vertical"
            tools:src="@drawable/model_1_sm"
            />

更新:虽然它在布局设计工具中看起来有效,但在模拟器中效果不同。更新2:由于此答案已有一些票数,您可能想要查看我实际使用的内容以显示新的指示点: https://gist.github.com/CapnSpellcheck/4d4638aefd085c703b9d990a21ddc1eb


9
仅仅是为了澄清用户983447的回答 - size属性确实是指比例。您应该为图层列表中的所有形状设置大小,它将在缩放时作为比例使用 - 就像LinearLayout的layout_weight属性一样。因此,最好将其命名为weight而不是size。
下面是一个解决方案,可以在不使用size属性的情况下实现顶部和底部的白线:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <solid android:color="#fff" />
        </shape>
    </item>
    <item android:top="1dp" android:bottom="1dp">
        <shape>
            <solid android:color="#888" />
        </shape>
    </item>
</layer-list>

由于GPU过度绘制,这会导致性能不佳(当您只想要两行像素时,两个形状会填充所有像素)。 - Gilian
@Gilian 如果我说错了,请纠正我,但是这个xml会通过aapt编译成Drawable的某个子类,因此在编译完成后它只是一个Java类,从GPU的角度来看性能与任何9-patch或位图相同。因此,如果设计需要它,就没有绕过它的方法。 - Max Ch

4

我发现对于第一次接触安卓的人来说,图层列表(layer-list)非常棘手,因为以下原因。乍一看,大多数人会认为item的top、bottom、right、left属性是相对于顶部、底部、右侧、左侧的位置。其中一个值如下所示:

<item android:top="10dp">

希望从各自容器的顶部开始,距离为10dp。但实际情况不是这样的。可以理解为距离顶部、底部、右侧和左侧各有多远。使用<item android:top="10dp">仍然会让你从顶部开始向下偏移10dp,但如果想设置底部呢?

<item android:bottom="20dp">

这并不会使你得到一个距离容器顶部20dp的底部,而是一个距离容器底部20dp的底部。例如,如果你有一个100dp的容器,想要一个矩形,顶部边缘从20dp开始,底部边缘在40dp处:
<item android:top="20" android:bottom="60dp">

1
我实际上理解了当我发布问题时。将所有值(即顶部,左侧,底部,右侧)都设置为相对于顶部和左侧无多大意义,因为你永远无法定义一个形状,使其扩展到与其父容器匹配而不知道容器的大小。在这种特定情况下,我有一个需要固定尺寸的形状,因此我想使用宽度/高度来设置尺寸,但文档没有说明宽度/高度的坐标系,因此你只能去猜测。 - chubbsondubs
谢谢你,这是很好的解释!让我明白了我的错误并在几小时后最终解决了问题!但你真的很棒!加一分! - Alexiscanny

2
当您将形状用作 View 的背景时,其大小将被忽略。但如果您通过 ImageView 显示它,则会生效。
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#FF7700" />
    <size android:width="20dp" android:height="20dp"/>
</shape>

在您的布局XML中:
<!-- will have the size of 20dp x 20dp -->
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/my_shape"
    />

1

shape的size属性将为drawable.getIntrinsicWidth和getIntrinsicHeight提供值。

如果drawable的容器(例如ImageView、TextView)具有WRAP_CONTENT布局参数,则当drawable的drawingState更改时,容器的尺寸也会发生变化。

但是,在ImageView的drawingState实现中存在一个bug。

ImageView仅在state_selected状态下通过drawable的尺寸更新/调整其尺寸,而不会在state_activated状态下进行更新/调整。


1
我有类似的问题。
文档(http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape)中说:

<size>

形状的大小。 (...)

注意:默认情况下,形状会按比例缩放到容器视图的尺寸与此处定义的尺寸成比例。当您在 ImageView 中使用该形状时,可以通过将 android:scaleType 设置为“center”来限制缩放。

如果我理解正确,这意味着“size”标签不是用于设置大小,而是用于设置比例。

4
所述的宽度/高度是整数,但你发布的内容听起来可能是百分比(0..1),或者与容器的尺寸一样大(0..视图宽度)?!或者你是说这很合理,你知道它是如何工作的,并且可以比文档更好地解释它?我不完全理解你的观点。无论哪种方式,都可能需要修复代码以使其实际上是宽度和高度,或者澄清极其糟糕的文档。 - chubbsondubs

0

使用了这个。

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

<stroke
    android:color="@color/lgray"
    android:width="1dip" />

<corners
    android:bottomLeftRadius="0dip"
    android:bottomRightRadius="0.1dip"
    android:topLeftRadius="0dip"
    android:topRightRadius="0.1dip" />

<solid android:color="@color/White" />

</shape>

将这个rectangle.xml文件放到drawable文件夹中,并将其设置为您的视图背景。

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