Android 在不丢失 material 主题的情况下为按钮添加边框(使用可绘制对象)

Android add border to button without losing material theme (using drawable)

我有一个简单的按钮

<Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/add"
        android:backgroundTint="@color/add_bg"
        android:textColor="@color/add_fg"
        <!--android:borderColor?="@color/button_border"-->
        android:text="@string/add"/>

我想要白色背景、蓝色文字和蓝色边框。我知道我可以通过如图所示 here 和许多其他地方的可绘制对象来实现这一点。但是我观察到,如果您向按钮添加一个可绘制对象,那么它将失去其所有 material 属性(例如阴影以及单击具有花式波纹动画的属性)。那么我如何在按钮周围添加边框而不丢失 material 主题动画(点击时的阴影和倾斜动画)?

android 附带的大多数项目只是一组预先打包的属性。

几乎不可能期望 Android API 开发人员为每个可能的 color/border 组合包含一组预先打包的属性,但总有解决方案!

不幸的是,正如您所提到的,解决方案确实存在于创建您自己的自定义 XML 文件中,在您掌握它之前,这通常会令人生畏。一旦你这样做了,你也会惊叹于它所允许的灵活性。

具体针对您的情况,有两种选择...

1) 创建自定义 XML 可绘制边框。

2) 在您的按钮背景下 属性 设置新的自定义边框可绘制对象

3) 然后在按钮 xml 属性下设置涟漪效果,方法是添加:

    android:foreground="?attr/selectableItemBackground"
    android:clickable="true"
    android:focusable="true"

----或----

一种更复杂的方法是制作如下所示的可绘制对象。这将添加 "ripple" 按钮效果以及自定义阴影、按钮颜色和边框颜色!

“对于以后阅读本文的人来说,可能经验不足)

1)在您的项目视图中转到 res/drawable

2)右键单击文件夹本身和select new/drawable资源文件

3)输入一个文件名my_ripple_button.xml(根并不重要,因为你会用下面的代码替换它)

4) 如果您还没有,请单击文本选项卡

5)select所有文字基本替换为以下内容:(创建自定义颜色边框步骤基本相同)

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorPrimaryDark">
    <item android:id="@android:id/ripple">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimaryDark" />
            <corners android:radius="@dimen/button_radius_large" />
       </shape>
   </item>

    <item android:id="@android:id/background">
       <shape android:shape="rectangle">
            <gradient
                android:angle="90"
                android:endColor="@color/colorPrimaryLight"
               android:startColor="@color/colorPrimary"
                android:type="linear" />
           <corners android:radius="@dimen/button_radius_large" />
        </shape>
    </item>
</ripple>