前不久碰到了需要给软件更换主题的问题,研究了一段时间后可以基本实现功能了,在这里拿出来分享下方法,如有不足欢迎指正。
要想实现主题切换,我们得自定义一些主题的属性,自定义属性的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主题设置与主题切换】下载地址