Android:如何找到覆写现有?attr样式的父样式名称?
问题描述
我在Fragment中使用MaterialButtonToggleGroup包含两个按钮,布局代码如下:
<com.google.android.material.button.MaterialButtonToggleGroup android:id="@+id/hide_show_all_models_toggle_group" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginHorizontal="@dimen/size_small" android:layout_marginBottom="@dimen/size_medium" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:selectionRequired="true" app:singleSelection="true"> <Button android:id="@+id/show_all_models_button" style="?attr/materialIconButtonOutlinedStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="end" android:paddingStart="@dimen/size_medium" android:paddingEnd="@dimen/size_large" android:text="@string/show_all" app:icon="@drawable/ic_show" app:rippleColor="#6b0000" tools:ignore="RtlSymmetry" /> <Button android:id="@+id/hide_all_models_button" style="?attr/materialIconButtonOutlinedStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="start" android:paddingStart="@dimen/size_large" android:paddingEnd="@dimen/size_medium" android:text="@string/hide_all" app:colorSecondaryContainer="#D2070E" app:icon="@drawable/ic_hide" app:iconGravity="end" app:rippleColor="#6b0000" tools:ignore="RtlSymmetry" /> </com.google.android.material.button.MaterialButtonToggleGroup>
我需要为选中状态的按钮设置不同的背景、图标颜色和文本颜色,打算覆写?attr/materialIconButtonOutlinedStyle,但不知道该用什么父样式。之前尝试用Widget.Material3.Button.OutlinedButton作为父样式:
<style name="App.Material3.Button.OutlinedButton" parent="Widget.Material3.Button.OutlinedButton"> <item name="backgroundTint">@color/app_m3_text_button_background_color_selector</item> </style>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="#D2070E" android:state_enabled="true" android:state_checked="true"/> <item android:color="?attr/colorContainer"/> </selector>
但这导致按钮其他样式异常,因为Widget.Material3.Button.OutlinedButton对应的是?attr/materialButtonOutlinedStyle,而非目标的materialIconButtonOutlinedStyle。Ctrl+点击该属性只能看到Material库中的属性声明,无法找到实际对应的父样式名称,这类覆写属性引用样式的场景经常遇到,不知道如何解决。
解决方案
一、找到materialIconButtonOutlinedStyle对应的父样式
在Material 3设计库中,?attr/materialIconButtonOutlinedStyle对应的实际父样式是**Widget.Material3.IconButton.Outlined**,这是专门为带图标的按钮设计的样式,和普通OutlinedButton的样式结构不同,这也是之前用错父样式导致异常的核心原因。
二、正确自定义选中状态样式
基于正确的父样式创建自定义样式,同时为背景、图标颜色、文本颜色设置状态选择器:
- 创建背景色选择器
res/color/app_icon_button_background_selector.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 选中状态背景色 --> <item android:color="#D2070E" android:state_checked="true" android:state_enabled="true"/> <!-- 默认状态背景色 --> <item android:color="?attr/colorContainer"/> </selector>
- 创建图标/文本颜色选择器
res/color/app_icon_button_tint_selector.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 选中状态颜色 --> <item android:color="#FFFFFF" android:state_checked="true" android:state_enabled="true"/> <!-- 默认状态颜色 --> <item android:color="?attr/colorOnSurface"/> </selector>
- 在
res/values/styles.xml中定义自定义样式:
<style name="App.Material3.IconButton.Outlined" parent="Widget.Material3.IconButton.Outlined"> <!-- 背景色 --> <item name="backgroundTint">@color/app_icon_button_background_selector</item> <!-- 图标颜色 --> <item name="iconTint">@color/app_icon_button_tint_selector</item> <!-- 文本颜色 --> <item name="textColor">@color/app_icon_button_tint_selector</item> <!-- 保留原有波纹颜色 --> <item name="rippleColor">#6b0000</item> </style>
三、应用自定义样式
有两种方式应用自定义样式:
- 全局替换:在App主题中覆写
materialIconButtonOutlinedStyle属性,让所有使用该样式的按钮自动生效:
<style name="AppTheme" parent="Theme.Material3.DayNight.NoActionBar"> ... <item name="materialIconButtonOutlinedStyle">@style/App.Material3.IconButton.Outlined</item> </style>
- 局部替换:直接在按钮的
style属性中引用自定义样式:
<Button android:id="@+id/show_all_models_button" style="@style/App.Material3.IconButton.Outlined" .../>
四、通用查找属性对应父样式的方法
遇到?attr/xxxStyle类属性找不到对应父样式时,可采用以下方法:
- 查看Material库源码:在Android Studio中找到Material库的
res/values/styles.xml文件,搜索目标属性名称,即可找到它在主题中对应的父样式赋值。 - 使用Theme Editor:打开Android Studio的
Tools > Theme Editor,在主题中找到对应的样式属性,查看其默认值。 - 参考Material Design官方文档:官方文档会明确标注每个组件样式属性对应的基础父样式名称。
内容的提问来源于stack exchange,提问作者Leonardo Sibela
相关产品推荐
相关产品推荐

