具有背景色的按钮上的材料效果

253

我正在使用Android v21的支持库。

我创建了一个带有自定义背景颜色的按钮。但是,当我使用这个背景颜色时,材料设计效果如波纹、揭示消失了(除了在点击时的高程效果)。

 <Button
 style="?android:attr/buttonStyleSmall"
 android:background="?attr/colorPrimary"
 android:textColor="@color/white"
 android:textAllCaps="true"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Button1"
 />

背景 以下是一个普通按钮,效果正常。

<Button
 style="?android:attr/buttonStyleSmall"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:textAllCaps="true"
 android:text="Button1"
/>

默认按钮


9
这是因为你用纯色替换了所有美观的Material效果作为背景。至于如何在保留Material效果的同时正确着色按钮,目前还没有人能够解决这个问题。 - Nathan Walters
2
@SweetWisher 当我改变按钮的背景颜色时,涟漪和其他效果未应用于按钮。 - Sathesh
2
@NathanWalters 但是默认的灰色很丑。 :-( - Sathesh
6
相信我,我知道……无论谁能够正确地解决这个问题,我们都将欠他们极大的债。 - Nathan Walters
1
真棒的答案 https://dev59.com/R18d5IYBdhLWcg3wt0EQ#32238489 - Pratik Butani
显示剩余3条评论
17个回答

5

appcompat-v7v22.1版本引入了一些新的可能性。现在可以仅为一个视图分配特定的主题。

已弃用使用app:theme样式化工具栏。您现在可以在所有API级别为7及更高的设备上使用android:theme进行工具栏样式化,并在API级别为11及更高的设备上支持所有小部件的android:theme

因此,我们不再在全局主题中设置所需的颜色,而是创建一个新的主题并仅将其分配给Button

示例:

<style name="MyColorButton" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorButtonNormal">@color/myColor</item>
</style>

并将此样式用作您的Button的主题

<Button
 style="?android:attr/buttonStyleSmall"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Button1"
 android:theme="@style/MyColorButton"/>

4
如果您愿意使用第三方库,可以查看 traex/RippleEffect, 它允许您只需几行代码就可以将 Ripple 效果添加到任何视图中。您只需要在 xml 布局文件中包裹您想要产生涟漪效果的元素,使用com.andexert.library.RippleView容器即可。
作为额外的福利,它需要 Min SDK 9,因此您可以跨操作系统版本实现设计一致性。
以下是从该库的 GitHub 存储库中获取的示例:
<com.andexert.library.RippleView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:rv_centered="true">

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@android:drawable/ic_menu_edit"
        android:background="@android:color/holo_blue_dark"/> 

</com.andexert.library.RippleView>

您可以通过向RippleView元素添加以下属性来更改涟漪颜色:app:rv_color="@color/my_fancy_ripple_color

3
<android.support.v7.widget.AppCompatButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:backgroundTint="#fff"
    android:textColor="#000"
    android:text="test"/>

使用

xmlns:app="http://schemas.android.com/apk/res-auto"

颜色将在早期的安卓版本中生效


2

以编程方式应用颜色:

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {

    ColorStateList colorStateListRipple = new ColorStateList(
            new int[][] {{0}},
            new int[] {Color.WHITE} // ripple color
            );

    RippleDrawable rippleDrawable = (RippleDrawable) myButton.getBackground();
    rippleDrawable.setColor(colorStateListRipple);
    myButton.setBackground(rippleDrawable); // applying the ripple color
}

ColorStateList colorStateList = new ColorStateList(
        new int[][]{
                new int[]{android.R.attr.state_pressed}, // when pressed
                new int[]{android.R.attr.state_enabled}, // normal state color
                new int[]{} // normal state color
        },
        new int[]{
                Color.CYAN, // when pressed
                Color.RED, // normal state color
                Color.RED // normal state color
        }
);

ViewCompat.setBackgroundTintList(myButton, colorStateList); // applying the state colors

2

通过Alex Lockwood的优秀教程,介绍了两种方法:http://www.androiddesignpatterns.com/2016/08/coloring-buttons-with-themeoverlays-background-tints.html

方法一:使用ThemeOverlay修改按钮的背景颜色

<!-- res/values/themes.xml -->
<style name="RedButtonLightTheme" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorAccent">@color/googred500</item>
</style>

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:theme="@style/RedButtonLightTheme"/>

Approach #2: Setting the AppCompatButton’s background tint

<!-- res/color/btn_colored_background_tint.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Disabled state. -->
    <item android:state_enabled="false"
          android:color="?attr/colorButtonNormal"
          android:alpha="?android:attr/disabledAlpha"/>

    <!-- Enabled state. -->
    <item android:color="?attr/colorAccent"/>

</selector>

<android.support.v7.widget.AppCompatButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:backgroundTint="@color/btn_colored_background_tint"/>


1
以编程方式:
 myMaterialButton.setRippleColor(ColorStateList.valueOf(Color.RED));

例如:

 MaterialButton myMaterialButton = new MaterialButton(this);
 myMaterialButton.setLayoutParams(myButtonParams);
 myMaterialButton.setBackgroundColor(Color.GRAY);
 myMaterialButton.setRippleColor(ColorStateList.valueOf(Color.RED));
   

-1
我尝试了这个:
android:backgroundTint:"@color/mycolor"

不要改变背景属性,这样并不能消除物质效应。


这对于早期的Lollipop设备(占70%的市场份额)不起作用。实际上,它已经被后移了,但是目前Android Studio在没有使用android前缀时仍然会显示错误。 - Siddharth Pant

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