关于夜间模式的总结

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

 

关于夜间模式的总结

1.目前自己做的案例

  • 1. 那么有两种方式可以实现夜间模式
    • 1:修改theme,重启Activity
      • 优点:正儿八经的夜间模式,配色看着舒服
      • 缺点:图片刺眼、闪屏
    • 2:使用一个带黑色带透明度的View,盖在现有的activity上【遮罩层】
      • 优点:不用重启activity,不闪屏;加上透明度过渡动画,模式之间切换非常舒服,解决了1中,白底图片依旧刺眼的问题。;
      • 缺点:配色没变化,就算带上墨镜,白天依旧是白天。
  • 2.使用步骤
    • 1.首先,在values下要准备好三个文件,没有就自己创建

 

关于夜间模式的总结_第1张图片

 

      • 说明: attrs.xml(声明属性的类型,布局xml中用) reference可以使用系统的资源ID,比如R.color.gray; color可以直接使用#ffffff颜色代码





    

    

    

    

    

    

    

    

    

    

 

      • colors.xml(调色板,集中管理颜色hex)遵循 优秀格式规范 ,即调色板模式,避免使用btn1,btn2,fontTitle,fontText之类的颜色名。




        #fafafa

        #f3f3f3

        #cccccc

        #777

        #383838

        #8e9ea4

        #34515c

        #1e3e4a

        #90000000

      • styles.xml(日间、夜间主题)


        

        

        

        

        

        

    • 2.定义Activity父类和Application,自动托管日间、夜间模式
      • 说明:BaseApplication就是自己包装的Application,通过它,保存日间、夜间模式
      • Application和Activity一样是android框架的一个系统组件,当android程序启动时系统会创建一个application对象,用来存储系统的一些信息。
      • android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,所以Application可以说是单例 (singleton)模式的一个类.且application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局 的单例的,所以在不同的Activity,Service中获得的对象都是同一个对象。所以通过Application来进行一些,数据传递,数据共享等,数据缓存等操作。
      • 在自定义Application中
@Override

public void onCreate() {

    super.onCreate();

    ……

    //记录夜间模式状态。这个SP值很重要,不要随便清理SP中的值

    mSp = PreferenceManager.getDefaultSharedPreferences(this);

    mIsNightMode = mSp.getBoolean(PARAM_IS_NIGHT_MODE, false);

}


private boolean mIsNightMode;

private SharedPreferences mSp;

private static final String PARAM_IS_NIGHT_MODE = "PARAM_IS_NIGHT_MODE";

public boolean isNightMode() {

    return mIsNightMode;

}


public void setIsNightMode(boolean isNightMode) {

    if (mIsNightMode == isNightMode)

        return;

    mIsNightMode = isNightMode;

    mSp.edit().putBoolean(PARAM_IS_NIGHT_MODE, mIsNightMode).apply();

}
      • 在BaseActivity中
@Override

protected void onCreate(Bundle savedInstanceState) {

    mBaseApp = (BaseApplication) getApplication();

    if (mBaseApp.isNightMode()){

        setTheme(isSwipeToClose() ? R.style.AppTheme_night_transparent : R.style.AppTheme_night);

    } else{

        setTheme(isSwipeToClose() ? R.style.AppTheme_day_transparent : R.style.AppTheme_day);

    }

    super.onCreate(savedInstanceState);

    //夜间模式

    mIsAddedView = false;

    if (mBaseApp.isNightMode()) {

        initNightView();

        mNightView.setBackgroundResource(R.color.night_mask);

    }

}


@Override

protected void onDestroy() {

    if (mIsAddedView) {

        mBaseApp = null;

        mWindowManager.removeViewImmediate(mNightView);

        mWindowManager = null;

        mNightView = null;

    }

    super.onDestroy();

}


protected void initNightView() {

    if (mIsAddedView)

        return;

    WindowManager.LayoutParams mNightViewParam = new WindowManager.LayoutParams(

            WindowManager.LayoutParams.TYPE_APPLICATION,

            WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,

            PixelFormat.TRANSPARENT);


    mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);

    mNightView = new View(this);

    mWindowManager.addView(mNightView, mNightViewParam);

    mIsAddedView = true;

}


protected void ChangeToDay() {

    mBaseApp.setIsNightMode(false);

    mNightView.setBackgroundResource(android.R.color.transparent);

}


protected void ChangeToNight() {

    mBaseApp.setIsNightMode(true);

    initNightView();

}

调用方式

isNight = BaseApplication.getInstance().isNightMode();

if (isNight) {

    ChangeToDay();

} else {

    ChangeToNight();

}

recreate();

    • 3.如何在布局中引用资源

  • 3.关于WebView网页如何实现日间、夜间模式
    • 先了解js的切换夜间模式的点击事件接口

    • 在代码里写【关键代码】
ws = webView.getSettings();

ws.setJavaScriptEnabled(true);

webView.setWebViewClient(new MyWebViewClient());


private class MyWebViewClient extends WebViewClient {

    @Override

    public void onPageFinished(WebView view, String url) {

        view.getSettings().setJavaScriptEnabled(true);

        super.onPageFinished(view, url);

        if (isNight) {

            webView.loadUrl("javascript:toggleClassTest()");

        }

    }

}

 

2.简单优雅使用Android7.0实现夜间模式

  • 1.关于Android7.0夜间模式新特性
    • 事实上,日间模式与夜间模式就是给APP定义并应用两套不同颜色的主题。用户可以自动或者手动的开启。
    • Android 6.0 Marshmallow 预览版中曾经短暂出现过相关的夜间模式的功能,只是在正式版中被移除了,在Android 7.0 Nougat上,用户们再次经历了「得而复失」的遗憾,在开发者预览版中,夜间模式和暗色模式先是开启,然后有再次被移除。而在正式版中,夜间模式也没有出现。但其实相关的代码一直存在于系统中,只是默认没有被开启。
  • 2.实现步骤
    • 1.添加依赖库

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

compile 'com.android.support:design:25.1.1'

由于Support Library在23.2.0的版本中才添加了Theme.AppCompat.DayNight主题,所以依赖的版本必须是高于23.2.0的,并且,这个特性支持的最低SDK版本为14,所以,需要兼容Android 4.0的设备,是不能使用这个特性的,在API Level 14以下的设备会默认使用亮色主题。不过现在4.0以下的设备应该比较少了吧,毕竟微信的minSdkVersion都设置为14了。

    • 2.准备资源
      • 1.让我们自己的主题继承并应用DayNight主题。
      • 2.新建资源文件

 

新建夜间模式资源文件夹:在res目录下新建values-night文件夹,然后在此目录下新建colors.xml文件在夜间模式下的应用的资源。当然也可以根据需要新建drawable-night,layout-night等后缀为-night的夜间资源文件夹。

 

在value中的color文件





    #009688

    #00796B

    #009688

    #616161

    @android:color/white



在value-night的color文件





    #35464e

    #212a2f

    #212a2f

    #616161

    #212a2f

      • 3. 使Activity继承自AppCompatActivity
    • 3.在自定义Application中
public class App extends Application {

    @Override

    public void onCreate() {

        super.onCreate();

        // the 'theme' has two values, 0 and 1

        // 0 --> day theme, 1 --> night theme

        if (getSharedPreferences("user_settings",MODE_PRIVATE).getInt("theme", 0) == 0) {

            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);

        } else {

            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);

        }

    }

}

 

注意:

                 这里AppCompatDelegate.setDefaultNightMode()方法可以接受的参数值有4个:

        • MODE_NIGHT_NO. (一直应用日间(light)主题).
        • MODE_NIGHT_YES. (一直使用夜间(dark)主题).
        • MODE_NIGHT_AUTO. (根据当前时间在day/night主题间切换).
        • MODE_NIGHT_FOLLOW_SYSTEM(默认选项)(跟随系统,通常为MODE_NIGHT_NO).
    • 4.动态调用切换夜间模式
SharedPreferences sp =  getSharedPreferences("user_settings",MODE_PRIVATE);

if ((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES) {

    sp.edit().putInt("theme", 0).apply();

    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);

} else {

    sp.edit().putInt("theme", 1).apply();

    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);

}

//过渡动画效果,防止切换夜间模式闪屏
 

getWindow().setWindowAnimations(R.style.WindowAnimationFadeInOut);

recreate();

 

注意:

在调用recreate()方法之前,还可以创建一些动画进行过渡。

过渡动画



fade_in.xml动画文件



    

    • 5.设置自定义属性,比如文字,按钮,容器背景等颜色
android:textColor="@color/textColor"

这样就可以根据属性切换字体颜色

values中color     

#FF0000

night-values中color

#039BE5
    • 6.注意事项

在Android 6.0及以下的设备上,本项目运行时会有切换的过渡动画效果,但是不支持Android 7.0及以上的设备

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/zbj1618/blog/847954

你可能感兴趣的:(关于夜间模式的总结)