【问题标题】:setState does not update TextFormField when use initialValue使用 initialValue 时 setState 不更新 TextFormField
【发布时间】:2019-09-22 22:52:03
【问题描述】:

每个人。

我正在使用没有任何自己的 TextEditController 的 Form 和 TextFieldForm。有 3 个带有初始值的 TextFieldForm(Value_1、Value_2、Total)。当我编辑第一个时,总文本字段应包含计算结果。要更新小部件,我正在使用 setState。变量 _total 和 Text 小部件始终具有正确的计算值,但 Total 文本字段不想更新的问题。

为什么?不使用自己的 TextEditController 可以吗?

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: TestForm(),
    );
  }
}

class TestForm extends StatefulWidget {
  @override
  _TestFormState createState() => _TestFormState();
}

class _TestFormState extends State<TestForm> {
  GlobalKey<FormState> _formKey = GlobalKey();

  int _value1 = 0;
  int _value2 = 20;
  int _total = 0;

  @override
  Widget build(BuildContext context) {
    print('rebuild');
    return Scaffold(
      appBar: AppBar(title: Text('test form')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: ListView(
            children: <Widget>[
              TextFormField(
                initialValue: _value1.toString(),
                decoration: InputDecoration(
                  labelText: 'Value_1',
                ),
                keyboardType: TextInputType.number,
                onChanged: (value) {
                  setState(() {
                    _total = int.parse(value) * _value2;
                    print('total: ' + _total.toString());
                  });
                },
              ),
              TextFormField(
                initialValue: _value2.toString(),
                keyboardType: TextInputType.number,
                 decoration: InputDecoration(
                  labelText: 'Value_2',
                ),
              ),
              TextFormField(
                initialValue: _total.toString(),
                keyboardType: TextInputType.number,
                 decoration: InputDecoration(
                  labelText: 'Total',
                ),
              ),
              SizedBox(height: 20),
              Text('total: ' + _total.toString()),
            ],
          ),
        ),
      ),
    );
  }
}


【问题讨论】:

  • 因为它只是一个初始值,而不是你设置给TextFormField的值,也许setState只是重建Widget而不是它的初始值。试试这个 [链接] (stackoverflow.com/questions/51715534/…)
  • 不,这是不可能的 - 使用 controller 属性而不是 initialValue
  • 顺便说一句,使用TextEditController 有什么问题?你的代码是不是更复杂,不可读?
  • TextEditController 没什么问题,但对我来说使用 TextFormField 和默认控制器有点奇怪,没有任何简单的选项使用这个控制器来管理值。表单中的 20 个字段 = 20 个自己的控制器,这太复杂了。

标签: flutter


【解决方案1】:

如果您有响应式数据源,也就是可以根据网络更新或其他数据更改的数据,那么对我有用的一个技巧是使用 Key

通过对响应式数据 (toString()) 进行Key,每次Key 更改时,表单字段都会更改。

所以在这种情况下你可以这样做:

TextFormField(
  key: Key(_total.toString()), // <- Magic!
  initialValue: _total.toString(),
  keyboardType: TextInputType.number,
  decoration: InputDecoration(
    labelText: 'Total',
  ),
),

【讨论】:

  • 我有一个类似的问题是初始值不会更新并且似乎总是滞后。这为我解决了问题。
  • Life Saver bro :D 由于数据量大,我不想使用控制器。这是我实施的解决方案,但没有更新但您的建议解决了问题的值。
  • 它有效,你节省了我的时间
  • 如果您有多个 TextFormFields,您最终可能会发生键冲突。 UniqueKey 似乎是一个解决方案。更新真的很慢,每次用户移动对象时我都会更新。使用控制器并没有真正产生性能差异......
  • 这是真正的魔法
【解决方案2】:

我用了这么简单的东西:

TextFormField(
 controller:  TextEditingController()..text = '23232',
  keyboardType: TextInputType.number,
  decoration: InputDecoration(
    labelText: 'Total',
  ),
),

【讨论】:

  • 这不是正确的方法。它不会是dispose()TextEdiingController
猜你喜欢
  • 1970-01-01
  • 2023-02-24
  • 2021-07-01
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 2023-04-09
  • 2021-01-13
  • 1970-01-01
相关资源
最近更新 更多