您可以在一个布局中参数化视图,而不是提供两种不同的布局。因此,您的布局视图会从它们膨胀的上下文主题中获取参数(例如背景颜色、文本颜色)。
所以,这就是我们想要实现的目标:
<android.support.constraint.ConstraintLayout
android:background="?attr/bgColor"
... >
<TextView
android:textColor="?attr/textColor"
... />
</android.support.constraint.ConstraintLayout>
?attr/someAttribute 将取自当前上下文的主题。
在values/ 中的attrs.xml 创建属性:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyAttrs">
<attr name="bgColor" format="reference|color"/>
<attr name="textColor" format="color"/>
</declare-styleable>
</resources>
在styles.xml 中声明从一个共同主题扩展而来的两个主题:
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
...
</style>
<style name="AppTheme.Default">
<item name="bgColor">@color/red</item>
<item name="textColor">@color/blue</item>
</style>
<style name="AppTheme.Accessibility">
<item name="bgColor">@color/orange</item>
<item name="textColor">@color/yellow</item>
</style>
</resources>
然后,在您的活动中执行断言并设置正确的主题:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
setTheme(isAccessibility ? R.style.AppTheme_Accessibility : R.style.AppTheme_Default);
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
...
}
或者,如果您必须在运行时执行此操作,您可以使用 ContextThemeWrapper 为特定视图添加适当的主题。
Context wrapper = new ContextThemeWrapper(MyFragment.this.getContext(), R.style.AppTheme_Accessibility);
// inflating with a `wrapper`, not with the activity's theme
View themedView = View.inflate(wrapper, R.layout.some_layout, parent);
这比提供两个单独的布局要好得多,因为它可以避免在 UI 发生变化时维护两个布局。