具有selectableItemBackground作为背景的形状可绘制对象

47

我有几个按钮需要一个椭圆形的边框。

所以我在capsule_border.xml中有这个。

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="9999dp"/>
    <stroke
        android:width="1px"
        android:color="@color/border_gray" />
</shape>

我会在需要的地方使用android:background="@drawable/capsule_border.xml"

现在,我想要一个按钮拥有椭圆形的边框,但是也带有android:background="?selectableItemBackground"以获得视觉反馈。

我尝试使用具有selectableItembackground的父布局和带有capsule_border的按钮。 但是,看起来被突出显示的可点击区域是整个正方形,而不是仅在胶囊边框内的区域。

输入图像描述

是否有一种方法可以使selectableItemBackground不突出整个视图矩形,而只是在绘制的边框内部突出显示?

3个回答

74

有一个名为round_corners.xml的文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="@android:color/transparent"/>
    <corners android:radius="15dp" />
    <stroke
        android:width="1px"
        android:color="#000000" />
</shape>

还有my_ripple.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?android:attr/colorControlHighlight">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="#000000" />
            <corners android:radius="15dp" />
        </shape>
    </item>
    <item android:drawable="@drawable/round_corners" />
</ripple>

和按钮:

<Button
    android:background="@drawable/my_ripple"
    ... />

将导致如下结果:

在此输入图片描述

请参阅此篇文章


5
非常好。如果有一个<21 api级别的版本会更好。 - Zhen Liu
1
谢谢你为此付出的努力! - parohy

15

我有第一个回答的更简单版本:

<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?colorControlHighlight"> <!-- default ripple color -->

    <item>
        <!-- the background shape when it's not being clicked -->
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimary" />
            <corners android:radius="32dp" />
        </shape>
    </item>
</ripple>

将其应用为背景,但如果应用于 Button,请移除阴影

style="?borderlessButtonStyle"

祝好运!


输入图像描述


这个解决方案的最低Android版本是多少? - Zhen Liu
@Zhen Liu,我没有看到任何API级别要求的警告,我想这对所有版本都是好的。 - Sam Chen

6

以下是一个更简单的解决方案,现在在2020年可用(API >= 21),因为我们使用了?attr语法:

<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?colorControlHighlight">
    <!--  the ripple's color (1) -->

    <!--  no `id` so our <shape> will be drawn and not just used as mask -->
    <item>
        <shape>
            <corners android:radius="9dp" />
            <solid android:color="@color/white" />
        </shape>
    </item>

</ripple>

如果您没有在主题中覆盖 colorControlHighlight ,则涟漪的颜色将为Android默认值。如果您确实覆盖了它但仍想使用Android默认值,则可以使用?android:colorControlHighlight

这种方法是可行的,但它存在一个问题,即当项目未被点击时,它总是绘制背景颜色(在本例中为白色)。这会导致过度绘制。另一方面,使用蒙版我们可以拥有默认透明背景并避免过度绘制。 - jmart
@flaw 只需删除实线并使用 backgroundTint。由于新的系统涟漪效果,这应该是2021年的第一选择。 - Joao
1
2021年更好的解决方案 - DIRTY DAVE

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