【android】夜间模式简单实现
完整代码,请参考我的博客园客户端,git地址:http://git.oschina.net/yso/CNBlogs
关于阅读类的app,有个夜间模式真是太重要了。
那么有两种方式可以实现夜间模式
1:修改theme,重启activity
优点:正儿八经的夜间模式,配色看着舒服
缺点:图片刺眼、闪屏
核心思路:自定义一个颜色属性名 A,A在日间和夜间模式下都有具体的颜色代码,页面布局文件只管引用A,至于是日间还是夜间,由后台主题决定。
2:使用一个带黑色带透明度的View,盖在现有的activity上,效果类似你带上墨镜,看着太阳不刺眼。
优点:不用重启activity,不闪屏;加上透明度过渡动画,模式之间切换非常舒服,解决了1中,白底图片依旧刺眼的问题。;
缺点:配色没变化,就算带上墨镜,白天依旧是白天。
核心思路:使用WindowManager,在当前activity上,通过addView,添加一个黑色带透明度的View。
本方案整合了两种解决方案。在夜间配色的基础上,再加上一层墨镜,让图片也变得柔和起来,效果图如下:
可以看待chrome图标的白色底,在夜间模式下也变得柔和了
好,下面来讲讲具体的实现步骤,本环节使用的开发环境是android Studio
1 首先,在values下要准备好三个文件,没有就自己创建
attrs.xml(声明属性的类型,布局xml中用) reference可以使用系统的资源ID,比如R.color.gray; color可以直接使用#ffffff颜色代码
<?xml version="1.0" encoding="utf-8"?> <resources><attr name="containerBackground" format="reference|color"></attr><attr name="cardBackground" format="reference|color"></attr><attr name="titleColor" format="reference|color"></attr><attr name="textColor" format="reference|color"></attr><attr name="selectorBtn" format="reference"></attr><attr name="selectorListItem" format="reference"></attr> </resources>
colors.xml(调色板,集中管理颜色hex)遵循优秀格式规范,即调色板模式,避免使用btn1,btn2,fontTitle,fontText之类的颜色名。
<?xml version="1.0" encoding="utf-8"?> <resources><color name="white">#fafafa</color><color name="white_dark">#f3f3f3</color><color name="gray_light">#cccccc</color><color name="gray">#777</color><color name="gray_dark">#383838</color><color name="green_light">#8e9ea4</color><color name="green">#34515c</color><color name="green_dark">#1e3e4a</color><color name="night_mask">#90000000</color> </resources>
styles.xml(日间、夜间主题)
<resources><!-- Application theme. --><style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"></style><!-- 日间模式 --><style name="AppTheme.day" parent="AppTheme"><item name="containerBackground">@color/white_dark</item><item name="titleColor">@color/gray_dark</item><item name="textColor">@color/gray</item><item name="selectorBtn">@drawable/navigator_list_item_day</item><item name="selectorListItem">@drawable/list_item_day</item></style><!-- 夜间模式 --><style name="AppTheme.night" parent="AppTheme"><item name="containerBackground">@color/green_dark</item><item name="titleColor">@color/white_dark</item><item name="textColor">@color/green_light</item><item name="selectorBtn">@drawable/navigator_list_item_night</item><item name="selectorListItem">@drawable/list_item_night</item></style> </resources>
2定义activity父类,自动托管日间、夜间模式
BaseApplication就是自己包装的Application,通过它,保存日间、夜间模式
Application和Activity,Service一样是android框架的一个系统组件,当android程序启动时系统会创建一个 application对象,用来存储系统的一些信息。通常我们是不需要指定一个Application的,这时系统会自动帮我们创建,如果需要创建自己 的Application,也很简单创建一个类继承 Application并在manifest的application标签中进行注册(只需要给Application标签增加个name属性把自己的 Application的名字定入即可)。
android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,所以Application可以说是单例 (singleton)模式的一个类.且application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局 的单例的,所以在不同的Activity,Service中获得的对象都是同一个对象。所以通过Application来进行一些,数据传递,数据共享 等,数据缓存等操作。
public class BaseActionBarActivity extends ActionBarActivity {private BaseApplication mBaseApp = null;private WindowManager mWindowManager = null;private View mNightView = null;private LayoutParams mNightViewParam; private boolean mIsAddedView; @Overrideprotected void onCreate(Bundle savedInstanceState) {mBaseApp = (BaseApplication) getApplication();if (mBaseApp.isNightMode())setTheme(R.style.AppTheme_night);elsesetTheme(R.style.AppTheme_day);super.onCreate(savedInstanceState);mIsAddedView = false; if (mBaseApp.isNightMode()) {initNightView();mNightView.setBackgroundResource(R.color.night_mask);}}@Overrideprotected void onDestroy() {if (mIsAddedView) {mBaseApp = null;mWindowManager.removeViewImmediate(mNightView);mWindowManager = null;mNightView = null;} super.onDestroy();}public void ChangeToDay() {mBaseApp.setIsNightMode(false);mNightView.setBackgroundResource(android.R.color.transparent);}public void ChangeToNight() {mBaseApp.setIsNightMode(true);initNightView();mNightView.setBackgroundResource(R.color.night_mask);}/*** wait a time until the onresume finish*/public void recreateOnResume() {new Handler().postDelayed(new Runnable() {public void run() {recreate();}}, 100);}private void initNightView() {if (mIsAddedView == true)return;mNightViewParam = new LayoutParams(LayoutParams.TYPE_APPLICATION,LayoutParams.FLAG_NOT_TOUCHABLE | LayoutParams.FLAG_NOT_FOCUSABLE,PixelFormat.TRANSPARENT);mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);mNightView = new View(this);mWindowManager.addView(mNightView, mNightViewParam);mIsAddedView = true;} }
值得一提的是recreateOnResume()函数,因为是从Resume里面重建activity的(避免闪屏)此时,直接调用系统的recreate函数时,会报错,原因是resume还没执行完,就被recreate了,因此,我们函数需要延时一会,等待系统完成resume就好了。一般延时1毫秒就可以了,但是我的app里面用到抽屉式导航栏,保存的时间要长点。
准备工作到这里已经结束了。只要activity集成自该父类,就会自动托管日间、夜间模式了
3调用方式
在布局文件里,引用颜色的地方,我们使用问号来访问定义在styles.xml里面主题的属性。换句话说,这种方式的神奇之处在于,我在夜间主题、白天主题都定义了titleColor,布局只管引用titleColor,至于是白天的还是晚上的,则由activity的setTheme指定。
?表示引用属性
“?”引用主题属性,当您使用这个标记,你所提供的资源名必须能够在主题属性中找到,因为资源工具认为这个资源属性是被期望得到的,您不需要明确的指出它的类型
<TextViewandroid:id="@+id/base_swipe_item_title"android:layout_width="0dp"android:layout_height="100dp"android:layout_weight="1"android:gravity="left|center_vertical"android:textColor="?titleColor"android:textSize="21sp" />
子类只要调用ChangeToDay、ChangeToNight就可以完成模式的切换了。别忘了recreate activity来生效哦,实例代码如下:
void changeViewMode() {boolean isNight = getMyApplication().isNightMode();if (isNight)ChangeToDay();elseChangeToNight();recreate();}
OK,如过你能坚持看到这里,说明阁下是有耐心的人,奉上一个彩蛋。
关于WebView网页如何实现日间、夜间模式。
这个问题比我们现象的要简单的多。因为网页么,在生成html内容时,只要根据日间、还是夜间模式,替换css路径为日间.css、夜间.css就好了。
栗子来了,瞧,就是这个"{style}",我们要替换的对象。
<html> <head><title>Cnblogs</title><link rel="stylesheet" type="text/css" href="{style}"/><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0, user-scalable=no"/> </head>
在对webview加载内容文本时,替换该字符串的css
replace("{style}",baseApplication.isNightMode() ? "style_night.css" : "style_day.css")
结构如下:
切换主题如何避免闪屏
我们知道,通过reCreate(),来重启activity的时候,会闪屏;
那么 在切换之前,先截屏作为activity盖在当前的activity上面,然后重启activity,完毕之后,把盖着的activity通过alpha动画消失,这样切换主题动作就会变的很柔和了
转载于:https://www.cnblogs.com/kimmy/p/4555197.html
【android】夜间模式简单实现相关推荐
- Android夜间模式实践
前言 由于项目需要,近段时间开发的夜间模式功能.主流的方案如下: 1.通过切换theme实现 2.通过resource id映射实现 3.通过Android Support Library的实现 方案 ...
- android自动夜间模式吗,Android夜间模式的实现方案
原标题:Android夜间模式的实现方案 作者简介 本篇来自 Sunlight1024的投稿,详细地讲解了关于Android应用的夜间模式的实现,希望大家喜欢! Sunlight1024的博客地址: ...
- Android夜间模式最佳实践
转自:Android夜间模式最佳实践 由于Android的设置中并没有夜间模式的选项,对于喜欢睡前玩手机的用户,只能简单的调节手机屏幕亮度来改善体验.目前越来越多的应用开始把夜间模式加到自家应用中,没 ...
- android os夜间,Android夜间模式实现
查看我的全部开源项目[开源实验室] 欢迎加入我的QQ群:[201055521],本博客客户端下载[请点击] 本文原创,转载请注明地址:http://blog.kymjs.com/ 最近在做一个Andr ...
- android自动夜间模式,夜晚的故事(android夜间模式实现)
夜幕降临,他走在马路上,回想着今天发生的一切,他不敢相信事情就这样发生了.他最终还是决定拨打那个电话,掏出手机,解锁屏幕,突然一道强光从屏幕里毫无预兆的发射出来.他一个踉跄倒在了马路中央.而他身后伴随 ...
- android 夜间模式 框架,Android 夜间模式的三种实现
实现夜间模式有很多种方式,经过多次尝试,算是找到了一种性价比较高的方式. 主题方式 这是最正统的方式,但工作量巨大,因为要全局替换 xml 布局中所有硬编码的色值,将其换成主题色.然后通过换主题达到换 ...
- android 夜间模式设置
夜晚的故事(android夜间模式实现) 字数2003 阅读1393 评论11 喜欢18 夜幕降临,他走在马路上,回想着今天发生的一切,他不敢相信事情就这样发生了.他最终还是决定拨打那个电话,掏 ...
- android 夜间模式代码,Android 超简单的夜间模式如何实现?
原标题:Android 超简单的夜间模式如何实现? 本文作者 作者: 唐子玄 实现夜间模式有很多种方式,经过多次尝试,算是找到了一种性价比较高的方式. 1 主题方式 这是最正统的方式,但工作量巨大,因 ...
- Android夜间模式的简单实现
前言 Android 6.0以后系统提供了AppCompatDelegate用来实现夜间模式和日间模式的切换,AppCompatDelegate中存在以下几种模式: AppCompatDelegate ...
最新文章
- opencv打开摄像头采集和保存
- php开启与关闭错误提示
- 实时视频传输中的BBR拥塞控制
- SQLServe错误整理
- 查看某个端口的进程 lsof -i:端口号
- Dijkstra 计算两地间的最短距离
- Kali Linux Web 渗透测试秘籍 第六章 利用 -- 低悬的果实
- POJ 1694 An Old Stone Game ★(排序+树+递归)
- iOS VideoToolBox decoder解码失败(-12909和-12911)问题解决
- 用JAVA写一个视频播放器
- Ubuntu安装wine和Wine QQ
- html点击图片局部放大,鼠标单击实现放大镜图片局部放大效果
- matlab src,SRC 这是一个利用了稀疏表示方法的MATLAB程序,供大家参考学习。 Special Effects 图形图像处理 256万源代码下载- www.pudn.com...
- prometheus Metric类型
- 苹果4s怎么越狱教程_ios9.2怎么越狱 iOS9.2.1完美越狱教程【详解】
- 二叉查找树,二叉平衡树
- java中堆和堆栈的区别
- 如何用Git将代码上传到GitHub
- C++ 强制类型转换操作符(static_cast、dynamic_cast、const_cast和reinterpret_cast)
- 【控制】自适应控制,模型参考自适应控制,公式推导,有程序有结果图