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

Flutter页面传值问题:页面2经纬度回显至页面1TextFormField

问题分析与解决方案

核心问题原因

  1. 控制器重复创建导致状态丢失:原代码中每次调用lngTextFormField都会新建TextEditingController,页面重建(路由跳转、状态更新)时控制器会被重新初始化,原有值被清空,新传递的参数也无法同步。
  2. 初始值未触发保存逻辑:onChanged仅在用户手动输入时触发,初始化或参数更新时不会调用saveAd,导致初始值无法自动保存,必须手动输入才会触发。

修复后的代码实现

页面1(EditAddressPage)重构

class EditAddressPage extends StatefulWidget {
  final int index;
  final String lat;
  final String lng;

  const EditAddressPage({
    super.key,
    required this.index,
    required this.lat,
    required this.lng,
  });

  @override
  State<EditAddressPage> createState() => _EditAddressPageState();
}

class _EditAddressPageState extends State<EditAddressPage> {
  // 将控制器声明为State成员变量,避免重复创建
  late TextEditingController _latController;
  late TextEditingController _lngController;

  @override
  void initState() {
    super.initState();
    // 初始化控制器,使用页面传入的初始参数
    _latController = TextEditingController(text: widget.lat);
    _latController.selection = TextSelection.collapsed(offset: _latController.text.length);
    _lngController = TextEditingController(text: widget.lng);
    _lngController.selection = TextSelection.collapsed(offset: _lngController.text.length);
    
    // 初始化时自动保存初始值
    saveAd(widget.lat, 'lat');
    saveAd(widget.lng, 'lng');
  }

  @override
  void didUpdateWidget(covariant EditAddressPage oldWidget) {
    super.didUpdateWidget(oldWidget);
    // 当页面参数更新时(从页面2跳转传递新值),同步更新控制器并保存
    if (oldWidget.lat != widget.lat) {
      _latController.text = widget.lat;
      _latController.selection = TextSelection.collapsed(offset: _latController.text.length);
      saveAd(widget.lat, 'lat');
    }
    if (oldWidget.lng != widget.lng) {
      _lngController.text = widget.lng;
      _lngController.selection = TextSelection.collapsed(offset: _lngController.text.length);
      saveAd(widget.lng, 'lng');
    }
  }

  @override
  void dispose() {
    // 销毁控制器,避免内存泄漏
    _latController.dispose();
    _lngController.dispose();
    super.dispose();
  }

  void saveAd(String value, String keyword) {
    // 你的保存逻辑(如更新本地存储、状态管理数据等)
    print("Saved $keyword: $value");
  }

  Widget _buildTextFormField(String label, String keyword, TextEditingController controller) {
    return TextFormField(
      controller: controller,
      onChanged: (value) {
        saveAd(value, keyword);
      },
      decoration: InputDecoration(
        labelText: label,
        labelStyle: const TextStyle(
          fontFamily: 'supermarket',
          fontSize: 16,
        ),
        isDense: true,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('编辑地址')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            _buildTextFormField('纬度', 'lat', _latController),
            const SizedBox(height: 16),
            _buildTextFormField('经度', 'lng', _lngController),
          ],
        ),
      ),
    );
  }
}

页面2跳转代码(保持原有逻辑即可)

void saveAddress() {
  var lat = centerMap.latitude;
  var lng = centerMap.longitude;
  Navigator.push(
    context,
    MaterialPageRoute(
      builder: (context) => EditAddressPage(
        index: widget.index,
        lat: lat.toString(),
        lng: lng.toString(),
      ),
    ),
  );
  print("Saving address: Latitude: $lat, Longitude: $lng");
}

关键修复点说明

  1. 控制器全局化:将TextEditingController提升为State类的成员变量,确保每个输入框对应唯一的控制器实例,避免页面重建时丢失状态。
  2. 初始化与参数更新同步:
    • 在initState中初始化控制器并保存初始值;
    • 通过didUpdateWidget监听参数变化,自动更新控制器文本并触发保存逻辑,无需手动输入。
  3. 内存泄漏防护:在dispose方法中销毁控制器,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 14:40:18