恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
D15_DataStore主题设置
首页
资讯中心
/
D15_DataStore主题设置
D15_DataStore主题设置
发布时间:2026/10/14 13:58:55
Android 学习笔记 D15用 DataStore 保存主题先分清默认值与已加载值发布摘要给 DevCommunity 增加跟随系统、浅色、深色三种主题重点解决设置持久化、启动闪烁和写入状态的问题。标签Android、DataStore、Compose、状态管理。收藏已经保存在 Room接下来添加主题设置很容易产生一个误解既然有数据库就把所有东西都放进去。真正应当先考虑的是数据如何使用。文章需要按时间排序、按编号查找主题只需要读取一个选择。本课用主题偏好练习小型设置的保存同时把“用户希望什么”和“界面当前显示什么”区分开。本文对应学习路线 D15《第一行代码》第 7 章的 SharedPreferences 帮助理解键值存储DataStore 和 Compose 是现代扩展不是书中的原有实现。下面是核心教学片段尚未在用户工程编译或运行接入前需要按工程版本配置依赖。一、先画出三个状态而不是直接写开关主题偏好有 SYSTEM、LIGHT、DARK 三种值。SYSTEM 不是第四种颜色而是“由系统当前配置决定”的规则。因此系统进入深色时只有跟随系统的用户应该同步改变。读取状态也至少有加载中、已读到偏好、读取失败三种。第一次安装时没有键使用 SYSTEM磁盘仍未读完时还不知道是否有键。这两种情况如果都提前显示成 SYSTEM保存了深色的用户可能先看到浅色内容再突然切换。本文选择在根界面等待首次偏好结果短暂显示中性启动背景如果读取失败显示可重试提示并允许临时跟随系统。临时显示不能自动覆盖磁盘中的旧值。业务默认值是产品规则读取失败是运行状态不能用同一个默认分支把二者抹平。DataStore 适合小型设置复杂查询和关联数据仍交给 Room同一文件在同一进程应使用一个 DataStore 实例。DataStore 官方说明二、把存储放到 Repository添加androidx.datastore:datastore-preferences版本与工程依赖目录统一管理。以下文件中的扩展属性只能定义一次。需要的导入完整列在片段中Repository 使用应用上下文避免保存 Activity。importandroid.content.Contextimportandroidx.datastore.preferences.core.editimportandroidx.datastore.preferences.core.stringPreferencesKeyimportandroidx.datastore.preferences.preferencesDataStoreimportkotlinx.coroutines.flow.Flowimportkotlinx.coroutines.flow.mapprivatevalContext.settingsStorebypreferencesDataStore(settings)enumclassThemeMode{SYSTEM,LIGHT,DARK}classSettingsRepository(context:Context){privatevalstorecontext.applicationContext.settingsStoreprivatevalthemeKeystringPreferencesKey(theme_mode)valtheme:FlowThemeModestore.data.map{values-when(values[themeKey]){LIGHT-ThemeMode.LIGHTDARK-ThemeMode.DARKelse-ThemeMode.SYSTEM}}suspendfunsetTheme(mode:ThemeMode){store.edit{values-values[themeKey]mode.name}}}读取中遇到未知字符串时回到 SYSTEM是为了让未来版本改动或旧数据不会直接引起枚举转换崩溃。这里没有吞掉 I/O 异常错误应交给上层转换为读取失败状态。写操作完成后才显示“已保存”失败时保留重试入口。依次完成四步第一步由应用容器创建一个 Repository第二步在设置 ViewModel 中收集theme把首次结果前的状态设为 Loading第三步按钮事件启动viewModelScope协程调用setTheme第四步根主题消费同一份偏好并把颜色传给整个导航内容。每个页面独立读取系统主题而忽略偏好会造成首页深色、详情浅色。三、快速点击到底保存哪个值DataStore 负责事务更新但不会替我们定义交互顺序。入门版可以在保存期间禁用选择按钮用户一次只提交一种偏好成功后再允许下一次修改行为更容易验证。若以后允许连续操作就需要明确以事件队列顺序为准或者建立只处理最新意图的状态机不要仅靠多个协程碰巧按点击顺序结束。也不要先读旧值到内存过一会儿再把“旧值修改后的整份设置”覆盖回去涉及读取并修改的操作应在更新事务内部表达。今天主题只有一个字段看不出覆盖问题加入字体大小后就容易把另一个开关改回旧值。根主题根据偏好计算深浅色收藏列表仍只观察 Room。两者的共同点是 UI 消费状态区别是数据结构和查询需求。这样设置页的写入逻辑不会渗透进文章卡片测试主题也不必构造整份收藏数据库。四、故障实验把“看起来没问题”变成证据先保存深色再结束进程并重新打开观察第一帧内容是否突然变亮。预期是等待偏好时使用既定启动背景加载完成后进入深色而不是先展示完整浅色首页。可使用屏幕录制辅助观察但文章发布时只能把实际记录过的现象写成实测。第二个实验在 Fake 设置仓库中延迟首次读取两秒。这能稳定放大启动问题不需要故意损坏真实偏好文件。预期加载中不能冒充“已经保存 SYSTEM”。第三个实验让一次保存返回 I/O 错误预期按钮恢复可用、提示失败、重启后仍是最后成功的值。最后在跟随系统模式切换设备主题然后分别进入首页和详情。预期所有页面同步再选固定浅色重复操作预期应用保持浅色。这里检验的是规则不只是按钮颜色。五、原创面试问答与追问可延伸到题库的SharedPreferences 主题和主题与样式主题。下面问答为自拟练习不是题库答案转载。问主题为什么不直接保存在 remember 中答它只解决组合中的内存记忆不能承担应用重启后的偏好持久化。追问换成 rememberSaveable 就够了吗仍不应把长期设置的唯一事实来源放在页面恢复状态里。问为什么保存函数不能放在 Composable 函数体里答重组可能再次执行函数体显示过程不应该反复产生写入。追问点击回调可以吗可以把用户事件传给状态持有者由后者管理保存进度和失败。问读不到键和读取失败有什么区别答前者是有效数据中的缺省情况后者意味着尚不能确定真实值。追问为什么失败时不能立刻写入默认值可能覆盖仍有恢复价值的用户配置。六、当天练习与验收按课程节奏先用二十分钟闭卷回忆存储边界四十分钟阅读相关接口一百五十分钟实现三种主题和首次加载状态三十分钟执行上述实验最后一小时练习解释设计。交付内容应包含主题状态草图、一次保存失败的录屏或日志、重启后的实际结果以及无参考实现的“字号偏好”小改动。验收标准是能追踪“点击—保存—观察—根主题更新”的完整路径并说明哪一步失败时 UI 会怎样变化。