以前寫過一篇文章:RxBus的實現及簡單使用。今天咱們嘗試使用RxBus動態切換主題。android
color.xmlgit
<color name="red_primary">#F44336</color> <color name="red_primary_dark">#D32F2F</color> <color name="red_accent">#F44336</color> <color name="pink_primary">#E91E63</color> <color name="pink_primary_dark">#C2185B</color> <color name="pink_accent">#E91E63</color> <color name="brown_primary">#795548</color> <color name="brown_primary_dark">#5D4037</color> <color name="brown_accent">#795548</color> <color name="blue_primary">#2196F3</color> <color name="blue_primary_dark">#1976D2</color> <color name="blue_accent">#2196F3</color> <color name="blue_grey_primary">#607D8B</color> <color name="blue_grey_primary_dark">#455A64</color> <color name="blue_grey_accent">#607D8B</color> <color name="yellow_primary">#FFEB3B</color> <color name="yellow_primary_dark">#FBC02D</color> <color name="yellow_accent">#FFEB3B</color> <color name="deep_purple_primary">#673AB7</color> <color name="deep_purple_primary_dark">#512DA8</color> <color name="deep_purple_accent">#673AB7</color> <color name="green_primary">#4CAF50</color> <color name="green_primary_dark">#388E3C</color> <color name="green_accent">#4CAF50</color> <color name="deep_orange_primary">#FF5722</color> <color name="deep_orange_primary_dark">#E64A19</color> <color name="deep_orange_accent">#FF5722</color> <color name="grey_primary">#9E9E9E</color> <color name="grey_primary_dark">#616161</color> <color name="grey_accent">#9E9E9E</color> <color name="cyan_primary">#00BCD4</color> <color name="cyan_primary_dark">#0097A7</color> <color name="cyan_accent">#00BCD4</color> <color name="amber_primary">#FFC107</color> <color name="amber_primary_dark">#FFA000</color> <color name="amber_accent">#FFC107</color> <color name="primary">#2196F3</color> <color name="primary_dark">#1E88E5</color> <color name="accent">@color/primary</color>
styles.xmlgithub
<style name="RedTheme" parent="AppTheme"> <item name="colorPrimary">@color/red_primary</item> <item name="colorPrimaryDark">@color/red_primary_dark</item> <item name="colorAccent">@color/red_accent</item> </style> <style name="PinkTheme" parent="AppTheme"> <item name="colorPrimary">@color/pink_primary</item> <item name="colorPrimaryDark">@color/pink_primary_dark</item> <item name="colorAccent">@color/pink_accent</item> </style> <style name="BrownTheme" parent="AppTheme"> <item name="colorPrimary">@color/brown_primary</item> <item name="colorPrimaryDark">@color/brown_primary_dark</item> <item name="colorAccent">@color/brown_accent</item> </style> <style name="BlueTheme" parent="AppTheme"> <item name="colorPrimary">@color/blue_primary</item> <item name="colorPrimaryDark">@color/blue_primary_dark</item> <item name="colorAccent">@color/blue_accent</item> </style> <style name="BlueGreyTheme" parent="AppTheme"> <item name="colorPrimary">@color/blue_grey_primary</item> <item name="colorPrimaryDark">@color/blue_grey_primary_dark</item> <item name="colorAccent">@color/blue_grey_accent</item> </style> <style name="YellowTheme" parent="AppTheme"> <item name="colorPrimary">@color/yellow_primary</item> <item name="colorPrimaryDark">@color/yellow_primary_dark</item> <item name="colorAccent">@color/yellow_accent</item> </style> <style name="DeepPurpleTheme" parent="AppTheme"> <item name="colorPrimary">@color/deep_purple_primary</item> <item name="colorPrimaryDark">@color/deep_purple_primary_dark</item> <item name="colorAccent">@color/deep_purple_accent</item> </style> <style name="GreenTheme" parent="AppTheme"> <item name="colorPrimary">@color/green_primary</item> <item name="colorPrimaryDark">@color/green_primary_dark</item> <item name="colorAccent">@color/green_accent</item> </style> <style name="DeepOrangeTheme" parent="AppTheme"> <item name="colorPrimary">@color/deep_orange_primary</item> <item name="colorPrimaryDark">@color/deep_orange_primary_dark</item> <item name="colorAccent">@color/deep_orange_accent</item> </style> <style name="GreyTheme" parent="AppTheme"> <item name="colorPrimary">@color/grey_primary</item> <item name="colorPrimaryDark">@color/grey_primary_dark</item> <item name="colorAccent">@color/grey_accent</item> </style> <style name="CyanTheme" parent="AppTheme"> <item name="colorPrimary">@color/cyan_primary</item> <item name="colorPrimaryDark">@color/cyan_primary_dark</item> <item name="colorAccent">@color/cyan_accent</item> </style> <style name="AmberTheme" parent="AppTheme"> <item name="colorPrimary">@color/amber_primary</item> <item name="colorPrimaryDark">@color/amber_primary_dark</item> <item name="colorAccent">@color/amber_accent</item> </style>
private void showThemeChooseDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setTitle("設置主題"); Integer[] res = new Integer[]{R.drawable.red_round, R.drawable.brown_round, R.drawable.blue_round, R.drawable.blue_grey_round, R.drawable.yellow_round, R.drawable.deep_purple_round, R.drawable.pink_round, R.drawable.green_round, R.drawable.deep_orange_round, R.drawable.grey_round, R.drawable.cyan_round}; List<Integer> list = Arrays.asList(res); ColorsListAdapter adapter = new ColorsListAdapter(MainActivity.this, list); adapter.setCheckItem(MyThemeUtils.getCurrentTheme(MainActivity.this).getIntValue()); GridView gridView = (GridView) LayoutInflater.from(MainActivity.this).inflate(R.layout.colors_panel_layout, null); gridView.setStretchMode(GridView.STRETCH_COLUMN_WIDTH); gridView.setCacheColorHint(0); gridView.setAdapter(adapter); builder.setView(gridView); final AlertDialog dialog = builder.show(); gridView.setOnItemClickListener( new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { dialog.dismiss(); int value = MyThemeUtils.getCurrentTheme(MainActivity.this).getIntValue(); if (value != position) { PreferenceUtils.getInstance(MainActivity.this).saveParam("change_theme_key", position); changeTheme(MyThemeUtils.Theme.mapValueToTheme(position)); } } } ); }
在drawable下新建red_round.xml,其餘主題顏色相似segmentfault
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="@color/red_primary"/> </shape
ColorsListAdapteride
public class ColorsListAdapter extends BaseAdapter { private int checkItem; Context context; List<Integer> list; public ColorsListAdapter(Context context, List<Integer> list) { this.context = context; this.list = list; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Holder holder; if (convertView == null) { convertView = LayoutInflater.from(context).inflate(R.layout.colors_image_layout, null); holder = new Holder(); holder.imageView1 = (ImageView) convertView.findViewById(R.id.img_1); holder.imageView2 = (ImageView) convertView.findViewById(R.id.img_2); convertView.setTag(holder); } else { holder = (Holder) convertView.getTag(); } holder.imageView1.setImageResource(list.get(position)); if (checkItem == position) { holder.imageView2.setImageResource(R.drawable.ic_done_white); } return convertView; } public void setCheckItem(int checkItem) { this.checkItem = checkItem; } static class Holder { ImageView imageView1; ImageView imageView2; } }
colors_image_layout.xml工具
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@android:color/transparent" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:id="@+id/img_1" android:layout_gravity="center" android:layout_width="40dp" android:layout_height="40dp" /> <ImageView android:id="@+id/img_2" android:layout_gravity="center" android:layout_width="20dp" android:layout_height="20dp" /> </FrameLayout>
發佈post
private void changeTheme(MyThemeUtils.Theme theme) { RxBus.getInstance().post(new RxbusEvent(theme)); }
接收ui
rxSbscription=RxBus.getInstance().toObserverable(RxbusEvent.class) .subscribe(new Action1<RxbusEvent>() { @Override public void call(RxbusEvent rxbusEvent) { changeTheme(rxbusEvent.getTheme()); } });
PreferenceUtilsthis
public class PreferenceUtils { private SharedPreferences sharedPreferences; private SharedPreferences.Editor shareEditor; private static PreferenceUtils preferenceUtils = null; public static final String NOTE_TYPE_KEY = "NOTE_TYPE_KEY"; public static final String EVERNOTE_ACCOUNT_KEY = "EVERNOTE_ACCOUNT_KEY"; public static final String EVERNOTE_NOTEBOOK_GUID_KEY = "EVERNOTE_NOTEBOOK_GUID_KEY"; private PreferenceUtils(Context context){ sharedPreferences = context.getSharedPreferences("ThemeSetting", Context.MODE_PRIVATE); shareEditor = sharedPreferences.edit(); } public static PreferenceUtils getInstance(Context context){ if (preferenceUtils == null) { synchronized (PreferenceUtils.class) { if (preferenceUtils == null) { preferenceUtils = new PreferenceUtils(context.getApplicationContext()); } } } return preferenceUtils; } public String getStringParam(String key){ return getStringParam(key, ""); } public String getStringParam(String key, String defaultString){ return sharedPreferences.getString(key, defaultString); } public void saveParam(String key, String value) { shareEditor.putString(key,value).commit(); } public boolean getBooleanParam(String key){ return getBooleanParam(key, false); } public boolean getBooleanParam(String key, boolean defaultBool){ return sharedPreferences.getBoolean(key, defaultBool); } public void saveParam(String key, boolean value){ shareEditor.putBoolean(key, value).commit(); } public int getIntParam(String key){ return getIntParam(key, 0); } public int getIntParam(String key, int defaultInt){ return sharedPreferences.getInt(key, defaultInt); } public void saveParam(String key, int value){ shareEditor.putInt(key, value).commit(); } public long getLongParam(String key){ return getLongParam(key, 0); } public long getLongParam(String key, long defaultInt){ return sharedPreferences.getLong(key, defaultInt); } public void saveParam(String key, long value){ shareEditor.putLong(key, value).commit(); } public void removeKey(String key){ shareEditor.remove(key).commit(); } }
MyThemeUtilsspa
public class MyThemeUtils { public static void changTheme(Activity activity, Theme theme) { if (activity == null) return; int style = R.style.RedTheme; switch (theme) { case BROWN: style = R.style.BrownTheme; break; case BLUE: style = R.style.BlueTheme; break; case BLUE_GREY: style = R.style.BlueGreyTheme; break; case YELLOW: style = R.style.YellowTheme; break; case DEEP_PURPLE: style = R.style.DeepPurpleTheme; break; case PINK: style = R.style.PinkTheme; break; case GREEN: style = R.style.GreenTheme; break; case DEEP_ORANGE: style = R.style.DeepOrangeTheme; break; case GREY: style = R.style.GreyTheme; break; case CYAN: style = R.style.CyanTheme; break; case AMBER: style = R.style.AmberTheme; break; default: break; } activity.setTheme(style); } public static Theme getCurrentTheme(Context context) { int value = PreferenceUtils.getInstance(context) .getIntParam("change_theme_key", 0); return MyThemeUtils.Theme.mapValueToTheme(value); } public enum Theme { RED(0), BROWN(1), BLUE(2), BLUE_GREY(3), YELLOW(4), DEEP_PURPLE(5), PINK(6), GREEN(7), DEEP_ORANGE(8), GREY(9), CYAN(10), AMBER(11); private int mValue; Theme(int value) { this.mValue = value; } public static Theme mapValueToTheme(final int value) { for (Theme theme : Theme.values()) { if (value == theme.getIntValue()) { return theme; } } // If run here, return default return RED; } static Theme getDefault() { return RED; } public int getIntValue() { return mValue; } } }
基類BaseActivity,主題的初始化。注意,須要變換主題的Activity需繼承BaseActivity
public class BaseActivity extends AppCompatActivity { protected PreferenceUtils preferenceUtils; @Override protected void onCreate(Bundle savedInstanceState) { preferenceUtils = PreferenceUtils.getInstance(this); initTheme(); super.onCreate(savedInstanceState); } private void initTheme() { MyThemeUtils.Theme theme = MyThemeUtils.getCurrentTheme(this); MyThemeUtils.changTheme(this, theme); } }