android主题设置与主题切换

前不久碰到了需要给软件更换主题的问题,研究了一段时间后可以基本实现功能了,在这里拿出来分享下方法,如有不足欢迎指正。
要想实现主题切换,我们得自定义一些主题的属性,自定义属性的attrs.xml新建在res/values下面。在这里我定义了软件背景,对话框图案和按钮的样式。


有了自定义主题属性后,就可以编写自己的主题了,同样在values文件夹里,找到styles.xml,可以看到里面有一个默认的系统主题,不用管它,在下面写自己主题的各种属性。注意我们的自定义主题也需要继承系统主题,也就是style的parent属性。

这里我用的是四季变化的主题,(说实话,由于不大会用PS软件,我做这套主题图片花的时间比我写代码要长多了。找到好看的背景,然后强迫症发作一定要搞定相匹配的对话框与按钮)大家可以选择自己喜欢的图片来替换这些。
这样一来前期准备就完成了,剩下的就是代码实现。由于主题切换涉及到很多的界面都需要更换背景,所以我干脆重写了Activity,需要更换背景的活动直接继承自己写的MyActivity会省事一些。
public class MyActivity extends Activity { public int mytheme; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SharedPreferences sharedPreferences = getSharedPreferences("info", MODE_PRIVATE); mytheme = sharedPreferences.getInt("theme", 1); if (mytheme == 1) { setTheme(R.style.SpringTheme); } else if (mytheme == 2) { setTheme(R.style.SummerTheme); } else if (mytheme == 3) { setTheme(R.style.AutumnTheme); } else if (mytheme == 4) { setTheme(R.style.WinterTheme); } else { setTheme(R.style.SpringTheme); } }@Override protected void onResume() { super.onResume(); if (mytheme != getSharedPreferences("info", MODE_PRIVATE).getInt("theme", 1)) { changetheme(); } }protected void changetheme() { Intent intent = getIntent(); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); //它可以关掉所到的界面中间的activity startActivity(intent); overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); //设置进入退出动画 finish(); } }

我是把切换过得主题用SharedPreferences保存下来,这样即使下次打开后还是上一次切换后的主题。这里的核心语句是setTheme(R.style.XXX),表示想要切换的主题。对于主题切换过程中的动画我这里使用的是渐出与渐入,大家也可以凭自己爱好修改。
注意,如果没有重写Acticvity,在活动中切换主题时记得把setTheme这一句放在setContentView的前面,不然有可能程序会出错,因为setContentView后活动的界面已经完成了,再设置主题在顺序上就有问题。在onResume()中进行界面跳转,这样不仅当前界面会切换主题背景,跳回前面的界面会发现背景也跟着变了。
最后就是具体的继承MyActivity来实现主题切换功能了。新建一个活动继承MyActivity,这里我只设置了一个按钮,点击弹出对话框提示是否确认切换主题,点确认就可以看到旧背景淡出,新背景淡入,且按钮的样式有了变化,点击按钮出现的对话框背景也相应变化。
下面是每次点击切换主题时候的逻辑代码,每次从SharedPreferences中取出当前主题代号,并相应地把代号往后挪一位再存进去。每次都调用onResume()方法来保证当前界面也能立即切换。
private void changethemeonce() { SharedPreferences sharedPreferences = getSharedPreferences("info", MODE_PRIVATE); int theme = sharedPreferences.getInt("theme", 1); if (theme == 1) { SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putInt("theme", 2); editor.apply(); onResume(); } else if (theme == 2) { SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putInt("theme", 3); editor.apply(); onResume(); } else if (theme == 3) { SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putInt("theme", 4); editor.apply(); onResume(); } else if (theme == 4) { SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putInt("theme", 1); editor.apply(); onResume(); }

至于对话框样式的xml文件和刚进入程序的过渡Activity比较简单,大家可以按需求改动,在这里就不贴出来了,有兴趣的话可以下载来自己改着玩。
【android主题设置与主题切换】下载地址

    推荐阅读