

Android Dark Theme/深色模式使用体验
source link: https://aprildown.xyz/2020/05/07/android-dark-theme/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Android Dark Theme/深色模式使用体验
2020-05-07Android
虽说一行代码AppCompatDelegate.setDefaultNightMode
就能搞定的问题,但实际上坑不少哩。
之前Google自己在文档中和API中混用Night Theme/Dark Theme,后来才统一用Dark Theme,毕竟不一定非得晚上才可以用这个模式嘛。同样的,在Dark Theme的中文文档里,将其翻译为深色/浅色主题,个人觉得比之前大伙儿用的夜间模式、黑色模式、黑夜模式、暗夜模式、暗黑模式等好听不少。
AppCompat 1.1.0给我们带来了深色模式,也带来了不少问题。像是因为从rc到正式版时只改了一行关于深色模式的代码,导致棒棒糖的WebView全线崩溃的问题。
setDefaultNightMode
在1.1.0中会自动重启所有Activity,这导致不少应用的深色主题的逻辑被打乱不说,这个实现也很难自定义。当然,你别动它,自然什么毛病没有。
setDefaultNightMode
会调用ActivityCompat.recreate()
)。
这个方法没有任何动画不说,而且在某些设备上会黑屏闪一下。在之前setDefaultNightMode
不会自动重启的日子里,我的办法是:
1
2
3
4
5
fun Activity.restartWithFading() {
startActivity(intent)
finish()
overridePendingTransition(R.anim.fade_in_short, R.anim.fade_out_short)
}
但现在不行了。那么如何拦截recreate()
呢?
我的第一次尝试是根据文档中对onConfigurationChanged()
进行拦截,在拦截后手动重启Activity。
这么做用了没问题,但如果我从一个没有拦截onConfigurationChanged()
的Activity中切换深色主题(比如通过省电模式),那这时会切换失效。
这是因为文档中有一句话:
An app can handle the implementation of Dark theme itself by declaring that each Activity can handle the uiMode configuration change:
我们需要对每个Activity都进行拦截。但这时如果我用了第三方的Activity(像CustomTabs),这依然会失效。至此我只能另寻他路。
我的第二次尝试是重写recreate()
:
1
2
3
4
5
6
7
8
override fun recreate() {
if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
// 不在前台时执行此处会导致Activity成为栈顶。
restartWithFading()
} else {
super.recreate()
}
}
使用后皆大欢喜,但当我在另一台机器上测试时,发现失效了。原因是:
1
2
3
4
5
6
7
8
9
10
11
public static void recreate(@NonNull Activity activity) {
// On Android P and later we can safely rely on the platform recreate()
if (Build.VERSION.SDK_INT >= 28) {
activity.recreate();
} else {
if (!ActivityRecreator.recreate(activity)) {
// If ActivityRecreator did not start a recreation, we'll just invoke the platform
activity.recreate();
}
}
}
ActivityCompat.recreate
在派之后才会调用recreate
,而在之前只是可能调用,比如我在27的设备上没调用,但在21的模拟器上调用了。
至此我没办法了,只能委屈部分老用户闪一下了。╮(╯▽╰)╭
我都不知道我不知道的坑
我的一个应用里有一个指定时间段内自动打开/关闭深色主题的功能。具体如下,
一个Switch显示是否使用了深色主题:
1
2
3
4
switchDark.isChecked = resources.isDarkTheme
val Resources.isDarkTheme: Boolean
get() = configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
切换Switch时切换深色模式:
1
2
3
4
5
6
7
8
9
10
11
12
13
switchDark.setOnCheckedChangeListener { _, isChecked ->
toggleDark(toDark = isChecked)
}
private fun toggleDark(toDark: Boolean) {
AppCompatDelegate.setDefaultNightMode(
if (toDark) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_NO
}
)
}
此外,在onCreate中根据需要自动切换深色模式:
1
2
3
if (shouldToggleAutoDark) {
toggleDark(toDark = !resources.isDarkTheme)
}
有啥问题,有啥问题呀?
如果使用之前在recreate
中重启应用的方法,那么在派及之后的设备上没有任何问题。否则,在所有设备上 + 使用之前在recreate
中重启应用的方法且在派之前的设备上,都会出现自动切换失效的问题。
比如现在是浅色主题,Switch为关,在启动时触发自动深色主题,setDefaultNightMode
呼叫recreate()
,应用重启,Switch为开,但这时Switch会经历一次onSaveInstanceState
,将它的状态设置为之前的关,同时触发OnCheckedChangeListener
,把应用设置为浅色模式,然后我们回到了原点。╮(╯▽╰)╭
最后我把Switch在切换前把所有可能调用onSaveInstanceState
的地方(toggleDark
和recreate
中)删掉View后,修好了。
也可以在那些地方清空掉Listener,再把isChecked设为新的值。
Recommend
-
55
macOS Mojave 发布以来,深色模式(Dark Mode)便成了天下大势。一众软件,无论知名与否,纷纷新增了深色模式的主题界面以与之相适配。一时间是否支持深色模式成为了评价一个 macOS 软件合格与否的一把重要标尺。LaunchBar 自然不能逆流而...
-
33
距离WWDC还有不到一周的时间,苹果将在本届WWDC上发布包括iOS13在内的新一代系统。今天,国外9to5mac网站获得了iOS13截图,通过截图可以确认iOS13一些功能。
-
44
千呼万唤始出来,苹果终于在今天凌晨的 WWDC 大会上公布了全球 10 亿用户都能用上「深色模式」的新系统——iOS 13。 虽然在大体设计上,iOS 13 对比 iOS 12 没有太大的变化,但在系统功能和应用层上,苹果依然还是「以用户为本」地...
-
45
今天的 WWDC 19 上发布了 iOS 13,我们来看下如何适配 DarkMode。 首先我们来看下效果图 效果图.gif Dark...
-
85
按照惯例,苹果于北京时间 6 月 4 日凌晨的 WWDC 上发布了各个平台的新一代操作系统。相比去年专注于性能和稳定性的 iOS 12,今年的 iOS 13 有了大幅改动,带来了众多系统新特性,以及原生应用也得到了大幅改进。 系统外观:姗...
-
40
新浪科技讯北京时间9月20日凌晨消息,今天凌晨苹果正式推送iOS13,iPhone的深色模式终于来了。iOS13推出的“深色”模式为iPhone带来了全然不同的新风格,提供了浏览和编辑照片的全新方式,并新增了保护隐私的登录方式。iOS13性
-
38
新酷产品第一时间免费试玩,还有众多优质达人分享独到生活经验,快来新浪众测,体验各领域最前沿、最有趣、最好玩的产品吧~!下载客户端还能获得专享福利哦! 视频加载中,请稍候... 新浪数码讯 10月21日上午消息,新版iOS以及...
-
34
新浪科技讯12月18日晚间消息,微信7.0.10内测版支持深色模式,安装完毕后,若系统已开启深色模式,微信将自动适配。不过据了解,微信对深色模式的支持并不全面,如游戏中心、搜一搜等暂未支持,且目前测试仅面向Android用户。
-
8
How to Implement Dark and Light Theme in Android App?How to Implement Dark and Light Theme in Android App?8 Views18/10/2021Having dark mode for androi...
-
3
Dark theme bookmark_border ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK