材质效果的按钮与背景色

我使用的是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"
/>

Background 下面是一个正常的按钮,效果很好

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

Default button

231094 次浏览

当你使用android:background时,你正在用空白颜色替换按钮的大部分样式和外观。

AppCompat版本23.0.0发布中,有一个新的Widget.AppCompat.Button.Colored样式,它使用你的主题的colorButtonNormal作为禁用的颜色,colorAccent用于启用的颜色。

这可以让你直接应用到你的按钮通过

<Button
...
style="@style/Widget.AppCompat.Button.Colored" />

如果你需要自定义colorButtonNormalcolorAccent,你可以使用按钮上的这pro-tipandroid:theme中解释的ThemeOverlay

以前的回答

你可以在你的v21目录中使用一个可绘制的后台,比如:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:drawable="?attr/colorPrimary"/>
</ripple>

这将确保你的背景颜色是?attr/colorPrimary,并使用默认的?attr/colorControlHighlight拥有默认的波纹动画(如果你愿意,你也可以在你的主题中设置)。

注意:你必须为v21以下的版本创建一个自定义选择器:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/primaryPressed" android:state_pressed="true"/>
<item android:drawable="@color/primaryFocused" android:state_focused="true"/>
<item android:drawable="@color/primary"/>
</selector>

假设有一些您想要的默认、按下和聚焦状态的颜色。就我个人而言,我在被选中的过程中截取了一个波纹的屏幕截图,并从中提取了主/聚焦状态。

还有另一个简单的解决方案,为“平面”按钮提供自定义背景,同时保持它们的“材质”效果。

  1. 将你的按钮放在ViewGroup中,并在那里设置所需的背景
  2. 将当前主题中的selectableItemBackground设置为按钮的背景(API >=11)

例如:

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

可以用于按钮,它在API >=11上工作,你将在>=21设备上获得涟漪效应,保持常规按钮在pre-21上,直到AppCompat更新以支持那里的涟漪。

你也可以只对>=21个按钮使用selectableItemBackgroundBorderless

我今天在使用v22库时遇到了这个问题。

假设你正在使用样式,你可以设置colorButtonNormal属性,按钮将默认使用该颜色。

<style name="AppTheme" parent="BaseTheme">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/primaryColor</item>
<item name="colorPrimaryDark">@color/primaryColorDark</item>
<item name="colorAccent">@color/accentColor</item>
<item name="colorButtonNormal">@color/primaryColor</item>
</style>

除此之外,你还可以为按钮创建一个样式,然后使用每个按钮,如果你需要各种颜色(还没有测试,只是猜测)。

记住在你的v21风格中的项目名称之前添加android:

使用AppCompat(22.1.1+),你可以添加这样的样式:

<style name="MyGreenButton">
<item name="colorButtonNormal">#009900</item>
</style>

并通过应用样式来使用它:

<android.support.v7.widget.AppCompatButton
style="@style/MyGreenButton"
android:layout_width="match_width"
android:layout_height="wrap_content"
android:text="A Green Button"
/>

通过编程改变颜色,我发现更新颜色的唯一方法(在API 15或16上)是使用“背景色调列表”。它不会删除API 21设备上漂亮的径向动画:

ColorStateList colorStateList = new ColorStateList(new int[][] \{\{0}}, new int[] {0xFF009900}); // 0xAARRGGBB
button.setSupportBackgroundTintList(colorStateList);

因为button.setBackground(...)button.getBackground().mutate().setColorFilter(...)在API 15和16上不像在API 21上那样改变按钮的颜色。

如果你可以使用第三方库,请检查traex / RippleEffect。它允许你用几行代码向任何视图添加涟漪效应。你只需要在你的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中添加这个属性来改变波纹颜色

使用backgroundTint代替background

下面是一种简单且向后兼容的方法,可以通过自定义背景向凸起的按钮传递涟漪效应。

你的布局应该是这样的

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/my_custom_background"
android:foreground="?android:attr/selectableItemBackground"/>

我试了一下:

android:backgroundTint:"@color/mycolor"

而不是改变背景属性。

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

不赞成使用app:theme样式工具栏。您现在可以使用 android:所有API级别7及以上设备的工具栏主题 android: API级别11及以上的所有小部件的主题支持 设备。< / p >

因此,我们不再在全局主题中设置所需的颜色,而是创建一个新的主题并仅将其分配给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"/>

@ianhanniballake的回答是绝对正确和简单的。但我花了几天时间才明白。对于那些不理解他的回答的人,这里有更详细的实现

<Button
android:id="@+id/btn"
style="@style/MaterialButton"
... />




<style name="MaterialButton" parent="Widget.AppCompat.Button.Colored">
<item name="android:theme">@style/Theme.MaterialButton</item>
...
</style>




<style name="Theme.MaterialButton" parent="YourTheme">
<item name="colorAccent">@color/yourAccentColor</item>
<item name="colorButtonNormal">@color/yourButtonNormalColor</item>
</style>

= = = = = =

<Button
android:id="@+id/btn"
style="@style/Widget.AppCompat.Button.Colored"
android:theme="@style/Theme.MaterialButton" />


<style name="Theme.MaterialButton" parent="YourTheme">
<item name="colorAccent">@color/yourAccentColor</item>
<item name="colorButtonNormal">@color/yourButtonNormalColor</item>
</style>
<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"

颜色也会在棒棒糖前被接受

我使用了backgroundTint和前景:

<Button
android:layout_width="match_parent"
android:layout_height="40dp"
android:backgroundTint="@color/colorAccent"
android:foreground="?android:attr/selectableItemBackground"
android:textColor="@android:color/white"
android:textSize="10sp"/>

我来这篇文章寻找一种方法,有我的ListView项目的背景颜色,但保持波纹。

我简单地添加了我的颜色作为背景,selectableItemBackground作为前景:

<style name="my_list_item">
<item name="android:background">@color/white</item>
<item name="android:foreground">?attr/selectableItemBackground</item>
<item name="android:layout_height">@dimen/my_list_item_height</item>
</style>

它就像一个魔法。我想同样的技巧也可以用在按钮上。祝你好运。

如果你对ImageButton感兴趣,你可以尝试这个简单的事情:

<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_button"
android:background="?attr/selectableItemBackgroundBorderless"
/>

Alex Lockwood教程中解释了两种方法:http://www.androiddesignpatterns.com/2016/08/coloring-buttons-with-themeoverlays-background-tints.html:

方法#1:修改按钮的背景颜色w/ 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"/>

方法2:设置AppCompatButton的背景色调

<!-- 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"/>

以编程方式应用颜色:

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

编程:

 myMaterialButton.setRippleColor(ColorStateList.valueOf(Color.RED));

例如:

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