用户反馈说每次重启App,明明设置了深色模式,打开又变回浅色。排查之后发现bug简单到让人脸红:我只更新了StateFlow。
ViewModel确实发出了新主题,Compose也重组了,界面看起来一切正常——直到进程被杀掉。下次冷启动时,MutableStateFlow带着硬编码的默认值初始化,之前持久化的偏好设置根本没被读取。
![]()
这是Compose深色模式最常见的坑。下面这套生产级方案能彻底避免。
别用Boolean,用Enum。Boolean只有开和关,用户需要第三个选项:跟随系统。把SYSTEM设为默认值(value=2),存储.value作为Int让SharedPreferences保持简洁。
持久化直接用SharedPreferences。别用PreferenceManager.getDefaultSharedPreferences()——它在AndroidX Preference库里已经废弃。也别急着上DataStore,它的异步读取需要启动页或加载状态来避免首帧闪烁。SharedPreferences的同步getInt()能在第一帧前完成,这正是主题偏好需要的。
ViewModel里要做两次写入,不是一次。先写SharedPreferences保证进程死亡后数据存活,再更新StateFlow驱动立即重组。很多教程到StateFlow就停了,少了持久化这一步,主题当然每次重启都重置。
AppCompatDelegate不该出现在ViewModel里,它属于Activity。Compose侧用when把ThemeMode解析成Boolean,再构建对应的ColorScheme。SYSTEM分支调用isSystemInDarkTheme()获取系统当前状态,这样就能在设置页看到实时切换效果,同时保证重启后读取用户明确的选择。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.