You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 13:24:03