前言
在应用开发中会经常遇到要求实现夜间模式
或者主题切换
具体例子如下,我会先讲解第一种方法。
夜间模式
- 知乎
- 网易新闻
- 沪江开心词场
主题切换
- 腾讯QQ
- 新浪微博
我今天主要是详述第一种的实现方式:
- 首先,应用的Application要继承自定义的Theme
1 2 3 4 5 6 |
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> </application> |
- 其实AppTheme要实现日间和夜间两种Theme
1 2 3 4 5 6 7 8 9 |
<style name="AppTheme"/> <style name="AppTheme.Light"> <item name="root_background">@color/white</item> </style> <style name="AppTheme.Dark"> <item name="root_background">@color/black</item> </style> |
- 在自定义属性attr.xml中添加如下:
1 2 3 |
<declare-styleable name="Theme"> <attr name="root_background" format="reference|color" /> </declare-styleable> |
- 在layout中引用自定义属性
1 2 3 4 5 6 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="?attr/root_background"> </RelativeLayout> |
- 代码中设置切换:所有Activity都继承BaseThemeActivity,将是否夜间模式的bool值保存在SharedPreferences中切换 SharedPreferences 中 is_night_mode 的值 ,然后调用 restartActivity()重启当前Activity方法即可切换Theme.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
@Override protected void onCreate(Bundle savedInstanceState) { setTheme(); super.onCreate(savedInstanceState); } private void setTheme() { mCurrentThemeResourceID = getThemeResourceID(); setTheme(mCurrentThemeResourceID); } private int getThemeResourceID() { mIsNightModule = PreferencesUtils.getBoolean(this, getResources().getString(R.string.is_night_mode)); return mIsNightModule ? R.style.AppTheme_Dark : R.style.AppTheme_Light; } public static void restartActivity(final Activity activity) { if (activity == null) return; final int enter_anim = android.R.anim.fade_in; final int exit_anim = android.R.anim.fade_out; activity.overridePendingTransition(enter_anim, exit_anim); activity.finish(); activity.overridePendingTransition(enter_anim, exit_anim); activity.startActivity(activity.getIntent()); } private final boolean isThemeChanged() { return getThemeResourceID() != mCurrentThemeResourceID; } @Override protected void onResume() { super.onResume(); if (isThemeChanged()) { restartActivity(this); } } |
总结
- 其中要注意的是setTheme()方法一定要在super.onCreate(savedInstanceState);之前调用即可
- 可用此方式实现多种theme的切换
以后会发博文讲解如何实现主题下载,主题切换等功能。
如果想和我讨论,请在下面评论即可。