美文网首页ITBOXAndroidAndroid_UI
简单实现夜间模式渐变

简单实现夜间模式渐变

作者: 风丰封峰 | 来源:发表于2016-09-13 13:31 被阅读2942次

    博文出处: Day Night Mode,我的博客

    话不多说,先上效果图!

    Twitter 实现夜间模式 我的实现我的实现 我的实现3我的实现3

    准备好你的铲铲

    • Android Support Library v7 24.2.0
        <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
    
    • 新建values-night文件夹,新建colors.xml,夜间模式要设置的颜色放在这里就好了!
    //File : values/colors.xml
    <resources>
        <color name="colorPrimary">@color/md_white_1000</color>
        <color name="colorPrimaryDark">@color/md_grey_600</color>
        <color name="colorAccent">@color/md_blue_500</color>
    </resources>
    
    //File : values-night/colors.xml
    <resources>
        <color name="colorPrimary">#ff243447</color>
        <color name="colorPrimaryDark">#ff1b2836</color>
        <color name="colorAccent">@color/md_blue_500</color>
    </resources>
    
    • Svg 的 fillcolor 取用你的color.xml 就好了!方便!如果不是svg,就要另外准备夜间模式的图片在drawable-night 文件夹里
    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportHeight="16.0"
        android:viewportWidth="16.0">
        <path
            android:fillColor="@color/colorPrimary"
            android:pathData="etc"
            android:strokeColor="#00000000"
            android:strokeWidth="1" />
    </vector>
    

    Show Me the code

    //Does not work in Android Nugget
    public void setDayNightMode(boolean day) {
            if (day)
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
            else
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
            getWindow().setWindowAnimations(R.style.WindowAnimationFadeInOut);
            recreate();
        }
    
    //Style
        <style name="WindowAnimationFadeInOut">
            <item name="@android:windowEnterAnimation">@anim/fade_in</item>
            <item name="@android:windowExitAnimation">@anim/fade_out</item>
        </style>
        
    //@anim/fade_in
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <alpha
            android:duration="1000"
            android:fromAlpha="0"
            android:interpolator="@android:anim/decelerate_interpolator"
            android:toAlpha="1.0" />
    </set>
    
    //@anim/fade_out
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <alpha
            android:duration="1500"
            android:fromAlpha="1.0"
            android:interpolator="@android:anim/decelerate_interpolator"
            android:toAlpha="0" />
    </set>
    

    一点解释

    1. windowAnimation 在这里的作用是模拟 startActivity 的 OverridingPendingTransition, 搭配 recreate 就不会出现闪现黑屏的情况了。
    2. 在style 文件里为windowAnimation 创建一个新的style,设定渐入动画和渐出动画。
    3. AppCompatDelegate.setDefaultNightMode 是support 包里的方法,我们只要简单设置他的mode 搭配recreate就可以变换夜间模式。
    MODE_NIGHT_NO - 日间模式
    MODE_NIGHT_YES - 夜间模式
    MODE_NIGHT_AUTO - 根据当前时间自动切换 亮色(light)/暗色(dark)主题
    MODE_NIGHT_FOLLOW_SYSTEM(默认选项). 设置为跟随系统,通常为 MODE_NIGHT_NO;貌似有些手机设定可以开启夜间模式
    

    备注

    • 这个渐变效果不支持API 24 Nougat
    • API 24 recreate 不会闪现黑屏

    我把这个效果实现在我的项目里了,有兴趣的童鞋可以来看一看星一星!谢谢!

    https://github.com/chkfung/MeizhiGank

    Reference

    1. https://kingideayou.github.io/2016/03/07/appcompat_23.2_day_night/

    相关文章

      网友评论

      • 碧雨:有一点想不明白,为什么Activity.recreate后,界面布局居然不会变,即滚动RecyclerView几行后recreate数据显示位置不变。理论上Activity实例重新生成后,RecyclerView应该从第一行开始显示,但貌似自带记忆功能,求解惑。
        碧雨:@风丰封峰 早期的Android版本不能这样,试了EditText可以,CheckBox和RadioBox不行。
        风丰封峰:@碧雨 Android 系统默认实现控件的状态缓存,以此减少开发者需要实现的缓存逻辑
      • starryZzz:切换模式过程中数据的保存lz是如何解决的
        风丰封峰:@5292d2ee97f8 备注写了呀
        5292d2ee97f8:5.1 6.0都可用 7.0上貌似没有渐变效果
        风丰封峰:@starryZzz onsavedinstance 保存 onrestoreinstance 恢复
      • yuger:简单有效,要的就是这个效果,渐变过程可以稍微缩短一点。第一张图与代码不符吧?含有你这种DrawerLayout的Theme不是这样子的。
        风丰封峰:我更新了一下,看看是不是你要的效果
        ```
        <Drawerlayout
        android:fitsSystemWindows="true">
        <CoordinatorLayout/>
        <NavigationView
        android:fitsSystemWindows="true"/>
        </DrawerLayout>

        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
        ```
        yuger:@风丰封峰 我在做第一张图的效果,就是有抽屉,同时有夜间模式. 如果将抽屉延伸至状态栏下层,需要设置Theme <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:windowTranslucentStatus">true</item> , 也就是把状态栏透明,你上面的Theme并没有这样 ; 而要实现夜间模式, 状态栏如果透明就不好看了,可见图一日间模式的状态栏,是透明的,而正常应该是colorPrimaryDark的,也就是说,在状态栏颜色上,这两者似乎有矛盾,不可两全,我在这篇文章底下也有评论,不知道你有没有解决方案? http://www.jianshu.com/p/b38d4bd54371
        风丰封峰:@yuger 加了新gif,代码一样。第一张是推特的实现,drawerlayout的theme并没有什么不同的。

      本文标题:简单实现夜间模式渐变

      本文链接:https://www.haomeiwen.com/subject/teumettx.html