Android不同主题为何生成不同Button类?主题中哪个属性控制?
问题描述
我在布局中定义了一个常规Button,并在AndroidManifest的android:theme中应用主题:
<Button android:id="@+id/supperButton" android:layout_width="match_parent" android:layout_height="120dp" />
<style name="AppTheme" parent="Theme.AppCompat"> </style>
通过Inflater加载该Button后,用调试器查看实例类,发现生成的是AppCompatButton而非原生Button。
将主题修改为Material Components系列后:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> </style>
此时生成的实例变成了MaterialButton,而非原生Button或AppCompatButton。
问题:主题显然能控制最终使用的具体控件类型,那么是由主题中的哪个属性定义的?
回答
这是Android布局Inflater的控件替换机制,结合主题中的样式属性共同实现的,核心关联的是这两个部分:
- 主题中的
buttonStyle属性:它指定了Button控件的默认样式。 - 样式内部的
android:viewClass属性:这个属性会明确指定要实例化的控件类路径。
具体到你遇到的两种场景:
- 用
Theme.AppCompat时,主题默认的buttonStyle是@style/Widget.AppCompat.Button。AppCompat框架的AppCompatViewInflater会自动拦截原生Button的创建流程,直接替换为AppCompatButton——这是AppCompat的内置规则,不需要样式里显式写viewClass。 - 切换到
Theme.MaterialComponents时,主题默认的buttonStyle是@style/Widget.MaterialComponents.Button,这个样式里通过android:viewClass指定了com.google.android.material.button.MaterialButton,LayoutInflater就会根据这个属性值创建对应的控件实例。
简单来说,主题通过buttonStyle指定默认样式,样式里的viewClass(或框架内置替换规则)决定了最终生成的控件类型。
内容的提问来源于stack exchange,提问作者VanechikSpace
相关产品推荐
相关产品推荐

