文章转载自 https://www.jianshu.com/p/66c6a97a8d80
场景
在 Android 5.0 以上的设备中,API 提供的 Button 样式自带了 Material Design 风格,默认的颜色还是灰色。但在大多数情况下我们需要修改 Button 的颜色来适应我们应用的整体风格。
当我们和往常一样通过设置 android:background
属性来改变 Button 的颜色后,实际应用发现 Button 失去了 Material Design 效果,变得很一般。当尝试用 selector
来实现时,发现处理过程工作量不少,而且效果也不明显。
那么如何修改默认 Button 的颜色,而不改变默认 Button 的其它特性呢?
解决思路
1、追踪默认 Button 样式是如何设置的?
在 .../res/styles.xml
文件中我们可以看到应用默认的style
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
继续跟踪 Theme.AppCompat.Light.DarkActionBar
<style name="Theme.AppCompat.Light.DarkActionBar" parent="Base.Theme.AppCompat.Light.DarkActionBar"/>
继续跟踪 Base.Theme.AppCompat.Light.DarkActionBar
<style name="Base.Theme.AppCompat.Light.DarkActionBar" parent="Base.Theme.AppCompat.Light">
<item name="actionBarPopupTheme">@style/ThemeOverlay.AppCompat.Light</item>
<item name="actionBarWidgetTheme">@null</item>
<item name="actionBarTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
<!-- Panel attributes -->
<item name="listChoiceBackgroundIndicator">@drawable/abc_list_selector_holo_dark</item>
<item name="colorPrimaryDark">@color/primary_dark_material_dark</item>
<item name="colorPrimary">@color/primary_material_dark</item>
</style>
继续跟踪 Base.Theme.AppCompat.Light
,会提示有不同版本,通过一一跟踪,最终继承的 parent style 都是 Base.V7.Theme.AppCompat.Light
<style name="Base.V7.Theme.AppCompat.Light" parent="Platform.AppCompat.Light">
...
<!-- Button styles -->
<item name="buttonStyle">@style/Widget.AppCompat.Button</item>
<item name="buttonStyleSmall">@style/Widget.AppCompat.Button.Small</item>
<item name="android:textAppearanceButton">@style/TextAppearance.AppCompat.Widget.Button</item>
...
</style>
发现其中设置了 buttonStyle
,继续跟踪 Widget.AppCompat.Button
<style name="Widget.AppCompat.Button" parent="Base.Widget.AppCompat.Button"/>
继续跟踪 Base.Widget.AppCompat.Button
,不同版本有不同的实现
- v21之前
<style name="Base.Widget.AppCompat.Button" parent="android:Widget">
<item name="android:background">@drawable/abc_btn_default_mtrl_shape</item>
<item name="android:textAppearance">?android:attr/textAppearanceButton</item>
<item name="android:minHeight">48dip</item>
<item name="android:minWidth">88dip</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
<item name="android:gravity">center_vertical|center_horizontal</item>
</style>
- v21及之后
<style name="Base.Widget.AppCompat.Button" parent="android:Widget.Material.Button"/>
...
<style name="Widget.Material.Button">
<item name="background">@drawable/btn_default_material</item>
<item name="textAppearance">?attr/textAppearanceButton</item>
<item name="minHeight">48dip</item>
<item name="minWidth">88dip</item>
<item name="stateListAnimator">@anim/button_state_list_anim_material</item>
<item name="focusable">true</item>
<item name="clickable">true</item>
<item name="gravity">center_vertical|center_horizontal</item>
</style>
可以看到针对不同版本分别设置了 Button 的样式。
2、通过 buttonStyle 对 Button 颜色进行设置
通过上面的分析过程得知,我们可以通过 buttonStyle
属性来指定 Button 的样式。
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<!-- 设置button的Style -->
<item name="buttonStyle">@style/Xxx</item>
</style>
而在V7支持包中,提供了5个预置的 Button 的 Style,如下:
<style name="Widget.AppCompat.Button" parent="Base.Widget.AppCompat.Button"/>
<style name="Widget.AppCompat.Button.Colored" parent="Base.Widget.AppCompat.Button.Colored"/>
<style name="Widget.AppCompat.Button.Borderless" parent="Base.Widget.AppCompat.Button.Borderless"/>
<style name="Widget.AppCompat.Button.Borderless.Colored" parent="Base.Widget.AppCompat.Button.Borderless.Colored"/>
<style name="Widget.AppCompat.Button.Small" parent="Base.Widget.AppCompat.Button.Small"/>
style | 背景颜色属性 | 文字颜色属性 | 效果 |
---|---|---|---|
.Button(默认) | colorButtonNormal | textColor (默认黑色) | ![]() |
.Button.Colored | colorAccent | …(默认白色) | ![]() |
.Button.Borderless | 透明 | …(默认黑色) | ![]() |
.Button.Borderless.Colored | 透明 | …(默认colorAccent) | ![]() |
.Button.Small | colorButtonNormal | …(默认黑色) | ![]() |
3、通过 ButtonStyle 修改 Button 颜色
3.1、将 ButtonStyle 应用到全局 Button
直接在应用主题中设置 buttonStyle,然后通过相应的属性修改 Button 的背景色或文字颜色。如下:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="buttonStyle">@style/Widget.AppCompat.Button</item>
<item name="colorButtonNormal">@color/colorBlue</item>
</style>
3.2、单个具体 Button 设置
在 styles.xml 文件中新建 Style,继承应用 Style,在其中设置 buttonStyle,并通过相应的属性修改 Button 的背景色或文字颜色。然后在需要修改的 Button 中添加 android:theme
属性,引用新建的 Style 即可
<style name="RedButton" parent="AppTheme">
<item name="buttonStyle">@style/Widget.AppCompat.Button</item>
<item name="colorButtonNormal">@color/colorRed</item>
</style>
在 layout 中使用
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button_1"
android:theme="@style/RedButton" />
<!-- 注意是android:theme属性,不是style属性 -->
4、修改 Button 圆角大小
目前只找到了全局修改 Button 圆角大小的方法在 dimes.xml
文件中复写 abc_control_corner_material
的值,可以修改应用内所有 Button 的圆角大小
<dimen name="abc_control_corner_material" tools:override="true">8dp</dimen>
文章只是作为个人记录学习使用,如有不妥之处请指正,谢谢。