Android暗黑模式适配

这篇具有很好参考价值的文章主要介绍了Android暗黑模式适配。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

最近这两年,用户关于支持暗黑模式的呼声越来越高。而友商也基本都上了暗黑模式,于是老板也要求我们年前得上,可是工作量太大了,200多个页面,一个人整,实在是没法年前发,就拖到了年后上。

成果

1.网页和文章兼容安卓10及其以上,由网页前端处理;
2.原生页面设置浅色和深色都有效。但是跟随系统的话,由于安卓系统10以下没有设置暗黑模式的入口,所以设置跟随系统后一直是浅色。
3.由于App由原生 View 和 Compose View 实现的,所以两套 UI 都得实现暗黑模式;
4.在处理 UI 基础 library 和业务 library 实现了暗黑模式的同时,需要处理没有暗黑模式要求的 App ,直接设置为浅色模式即可

遇到的问题:

  1. 无法兼容 android 10 以下的系统
  2. 修改暗黑模式后,部分颜色没有更新
  3. 修改暗黑模式后,跟随系统部分手机不生效
  4. 系统暗黑模式修改后,无论当前处理什么模式,所有 Activity 都会 recreate

问题1:无法兼容 android 10 以下的系统

1.1 第三方库 Android-skin-support
开始之前也在网上查过相关的实现,类似功能就是换肤。
但是,我们做的是暗黑模式,包括:浅色,深色,跟随系统。
其中浅色和深色比较好实现,但是跟随系统的话,换肤功能就不方便实现了。用的最多的就是 Android-skin-support 这个库,实现起来也不容易,当然自己实现也挺麻烦。
未处理的 issue 接近三位数了,最后一次维护是3年前,慎用。
插件换肤,我们除了需要在国内各大应用市场上架外,还需要在 google play 上架,皮肤颜色相关的资源打包成一个 .apk 文件放在住工程内就不符合 google play 的上架规范。
1.2 我们的用户手机系统低于 android 10 的用户占比不多,小公司也那么多人手去做这种投入产出比较低的事情
1.3 我们的 App 有传统 View 和 Compose View 的实现,接入可能产生其他问题

问题2:修改暗黑模式后,部分颜色没有更新

2.1 所有 View 相关的页面,包括 View 和 Compose View 混合的页面的 Activity 必须继承自 AppCompatActivity。单纯的 Compose 页面没有这个要求。
2.2 除非特殊页面,比如分享页外,所有地方的颜色都不能直接硬编码。所有颜色均使用 xml 中定义的两套颜色,或使用 Compose 调色板中指定的主题颜色。
2.3 View 设置颜色不能直接使用 application 的 Context 作为上下文去获取颜色,需使用 Activity 的 Context 去获取上下问。

问题3: 修改暗黑模式后,跟随系统部分手机不生效

这个手查了很久才解决的问题,起初发现是在 debug 版本和 beta 版本之间的差异问题,在 debug 版本中不存在这个问题。最后发现是由于 debug 版本中关闭了多语言的功能,为了提升编译速度,禁止了多语言相关的实现。
最后发现是在对多语言处理的时候,导致了 Configuration 中的 uiMode 出现了问题。然后解决办法也就很清晰了:

override fun attachBaseContext(context: Context?) {
        super.attachBaseContext(InjectUtils.updateLocalConfig(context))
    }
    
override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        InjectUtils.onConfigChange(newConfig) // 再次矫正 UI_MODE
    }
// InjectUtils.kt
fun updateLocalConfig(context: Context?): Context? {
        return context?.let {
            val languageContext = setLocalLanguage(it)
            setLocalDarkMode(languageContext)
        }
    }
private fun setLocalDarkMode(context: Context?): Context? {
        val res = context?.resources
        val config = Configuration(res?.configuration)
        config.uiMode = DarkModeUtils.getCurrentUIMode(config.uiMode)
        return context?.createConfigurationContext(config)
    }
// DarkModeUtils.kt 根据当前模式还原正确的 UI_MODE 参数
fun getCurrentUIMode(uiMode: Int) = when (getCurrentMode()) {
        AppearanceMode.DAY -> Configuration.UI_MODE_NIGHT_NO
        AppearanceMode.NIGHT -> Configuration.UI_MODE_NIGHT_YES
        else -> Configuration.UI_MODE_NIGHT_UNDEFINED
    }.let {
        uiMode and Configuration.UI_MODE_NIGHT_MASK.inv() or it
    }

问题四:系统切换暗黑模式导致 AppCompatActivity 重启

暂时无法解决,看起来是系统处理的。
4.1 对于重要的页面,进行数据保存: onSaveInstanceState
4.2 说服老板

Compose 才是暗黑模式的最佳实现

其实 Compose 页面是最好实现暗黑模式的,切换暗黑模式也不会导致 Activity 重启,上面问题四说的是 View 页面的 AppCompatActivity 会重启。
而且 Compose 不仅仅能实现浅色和黑色两套主题,N 套都没问题,新增主题就可以了。
反关 View 实现的页面就不行了,因为只有 color.xml 和 color-night.xml 两套,或许还有其他方式,不过也不简单吧。
然后问题了下 iOS 的同事,说 iOS 切换暗黑模式页面也不会 recreate ,算了,还是 View 页面的设计不合理吧。文章来源地址https://www.toymoban.com/news/detail-771824.html

到了这里,关于Android暗黑模式适配的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android将Uri转为路径字符串(适配安卓全版本)并使用第三方应用打开文件(适配Android7.0+)

    做这个功能时在网上找了无数篇例子,有些方法是有问题的,故自己写一篇完整实现的总结,作备忘也作案例。顺便说一句,Android对存储权限的给予真的越来越严格 目录 1.Uri转为路径String以获得文件名  2.获取文件后缀名 3.通过后缀名获取文件MIME类型  4.设置Intent的Uri与权限

    2024年02月19日
    浏览(41)
  • Android文件选择器 路径选择 支持安卓4.4 ~ 13 支持Android/data目录访问 支持SD卡 适配Android11

    Android上进行文件选择或操作的第三方库,自动申请存储权限,支持 Android4.4 ~ 13,再也不用为了适配各种版本而苦恼了,快速集成,一句代码搞定,完善的文档,支持无root权限访问和操作Android/data和Android/obb目录(适配Android 13),支持SD卡,高度自定义UI满足你的所有需求,使用非常

    2024年02月04日
    浏览(40)
  • Android实现App内自动升级,适配了安卓7、8及以上版本

            应用发布后,要实现灰度升级控制,如果只依赖各家应用市场是不够的,还需要自己在应用中控制升级逻辑。并且每家应用市场上新审核也是一件很麻烦的事情,尤其像至简网格这样的应用,甚至没在应用市场上架,更不可能依赖它们了。所以必须要在应用中实现自

    2024年02月10日
    浏览(66)
  • Android 操作系统日历完成提醒功能 附带开关闹钟 适配高版本安卓

    如果想要一个稳定且不用担心生命周期的提醒方式,可以试试利用系统日历去完成任务的提醒或某个活动的预约。 项目仓库地址在文末 环境 Java 11 Android sdk 30 Gredle 7.1 测试机型 mi 8(安卓 9) mi10 pro(安卓11) huawei m8(安卓7) 日历操作表 ​ 其实完成这个功能本质是对安卓原

    2024年02月03日
    浏览(43)
  • Android-目前最稳定和高效的UI适配方案

    为了更形象的展示,假设我们在布局文件中把一个ImageView的宽度设置为360dp,那么在下面两张图中表现是不一样的: 图一是1080P,480dpi的手机,图二是1080P,420dpi的手机 从上面的布局中可以看到,同样是1080P的手机,差异是比较明显的。在这种情况下,我们的UI可能需要做一些微调

    2024年03月18日
    浏览(44)
  • Android-目前最稳定和高效的UI适配方案(1)

    然后我们就可以直接在布局文件里面使用具体的像素值了,比如,设计稿上是96*96,那么我们可以直接写96px,APP运行时,框架会帮助我们根据不同手机的具体尺寸按比例伸缩。 这可以说是一个极好的方案,因为它在宽高限定符适配的基础上更进一步,并且解决了容错机制的问

    2024年03月18日
    浏览(41)
  • Android 白天黑夜模式切换适配及引起的Activity销毁重启解决

    目录 一、白夜模式切换,Activity销毁重启解决: 二、 暗黑模式适配  1. 添加依赖:   2. 复制下面工具类方法直接使用即可: 3.资源适配:  4. 适配回调: 5.切换白夜模式注意事项:         当白夜模式切换时,activity会销毁重新加载,谷歌是希望重新加载Activity可以刷新页面UI,但我的

    2023年04月20日
    浏览(31)
  • Android技术栈(二)组件化改造,目前最稳定和高效的UI适配方案

    .build(PR.navi.navi) .navigation(); 而 Activity 则不需要,它会立即显示 ARouter.getInstance() .build(PR.navi.navi) //还可以设置参数,ARouter会帮你存在Bundle中 .withString(“pathId”,UUID.randomUUID().toString()) //Activity 或 Context .navigation(this); navi 模块是典型的业务逻辑模块,这里你可导入一些只有这个模块才

    2024年03月24日
    浏览(44)
  • 一线互联网架构师360°全方面性能调优,android适配器ui

    为什么要使用多进程 对于进程的概念,来到这里的都是编程修仙之人,就不再啰嗦了,相信大家倒着、跳着、躺着、各种姿势都能背出来。 相信很多同学在实际开发中,基本都不会去给app划分进程,而且,在Android中使用多进程,还可能需要编写额外的进程通讯代码,还可能

    2024年04月13日
    浏览(41)
  • GitHub标星7-5K!Android-超级稳定且高效的UI适配方案【建议收藏】(1)

    图一是1080P,480dpi的手机,图二是1080P,420dpi的手机 从上面的布局中可以看到,同样是1080P的手机,差异是比较明显的。在这种情况下,我们的UI可能需要做一些微调甚至单独适配。 第二个问题,这种方式无法快速高效的把设计师的设计稿实现到布局代码中,通过dp直接适配,我

    2024年04月10日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包