Android - 只在顶部带圆角的可绘制对象

190

我有这个drawable,它将圆角矩形作为背景:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/white" />
    <stroke android:width="1dp" android:color="@color/light_gray" />
    <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />
    <corners android:radius="6dp" />
</shape>

这个很好用,效果正是我期望的。

现在,我想要只将顶部的圆角变成圆形,所以我将它改为:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/white" />
    <stroke android:width="1dp" android:color="@color/light_gray" />
    <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />
    <corners android:topLeftRadius="6dp" android:topRightRadius="6dp"
             android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp"/>
</shape>

但是现在我的按钮没有圆角了,我只得到了一个普通的矩形。我错过了什么?


这真的不是一个解决方案,但我想我曾经遇到过类似的问题。将描边增加到2像素有所帮助,但你知道,那不是一个解决方案。 - Code Poet
这里有一个关于形状角的问题:http://code.google.com/p/android/issues/detail?id=939 - Knickedi
10个回答

374

尝试使用以下值:

 <corners android:topLeftRadius="6dp" android:topRightRadius="6dp"
         android:bottomLeftRadius="0.1dp" android:bottomRightRadius="0.1dp"/>

请注意,我已将0dp更改为0.1dp

编辑:请参考下面Aleks G评论获取更加简洁的版本。


156
进一步探索后,我找到了一个更好的解决方案: <corners android:radius="1dp" android:topLeftRadius="6dp" android:topRightRadius="6dp" android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp"/> - 这将产生完全正方形的底部角,甚至没有任何圆角的迹象。不过您的解决方案基本上也可以使用。 - Aleks G
1
如何在代码中处理位图?如何在其周围添加轮廓(也称为描边)? - android developer
@Aleks G 我认为没有必要指定 android:radius="1dp" - hmac
@hmac 是必要的。阅读文档,它会让你明白的。 - Aleks G
@AleksG 我相信你现在已经注意到你的问题至今仍然相关。你是否考虑编辑问题并指明它所涉及的Android版本(我认为这比读者从发布日期推断信息要好得多)?也许提到需要在哪些设备上工作也对未来的读者有帮助。根据现代SO标准进行问题标记,我会从标题中删除“Android”。 - Dev-iL
显示剩余2条评论

15

尝试做类似这样的事情:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:bottom="-20dp" android:left="-20dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />

            <corners android:radius="20dp" />
        </shape>
    </item>
</layer-list>

看起来不太适合为矩形设置不同的圆角半径。因此,您可以使用这个hack。


看我的回答 - 对于不同的角落有不同的半径是完全可以接受的。 - Aleks G
我尝试了这种方法,但它不可行。IDE 告诉我,拥有不同的半径是不合适的,并忽略了它。 - busylee

15

在我的情况下,以下代码

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

        <shape android:shape="rectangle">
            <solid android:color="@color/maincolor" />

            <corners
                android:topLeftRadius="10dp"
                android:topRightRadius="10dp"
                android:bottomLeftRadius="0dp"
                android:bottomRightRadius="0dp"
            />
        </shape>

    </item>
    </layer-list>

1
除非您想在视图中设置填充,否则项目上的顶部和底部属性是不需要的,但是这样可以正常工作。 - RominaV

13
bg.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#FFFFFF"/>
    <corners android:topLeftRadius="24dp" android:topRightRadius="24dp"
        android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp"/>
</shape>

在您的布局中添加:

android:background="@drawable/bg"

如果您完整地阅读问题,您会注意到这种方法不起作用,这也是为什么首先提出这个问题的原因。 - Aleks G

9

busylee的回答的基础上,以下是如何制作一个只有一个圆角(例如左上角)的drawable

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
            <!-- A numeric value is specified in "radius" for demonstrative purposes only,
                  it should be @dimen/val_name -->
            <corners android:radius="10dp" />
        </shape>
    </item>
    <!-- To keep the TOP-LEFT corner UNROUNDED set both OPPOSITE offsets (bottom+right): -->
    <item
        android:bottom="10dp"
        android:right="10dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
        </shape>
    </item>
</layer-list>

请注意,上述的drawable在Android Studio预览中(2.0.0p7)不能正确显示。要预览它,请创建另一个视图并将其用作android:background="@drawable/..."

6
当然可以。这个问题的相关性从过去一直延续至今(作为证据 - 我需要这样的东西)。你必须知道,随着时间的推移,一些做事情的方式会变得过时并可能需要用更现代的方法替换。正如 @busylee 所提到的,当定义不同圆角半径时,IDE 会发出警告,而使用现有的方法则不会出现这种情况。此外,既然这个问题是我在 Google 上搜索的第一个结果(如果我没记错的话),更新它是很有意义的。无论如何,我相信 SO 不会介意多几 KB 的代码... :) - Dev-iL

9
尝试使用 MaterialShapeDrawable 并在 Kotlin/Java 代码中进行配置。
val backgroundShapeModel:ShapeAppearanceModel = ShapeAppearanceModel.builder()
    .setTopLeftCorner(CornerFamily.ROUNDED, 16F.toPx)
    .setTopRightCorner(CornerFamily.ROUNDED, 16F.toPx)
    .build()
textView.background = MaterialShapeDrawable(backgroundShapeModel).apply {
    fillColor = ColorStateList.valueOf(Color.GREEN)
}

图片描述

P.S:

除了xml可提供的能力(如fillColor、stroke等),MaterialShapeDrawable还支持:

  1. cornerFamily分为两个类别:roundedcut
  2. edgeTreatment,包括TriangleEdgeTreatmentOffsetEdgeTreatment
  3. 无需上下文和获取资源即可使用

图片描述]

val backgroundShapeModel = ShapeAppearanceModel.builder()
    .setTopLeftCorner(CornerFamily.ROUNDED, 16F.toPx)
    .setTopRightCorner(CornerFamily.CUT, 16F.toPx)
    .setAllEdges(TriangleEdgeTreatment(5f.toPx, true))
    .build()
textView.background = MaterialShapeDrawable(backgroundShapeModel).apply {
    fillColor = ColorStateList.valueOf(Color.GREEN)
    setStroke(2f.toPx,Color.RED)
}

2
您可能需要阅读这篇文章:https://developer.android.com/guide/topics/resources/drawable-resource.html#Shape,以下是一条注意事项。
注意:每个角(初始时)都必须提供大于1的角半径,否则没有任何角会被圆角化。如果您想要特定的角不被圆角化,则可以使用android:radius来设置大于1的默认角半径,然后使用您真正想要的值覆盖每个角,其中您不想要圆角的地方提供零(“0dp”)。

2
我尝试了您的代码,得到了一个顶部圆角按钮。我将颜色设置为@ffffff,描边颜色为#C0C0C0
请尝试以下操作:
1. 将android:bottomLeftRadius设置为“0.1dp”,而不是“0”。如果这不起作用,请尝试下一步。
2. 检查drawable文件夹和模拟器的分辨率。我在res下创建了一个drawable文件夹,并在其中使用它(hdpi、mdpi、ldpi)。这是我的输出结果。 enter image description here

这是哪个安卓版本?我的应用程序必须在1.6上运行,而模拟器1.6有问题。 - Aleks G

2

在drawable中创建roung_top_corners.xml,并复制以下代码

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<corners
    android:topLeftRadius="22dp"
    android:topRightRadius="22dp"
    android:bottomLeftRadius="0dp"
    android:bottomRightRadius="0dp"
    />
<gradient
    android:angle="180"
    android:startColor="#1d2b32"
    android:centerColor="#465059"
    android:endColor="#687079"
    android:type="linear" />
<padding
    android:left="0dp"
    android:top="0dp"
    android:right="0dp"
    android:bottom="0dp"
    />
<size
    android:width="270dp"
    android:height="60dp"
    /></shape>

0

尝试完全删除这些属性。

android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp"

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