Android实现切换主题功能

现在市面上有很多app都有更换主题皮肤的功能,那么到底是怎么实现的呢?
首先我们先上一张简单效果图
在这里插入图片描述

特别简单的实现,我们通过点击按钮切换主题

1.实现原理

实现起来特别简单,这里我们准备多个主题资源(自己适配),然后通过代码控制切换主题

项目结构
在这里插入图片描述

2.配置styles.xml 和manifest清单

styles.xml

<resources>

    <!--正常主题-->
    <style name="LightTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/white</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/white</item>
        <item name="myBgColor">@color/white</item>
        <item name="background">@color/white</item>
        <item name="myTextColor">@color/white</item>
        <item name="myButtonColor">@color/black</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
    <!--黑暗主题-->
    <style name="NightTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <item name="colorPrimary">@color/black</item>
        <item name="colorPrimaryDark">@color/red</item>
        <item name="colorAccent">@color/black</item>
        <item name="myBgColor">@color/black</item>
        <item name="background">@color/black</item>
        <item name="myTextColor">@color/black</item>
        <item name="myButtonColor">@color/white</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>


</resources>

AndroidManifest.xml

  <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/LightTheme">//设置自定义主题
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

attr.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="myBgColor" format="color" />
    <attr name="myButtonColor" format="color" />
    <attr name="myTextColor" format="color" />
</resources>

接下来我们在activity_main.xml设置

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?attr/myBgColor"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_setTheme"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/shape_btn"
        android:text="切换主题"
        android:textColor="?attr/myTextColor"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

3.通过代码控制主题

我们利用 setTheme(id);的方法动态的设置主题(不过需要注意这个方法需要放到setContentView(R.layout.activity_main); 之前)
然后调用recreate();方法重启资源

我们要实现点击按钮就实现连续更换主题,我们需要记录下来更换状态,这里利用了SharedPreferences来存储更换状态。

实现代码:

public class MainActivity extends AppCompatActivity {
    private Button mBtn;
    private Boolean mUseMyTheme;

    @SuppressLint("ObsoleteSdkInt")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
            Window window = getWindow();
            window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
        super.onCreate(savedInstanceState);
        final SharedPreferences sharedPreferences = getSharedPreferences("useMyTheme", MODE_PRIVATE);//获取主题更换状态
        mUseMyTheme = sharedPreferences.getBoolean("useMyTheme", true);//第一次默认设置为亮色主题
        if (!mUseMyTheme) {
            setTheme(R.style.NightTheme);//黑色主题
        } else {
            setTheme(R.style.LightTheme);//亮色主题
        }
        setContentView(R.layout.activity_main);
        mBtn = findViewById(R.id.btn_setTheme);
        mBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mUseMyTheme = !mUseMyTheme;//切换主题状态
                recreate();//重启资源
                SharedPreferences.Editor editor = sharedPreferences.edit();
                editor.putBoolean("useMyTheme", mUseMyTheme);//存储主题更换状态
                editor.commit();

            }
        });
    }
}

到这里简单的实现了主题切换的功能,那大部分app的主题皮肤大多数都是要下载的,不可能把这些五花八门的样式全都都放在apk文件上,那样的话应用会很大。所以皮肤是通过网络下载的(当然可以有几套默认的皮肤)在放入资源文件夹下,实现方法也是这样。

4.附上项目源码

项目源码

转载:https://blog.csdn.net/qq_35416214/article/details/105037199

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值