android主题设置与主题切换

前不久碰到了需要给软件更换主题的问题,研究了一段时间后可以基本实现功能了,在这里拿出来分享下方法,如有不足欢迎指正。

要想实现主题切换,我们得自定义一些主题的属性,自定义属性的attrs.xml新建在res/values下面。在这里我定义了软件背景,对话框图案和按钮的样式。

<resources>
    <attr name="back_ground" format="reference" />
    <attr name="dialog_back" format="reference" />
    <attr name="dialog_button1" format="reference" />
    <attr name="dialog_button2" format="reference" />
</resources>

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

<resources>

    <!-- Base application theme. -->
    <style name="AppBaseTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

    <style name="SpringTheme" parent="AppBaseTheme">
        <item name="back_ground">@drawable/spring</item>
        <item name="dialog_back">@drawable/spring_dialog</item>
        <item name="dialog_button1">@drawable/spring_button1</item>
        <item name="dialog_button2">@drawable/spring_button2</item>
    </style>

    <style name="SummerTheme" parent="AppBaseTheme">
        <item name="back_ground">@drawable/summer</item>
        <item name="dialog_back">@drawable/summer_dialog</item>
        <item name="dialog_button1">@drawable/summer_button1</item>
        <item name="dialog_button2">@drawable/summer_button2</item>
    </style>

    <style name="AutumnTheme" parent="AppBaseTheme">
        <item name="back_ground">@drawable/autumn</item>
        <item name="dialog_back">@drawable/autumn_dialog</item>
        <item name="dialog_button1">@drawable/autumn_button1</item>
        <item name="dialog_button2">@drawable/autumn_button2</item>
    </style>

    <style name="WinterTheme" parent="AppBaseTheme">
        <item name="back_ground">@drawable/winter</item>
        <item name="dialog_back">@drawable/winter_dialog</item>
        <item name="dialog_button1">@drawable/winter_button1</item>
        <item name="dialog_button2">@drawable/winter_button2</item>
    </style>

</resources>

这里我用的是四季变化的主题,(说实话,由于不大会用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比较简单,大家可以按需求改动,在这里就不贴出来了,有兴趣的话可以下载来自己改着玩。

下载地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值