Android使用系统自动SDK V7库实现切换主题

Android使用系统自动SDK V7库实现切换主题

概述:google在v7:23.2.0之后引进了新方法那就是日夜间模式的主题切换,据说有很多坑,反正项目也没有具体用到这里写了个简单的demo加上了一个前辈填的坑,经验有限仅供参考^-^

1.添加依赖库

 compile 'com.android.support:appcompat-v7:23.4.0'

只要是是在23.2.0以后的版本就可以

2.接着再上一张动图

3.分析

1首先创建一个ScrollingActivity,如果你要问为什么,自己去琢磨^-^haha:activity_scrolling.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true"
    tools:context="tangren.szxb.com.theme.ScrollingActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/app_bar_height"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@mipmap/icon_icon"
                android:fitsSystemWindows="true" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_view" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email"
        app:layout_anchor="@id/app_bar"
        app:layout_anchorGravity="bottom|end" />

</android.support.design.widget.CoordinatorLayout>

content_view.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView 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:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="tangren.szxb.com.theme.ScrollingActivity"
    tools:showIn="@layout/activity_scrolling">

</android.support.v7.widget.RecyclerView>

这样我们就把整体布局给写好了,其实这基本上都是自己生成的,这就是为什么要新建ScrollingActivity了

2其实切换主题这里就是切换style了,所以咱们要准备两套style、color等等
1 values\styles.xml:未做修改,当做白天模式的style
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

</resources>

values\colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="colorText">#000000</color>
</resources>
2 新建values-night文件夹在res下,然后在values-night下新建style、color等配置xml,我这里style风格不变只是color有所改变
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#383838</color>
    <color name="colorPrimaryDark">#333333</color>
    <color name="colorAccent">#FF4081</color>
    <color name="colorText">#A604bA</color>
</resources>

接下来就是代码部分了,首先官方给给咱们提供了四种状态:

public static final int MODE_NIGHT_NO = 1;

public static final int MODE_NIGHT_YES = 2;

public static final int MODE_NIGHT_AUTO = 0;

public static final int MODE_NIGHT_FOLLOW_SYSTEM = -1;

分别是不使用夜间模式,使用夜间模式,根据地理位置推算白天夜晚自动进入夜间或白天模式,根据Android系统设置的模式
当然你可以设置一个默认模式

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO);

或者自己切换

白天模式

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);      activity.getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);

夜间

模式

 AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);     activity.getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);

如果你有横竖屏的需求可能就会出现一点bug那就是横竖屏切换后可能会出现夜间模式跟白天模式混乱的情况,现有的解决办法是更新UI模式,但是你一定要找准时机不能随处更新,有人说google已经在23.4已经修复了此bug,暂未知……


    public static void refershResource(AppCompatActivity activity) {
        isNight = SpUtils.getBoolean(THEME_KEY, false);
        if (isNight)
            updateConfig(activity, Configuration.UI_MODE_NIGHT_YES);
        else
            updateConfig(activity, Configuration.UI_MODE_NIGHT_NO);
    }
 private static void updateConfig(AppCompatActivity activity, int uiNightModel) {
        Configuration configuration = new Configuration(activity.getResources().getConfiguration());
        configuration.uiMode &= ~Configuration.UI_MODE_NIGHT_MASK;
        configuration.uiMode |= uiNightModel;
        activity.getResources().updateConfiguration(configuration, null);
    }

这里我贴一下application的代码吧,其实这里做一下初始化的东西,重点也都是这里的东西,下面我会留源码地址的

package tangren.szxb.com.theme;

import android.app.Application;
import android.content.res.Configuration;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDelegate;

/**
 * Created by Administrator on 2016/10/19 0019.
 */
public class MyApplication extends Application {

    private static MyApplication application;

    private static boolean isNight;

    private static String THEME_KEY = "mode";

    public static MyApplication getIntence() {
        if (application == null) {
            application = new MyApplication();
        }
        return application;
    }


    @Override
    public void onCreate() {
        super.onCreate();
        this.application=this;
        init();

    }

    private void init() {
        isNight = SpUtils.getBoolean(THEME_KEY, false);
        if (isNight)//夜间模式
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
        else//默认为白天模式
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
    }

    public static void setThemeModel(AppCompatActivity activity, boolean model) {
        if (isNight == model)
            return;
        if (!model)//白天模式
        {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
            activity.getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        } else {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
            activity.getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
        }
        isNight = model;
        SpUtils.putBoolean(THEME_KEY, isNight);
        activity.recreate();

    }

    public static void refershResource(AppCompatActivity activity) {
        isNight = SpUtils.getBoolean(THEME_KEY, false);
        if (isNight)
            updateConfig(activity, Configuration.UI_MODE_NIGHT_YES);
        else
            updateConfig(activity, Configuration.UI_MODE_NIGHT_NO);
    }


    private static void updateConfig(AppCompatActivity activity, int uiNightModel) {
        Configuration configuration = new Configuration(activity.getResources().getConfiguration());
        configuration.uiMode &= ~Configuration.UI_MODE_NIGHT_MASK;
        configuration.uiMode |= uiNightModel;
        activity.getResources().updateConfiguration(configuration, null);
    }


}

源码地址:https://github.com/wuxinxi/SwitchingTheme

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吴唐人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值