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

Flutter中TextFormField页面跳转后值持久化的Provider实现咨询

解决Flutter TextFormField跳转返回后输入值丢失的问题

你的当前写法只实现了输入时把值同步到Provider,但缺少了页面初始化/重建时从Provider同步值到controller的逻辑——这就是跳转返回后值消失的核心原因:页面重建时controller会重新创建,没有加载Provider中保存的历史值。

下面是两种可行的实现方案:

方案一:初始化同步+Controller监听(推荐)

1. 完善Provider类

确保Provider正确持有状态并提供更新方法:

import 'package:flutter/foundation.dart';

class FormProvider extends ChangeNotifier {
  String? _amount;

  // 提供只读的状态获取方法
  String? get amount => _amount;

  // 更新金额并通知监听者
  void updateAmount(String newAmount) {
    _amount = newAmount;
    notifyListeners();
  }
}

2. 页面中同步Controller与Provider

在StatefulWidget中处理Controller的初始化、同步和销毁:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class AmountFormPage extends StatefulWidget {
  const AmountFormPage({super.key});

  @override
  State<AmountFormPage> createState() => _AmountFormPageState();
}

class _AmountFormPageState extends State<AmountFormPage> {
  late TextEditingController _amountController;
  late FormProvider _formProvider;

  @override
  void initState() {
    super.initState();
    // 获取Provider实例(listen: false避免不必要的UI重建)
    _formProvider = Provider.of<FormProvider>(context, listen: false);
    // 初始化Controller时,直接传入Provider中保存的历史值
    _amountController = TextEditingController(text: _formProvider.amount);
    
    // 监听Controller的文本变化,自动同步到Provider
    _amountController.addListener(() {
      _formProvider.updateAmount(_amountController.text);
    });
  }

  @override
  void dispose() {
    // 销毁Controller,防止内存泄漏
    _amountController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('输入金额')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: TextFormField(
          controller: _amountController,
          decoration: const InputDecoration(
            labelText: '金额',
            border: OutlineInputBorder(),
          ),
          keyboardType: TextInputType.number,
        ),
      ),
    );
  }
}

方案二:Consumer监听Provider变化(适合跨页面更新场景)

如果需要从其他页面修改Provider的amount并同步到当前输入框,可以用Consumer监听Provider的变化,自动更新Controller:

// 替换页面的build方法为以下代码
@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: const Text('输入金额')),
    body: Padding(
      padding: const EdgeInsets.all(16.0),
      child: Consumer<FormProvider>(
        builder: (context, provider, child) {
          // 仅当值不同时更新,避免无限循环
          if (_amountController.text != provider.amount) {
            _amountController.text = provider.amount ?? '';
          }
          return TextFormField(
            controller: _amountController,
            decoration: const InputDecoration(
              labelText: '金额',
              border: OutlineInputBorder(),
            ),
            keyboardType: TextInputType.number,
            onChanged: (value) {
              provider.updateAmount(value);
            },
          );
        },
      ),
    ),
  );
}

关键注意事项

  • 必须在父级Widget中注册Provider(比如用ChangeNotifierProvider包裹MaterialApp):
    void main() {
      runApp(
        ChangeNotifierProvider(
          create: (context) => FormProvider(),
          child: const MyApp(),
        ),
      );
    }
    
  • 始终在dispose方法中销毁TextEditingController,防止内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 18:10:19