Android Java如何动态修改主题中textColorAnswer等自定义属性值
Android 动态修改自定义主题属性的实现方案
Android 中已加载应用到当前页面的主题无法直接修改原有属性值,通常有以下两种常用可行方案实现自定义属性动态替换:
前置要求:首先需要确保
textColorAnswer和layoutColorAnswer已经在res/values/attrs.xml中声明为自定义属性:<declare-styleable name="AppTheme"> <attr name="textColorAnswer" format="color" /> <attr name="layoutColorAnswer" format="color" /> </declare-styleable>
方案1:切换完整主题重建页面(适合全局主题切换场景)
如果是全局统一替换主题属性,可预先定义多套主题样式,切换后重建页面即可生效:
- 预先定义多套主题样式,除原有主题外新增修改属性后的主题:
<!-- 原有主题 --> <style name="apptheme.home"> <item name="textColorAnswer">@color/blue</item> <item name="layoutColorAnswer">@color/red</item> </style> <!-- 修改属性后的新主题 --> <style name="apptheme.home.modified"> <item name="textColorAnswer">@color/green</item> <item name="layoutColorAnswer">@color/yellow</item> </style>
- Activity 中切换主题逻辑:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 读取存储的当前主题id,设置后再加载布局 int currentThemeId = getSharedPreferences("theme_config", MODE_PRIVATE) .getInt("theme_id", R.style.apptheme_home); setTheme(currentThemeId); setContentView(R.layout.activity_home); } // 触发主题切换的逻辑 public void switchTheme() { // 存储新主题id getSharedPreferences("theme_config", MODE_PRIVATE) .edit() .putInt("theme_id", R.style.apptheme_home_modified) .apply(); // 重建页面让主题生效 recreate(); }
方案2:动态叠加属性无需重建页面(适合小范围属性修改场景)
如果不想重建页面,可使用系统公开APIapplyStyle()叠加属性覆盖层,新加载的控件会自动读取更新后的属性,已渲染的控件手动刷新即可:
- 先定义仅包含需要修改属性的主题覆盖层:
<style name="ThemeOverlay.Home.ModifyColor"> <item name="textColorAnswer">#FF00FF</item> <item name="layoutColorAnswer">#00FFFF</item> </style>
- Java 代码中叠加属性:
// 给当前页面主题叠加属性覆盖层,第二个参数传true表示新属性覆盖原有值 getTheme().applyStyle(R.style.ThemeOverlay_Home_ModifyColor, true); // 已显示的控件手动刷新属性 TypedArray ta = obtainStyledAttributes(new int[]{R.attr.textColorAnswer, R.attr.layoutColorAnswer}); int newTextColor = ta.getColor(0, Color.BLACK); int newLayoutColor = ta.getColor(1, Color.WHITE); ta.recycle(); // 手动赋值给对应控件 TextView answerText = findViewById(R.id.answer_text); answerText.setTextColor(newTextColor); findViewById(R.id.answer_layout).setBackgroundColor(newLayoutColor);
内容的提问来源于stack exchange,提问作者Thầy Giáo Long
相关产品推荐
相关产品推荐

