如何在 Android 中制作无阴影彩色按钮

How to make a shadowless coloured button in Android

我一直在尝试各种方法来通过样式来做到这一点,但无法得到我想要的。看来我可以有一个带阴影的彩色按钮或​​一个没有阴影的按钮,我只能更改文本和按下的颜色。

这是我 styles.xml 中的内容:

<style name="PrimaryFlatButton"  parent="Theme.AppCompat.Light">
    <item name="colorControlHighlight">@color/colorPrimary</item>
    <item name="colorButtonNormal">@color/colorPrimaryLight</item>
</style>

这是我的布局:

<Button
    android:id="@+id/btn_search"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/pc_large_padding"
    android:theme="@style/PrimaryFlatButton"
    style="@style/Widget.AppCompat.Button"
    android:text="Search"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintRight_toRightOf="parent"/>

这给了我一个彩色按钮,它在按下时变暗但有阴影。

如果我将按钮的样式更改为:

style="@style/Widget.AppCompat.Button.Borderless"

然后我成功地失去了阴影但没有背景颜色除非按下按钮。我认为 Android 的想法 "borderless" 意味着根本没有任何指示边框的东西 - 只是纯文本 - 而不是制作一个平面按钮。

我想要的只是标准主题按钮,带有背景颜色,按下时会改变颜色,并且没有阴影。

通过创建 selector 可绘制对象并将其指定为按钮的背景,您应该能够获得带有波纹效果的彩色按钮。像这样:

some_layout.xml

<Button
   style="@style/Theme.Flat.Button"
   <!-- Any other properties you want to set -->
   />

style.xml

<style name="Theme.Flat.Button" parent="@style/Widget.AppCompat.Button.Borderless">
    <item name="android:background">@drawable/ripple_selector</item>
    <!-- Any other items you want to add -->
</style>

ripple_selector.xml

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorPrimary">
    <item>
        <selector>
            <item android:state_enabled="false">
                <color android:color="@color/colorPrimaryLight" />
            </item>
            <item android:state_enabled="true" android:state_pressed="false">
                <color android:color="@color/colorPrimaryLight" />
            </item>
            <item android:state_enabled="true" android:state_pressed="true">
                <color android:color="@color/colorPrimary" />
            </item>
        </selector>
    </item>
</ripple>

您可以通过将 android:stateListAnimator="@null" 添加到按钮的 XML 属性来删除 elevation/shadow。

完整按钮XML:

<Button
    android:id="@+id/btn_search"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/pc_large_padding"
    android:theme="@style/PrimaryFlatButton"
    style="@style/Widget.AppCompat.Button"
    android:text="Search"
    android:stateListAnimator="@null"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintRight_toRightOf="parent"/>

您也可以将此行放入您的 styles.xml 以避免将它添加到您的每个按钮

styles.xml:

<style name="PrimaryFlatButton"  parent="Theme.AppCompat.Light">
    <item name="colorControlHighlight">@color/colorPrimary</item>
    <item name="colorButtonNormal">@color/colorPrimaryLight</item>
    <item name="android:stateListAnimator">@null</item>
</style>

Michael 的回答在技术上也是正确的。如果您希望更好地控制按钮(包括 elevation/shadows)的样式和状态,您可以考虑为按钮创建自己的 StateListDrawable 资源。由于您似乎对使用仅稍作修改的默认按钮样式更感兴趣,因此我不会在这里详细介绍 StateListDrawables。但是,如果您有兴趣,可以阅读 Michael 的回答以及 StateListDrawable 文档 here.