使用 initialValue 时 setState 不会更新 TextFormField

won*_*lik 25 flutter

每个人。

我正在使用没有任何自己的 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()),
            ],
          ),
        ),
      ),
    );
  }
}


Run Code Online (Sandbox Code Playgroud)

例子

小智 51

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

通过制作Key反应数据 ( toString()),表单字段将在每次更改时Key更改。

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

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

  • 如果您有多个 TextFormFields,则可能会导致按键冲突。UniqueKey 似乎是一个解决方案。更新真的很慢,每次用户移动对象时我都会更新。使用控制器并不会真正影响性能...... (8认同)
  • 救生员兄弟:DI 由于数据量太大而不想使用控制器。这是我实施的解决方案,但价值不更新,但您的建议解决了问题。 (2认同)

小智 5

我使用了这样简单的东西:

TextFormField(
 controller:  TextEditingController()..text = '23232',
  keyboardType: TextInputType.number,
  decoration: InputDecoration(
    labelText: 'Total',
  ),
),
Run Code Online (Sandbox Code Playgroud)

  • 这不是执行此操作的正确方法。它不会“TextEditingController”的“dispose()”。 (2认同)