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

Flutter中Widget无法加载更新shared_preferences存储数据的问题

问题核心原因
  • TextFormField的initialValue属性仅在组件首次挂载初始化时生效一次,后续哪怕父组件调用setState更新了max变量,已经完成初始化的输入框不会重新读取initialValue做更新,这就是数据读取成功、setState也触发了但界面不显示存储值的核心原因。
  • _loadMax()方法直接写在build方法中存在逻辑风险:build方法会在每次组件重建时触发,虽然加了max == null的判断,但异步调用时序不可控,极端场景下会重复触发初始化逻辑。
  • 首次进入页面无存储值时,调用_setMax(16)的分支没有同步处理当前页面的状态更新,会导致默认值加载异常。
  • SharedPreferences实例初始化没有放在组件专属的初始化生命周期钩子中,不符合Flutter状态管理规范。
  • 原代码存在隐藏崩溃风险:max为null时max.toString()会得到字符串"null"作为输入框初始值,同时输入正则允许输入小数点,但存储逻辑按int类型解析,输入小数时会触发类型转换错误。
修复步骤
  1. 把预加载逻辑从build方法移到initState生命周期中,确保组件挂载时只执行一次数据读取。
  2. 新增TextEditingController控制输入框文本内容,替代initialValue实现数据更新后的界面同步,controller支持在任意时机主动设置输入框文本,不受组件初始化时机限制。
  3. 补全默认值设置分支的状态同步逻辑,确保首次加载默认值时也能正常触发界面更新。
  4. 组件销毁时回收TextEditingController,避免内存泄漏。
  5. 修正输入格式正则和空值判断,移除小数点匹配规则,避免解析崩溃。
修复后完整代码
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';

class Settings extends StatefulWidget {
  const Settings({Key? key}) : super(key: key);

  @override
  State<Settings> createState() => _SettingsState();
}

class _SettingsState extends State<Settings> {
  late SharedPreferences preferences;
  int? max;
  late TextEditingController _maxInputController;

  @override
  void initState() {
    super.initState();
    _maxInputController = TextEditingController();
    // 组件初始化时统一加载存储数据
    _loadMax();
  }

  @override
  void dispose() {
    // 销毁时回收控制器
    _maxInputController.dispose();
    super.dispose();
  }

  _loadMax() async {
    preferences = await SharedPreferences.getInstance();
    if (!preferences.containsKey('max')) {
      await _setMax(16);
    } else {
      max = preferences.getInt('max');
      // 直接给控制器赋值,同步输入框显示
      _maxInputController.text = max.toString();
      setState(() {});
    }
  }

  _setMax(int value) async {
    await preferences.setInt('max', value);
    max = value;
    // 同步更新输入框文本
    _maxInputController.text = value.toString();
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(
                  'Max Number (Inclusive) ',
                  style: Theme.of(context).textTheme.titleMedium,
                ),
                const SizedBox(width: 10.0),
                SizedBox(
                  width: 100,
                  height: 50,
                  child: TextFormField(
                    controller: _maxInputController,
                    decoration: const InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Maximum',
                      counterText: '',
                    ),
                    inputFormatters: [
                      FilteringTextInputFormatter.allow(RegExp(r"[0-9]")),
                    ],
                    onFieldSubmitted: (s) {
                      if(s.isNotEmpty) {
                        _setMax(int.parse(s));
                      }
                    },
                    maxLength: 4,
                    keyboardType: TextInputType.number,
                  ),
                ),
              ],
            ),
            ElevatedButton(
              onPressed: () => Navigator.pop(context),
              child: const Text('Home'),
            ),
          ]),
    );
  }
}

内容的提问来源于stack exchange,提问作者user19309046

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 10:27:17