DayNight Mode实现Android夜间模式

DayNight Mode实现Android夜间模式!

期末设计开发了一个小说阅读器,里面涉及到白天/夜间模式的切换,特拿出来试验,验证DayNight Mode标准

利用DayNight Mode标准实现Android白天/夜间模式切换,主要用到控制器UiModeManager。

UiModeManager主要用来进行模式切换。它是Android系统SDK本来就提供的模式切换系统。利用该控制器外加一套白天/夜间模式的资源(UiModeManager会根事件自动在两个模式之间切换),即可实现白天/夜间模式的切换。

资源细分

首先我们看一看一个界面需要控制哪些颜色:

在这里插入图片描述

而除了上述基本需要控制的窗口颜色外,布局中受影响的还会有一些文本和图像。一般的,白天/夜间模式涉及到的显示状态的切换最基本改变影响就是这些文本、icon图标、整体的背景颜色等。

首先我们在colors.xml中设置好这些颜色,代码如下:

白天模式:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--    文本颜色-->
    <color name="text">@android:color/black</color>
<!--    背景颜色-->
    <color name="background">@android:color/white</color>
<!--    窗口颜色-->
    <color name="colorPrimary">#FF9600</color>
    <color name="colorPrimaryDark">#FF9600</color>
    <color name="colorAccent">#FF4081</color>
</resources>

夜间模式:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--    文本颜色-->
    <color name="text">@android:color/white</color>
<!--    背景颜色-->
    <color name="background">@android:color/black</color>
<!--    窗口颜色-->
    <color name="colorPrimary">@android:color/black</color>
    <color name="colorPrimaryDark">@android:color/black</color>
</resources>

注意夜间模式的colors.xml文件必须创建在values-night文件夹下,否则控制器读不到!

然后修改styles.xml文件,让app调用我们设置的颜色:

<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>

</resources>

然后我们规定图标的变化,这里我们规定白天显示一个心性图标,夜间显示一个圆形图标。

首先我们要在drawable中添加心性图标,然后创建 drawable-night文件夹,并添加圆形图标进去。注意两个图标的名字一定相同,并且文件夹的名字也一定要是默认的drawable-night,否则控制器读不出来资源!

通过上述步骤,需要的两套资源都准备好了,现在就差上层java代码和布局xml文件了。

MainActivity代码

先上代码:

package com.example.daynightmode;
import androidx.appcompat.app.AppCompatActivity;
import android.app.UiModeManager;
import android.content.Context;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {
    
    
    //定义“白天/夜间模式”菜单项的标识
    private static final int BACKGROUND_DAY =0;
    private static final int BACKGROUND_NIGHT =1;

    //实现Android白天/夜间模式的关键类
    private UiModeManager mUiModeManager = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mUiModeManager = (UiModeManager) getSystemService(Context.UI_MODE_SERVICE);

    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu){
    
    
        menu.add(0,BACKGROUND_DAY,0,"白天模式");
        menu.add(0,BACKGROUND_NIGHT,0,"夜间模式");
        return super.onCreateOptionsMenu(menu);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem mi){
    
    
        switch (mi.getItemId()){
    
    
            //点击白天模式,切换到白天模式
            case BACKGROUND_DAY:
                mUiModeManager.setNightMode(UiModeManager.MODE_NIGHT_NO);break;
            //点击夜间模式,切换到夜间模式
            case BACKGROUND_NIGHT:
                mUiModeManager.setNightMode(UiModeManager.MODE_NIGHT_YES);break;
        }
        return true;
    }
}

上述代码首先创建了一个选择菜单,然后用户一旦点击相关的菜单,UiModeManager控制器的mUiModeManager对象则调用setNightMode方法。去更改相应的模式。(setNightMode是Android自己支持的方法,通过布尔型变量更改模式。为True时是调用夜间资源,为False时调用白天资源,从而实现模式转化。)

activity_main.xml代码

先上代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/background"
    android:orientation="vertical">
    <!--显示图片-->
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:src="@drawable/icon" />
    <!--显示文本-->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text=".@Design By AiYuan"
        android:textColor="@color/text"
        ></TextView>

</LinearLayout>

上述代码,显示了一个图标(调用drawable中的icon)和一个文本框(颜色调用values文件夹下colors中的text对应的颜色)。一旦发生夜间事件,控制器则直接调用配套同名的夜间资源替换,达到更改模式的效果。

项目结构截图:

在这里插入图片描述

运行效果:

白天模式:

在这里插入图片描述

夜间模式:

夜间事件,控制器则直接调用配套同名的夜间资源替换,达到更改模式的效果。
在这里插入图片描述

作者:王子豪
原文链接:https://blog.csdn.net/IYuanM/article/details/111906225

猜你喜欢

转载自blog.csdn.net/fjnu_se/article/details/112667704