Flutter如何使用shared_preferences实现字体大小本地持久化存储
问题排查与修复方案
现有代码的核心错误
getFontSize方法缺少返回值:你调用了sharedPreferences.getInt('fontsize')但没有return该结果,导致方法永远返回null,这是读取失败的核心原因- 默认值逻辑缺失:
addDefaultValueToSharedPreferences方法从未被调用,用户首次打开应用时没有存储过字号配置,读取自然返回null,且你写的默认值是1,和你的字号列表[10,11,12,13,14,15]完全不匹配 - 缺少全局状态同步逻辑:当前字号状态只存在于
MyApp2页面的state中,无法同步到应用其他页面,达不到全应用生效的需求
修复后的完整代码
import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; class MyApp2 extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp2> { int? _changeFontSize; final List<int> _fontSizeList = [10, 11,12,13,14,15]; // 定义和字号列表匹配的默认字号 static const int defaultFontSize = 14; @override void initState() { super.initState(); _initFontSize(); } // 合并初始化逻辑,避免嵌套回调 void _initFontSize() async { int? storedSize = await getFontSize(); setState(() { // 读取为空时直接使用默认值 _changeFontSize = storedSize ?? defaultFontSize; }); // 首次打开时写入默认值到存储 if (storedSize == null) { await updateFontSize(_changeFontSize!); } } Future<int?> getFontSize() async { final sharedPreferences = await SharedPreferences.getInstance(); // 补上返回值,修复读取为null的问题 return sharedPreferences.getInt('fontsize'); } Future<void> updateFontSize(int updatedSize) async { final sharedPreferences = await SharedPreferences.getInstance(); await sharedPreferences.setInt('fontsize', updatedSize); // 接入全局状态管理后,可在此处同步更新全局字号变量,实现全应用生效 } @override Widget build(BuildContext context) { return Center( child: Column( children: [ Card( margin: const EdgeInsets.only(bottom: 3), child: ListTile( title: const Text("字体大小"), trailing: DropdownButtonHideUnderline( child: DropdownButton( isExpanded: false, value: _changeFontSize, items: _fontSizeList.map((myFontSize) { return DropdownMenuItem( child: Text(myFontSize.toString()), value: myFontSize, ); }).toList(), onChanged: (value) async { if (value == null) return; setState(() { _changeFontSize = value as int; }); await updateFontSize(value); }, hint: const Text("选择字号"), ), ), ), ), ], ), ); } }
全应用生效实现建议
如果需要修改的字号在所有页面生效,推荐按以下逻辑实现:
- 引入
Provider或Riverpod等状态管理工具,在应用顶层存储全局字号变量 - 所有页面的Text样式都引用该全局字号变量
- 字号修改后同步更新全局状态,所有页面会自动重绘适配新字号
内容的提问来源于stack exchange,提问作者eno2
相关产品推荐
相关产品推荐

