在 TextInputType 更改后控制器重置的 Flutter TextField

Posted

技术标签:

【中文标题】在 TextInputType 更改后控制器重置的 Flutter TextField【英文标题】:Flutter TextField with controller resetting after TextInputType change 【发布时间】:2019-01-02 05:44:05 【问题描述】:

我在我的应用程序中使用全屏对话框将用户输入值输入到文本字段中。其中一些值是字符串,一些是整数。所以我想相应地更改键盘以使不必要的键消失。这是我的实现:

import 'package:flutter/material.dart';
import 'package:meal_tracker/model/food_model.dart';

class AddFoodDialog extends StatelessWidget 
  TextEditingController nameController = TextEditingController(),
      carbsController = TextEditingController(),
      fatController = TextEditingController(),
      proteinController = TextEditingController(),
      amountController = TextEditingController();

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text("Add Food"),
        actions: <Widget>[
          FlatButton(
            child: Text(
              "SAVE",
              style: TextStyle(color: Colors.white),
            ),
            onPressed: () 
              _handleSave(context);
            ,
          )
        ],
      ),
      body: Form(
          child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: <Widget>[
            TextFormField(
              decoration: InputDecoration(labelText: "Name"),
              controller: nameController,
            ),
            TextFormField(
              decoration: InputDecoration(labelText: "Carbs per 100g"),
              controller: carbsController,
              keyboardType: TextInputType.number,
            ),
            TextFormField(
              decoration: InputDecoration(labelText: "Fat per 100g"),
              controller: fatController,
              keyboardType: TextInputType.number,
            ),
            TextFormField(
              decoration: InputDecoration(labelText: "Protein per 100g"),
              controller: proteinController,
              keyboardType: TextInputType.number,
            ),
            TextFormField(
              decoration: InputDecoration(labelText: "Amount in g"),
              controller: amountController,
              keyboardType: TextInputType.number,
            ),
          ],
        ),
      )),
    );
  

  void _handleSave(BuildContext context) 
    print("Dialog text: " + nameController.text);
    Navigator.of(context).pop(Food(
        name: nameController.text,
        carbsPer100g: double.parse(carbsController.text),
        fatPer100g: double.parse(fatController.text),
        proteinPer100g: double.parse(proteinController.text),
        amount: double.parse(amountController.text)));
  

问题是,当我在“名称”文本字段中输入一些内容时,该文本字段具有 TextInputType.text,然后点击另一个文本字段,其中具有 TextInputType.number,“名称”字段会无缘无故地清除.反过来也一样。

【问题讨论】:

您需要创建一个 StatefulWidget 并将您的控制器放在 State 上。将可变字段添加到 StatelessWidget 将不起作用 你有什么方法可以避免大量的 TextEditingControllers 吗? 【参考方案1】:

我不得不将 TextEditingControllers 放在一个有状态的小部件中,这确实有效。感谢 Jonah Williams 的快速回复!

【讨论】:

你们拯救了我的一天。谢谢各位【参考方案2】:

在您的情况下,您必须声明一个 StatefulWidget。如果控制器是在构建函数中定义的,可能会导致类似的问题

【讨论】:

【参考方案3】:

TextFields 值重置可能有两个主要原因

无状态小部件 将 TextEditingController 的属性声明为 final

如果您想处理任何小部件的状态,尤其是在 Dialogue (SimpleDialog) 内部,请始终创建一个单独的 StatefulWidget 类和 TextEditingController 属性作为变量 var

以下是 Stateful 小部件的完整示例,它不会在切换时重置 TextFields 值

class ReportDialog extends StatefulWidget 
  @override
  _ReportDialogState createState() => new _ReportDialogState();


class _ReportDialogState extends State<ReportDialog> 
  var selectedConfiguration = SharedConfiguration().selectedConfiguration;
  var titleTextField = TextEditingController();
  var descriptionTextField = TextEditingController();

  @override
  Widget build(BuildContext context) 
    final reportButton = ReusableWidgets.getButton('REPORT',
        Colors.redAccent, Colors.white, reportButtonAction, context, 46);

    return SimpleDialog(
      contentPadding: EdgeInsets.fromLTRB(20, 10, 20, 10),
      children: <Widget>[
        new TextField(
          controller: titleTextField,
          decoration: new InputDecoration(
            border: new OutlineInputBorder(),
            hintText: 'Title',
          ),
          maxLines: 1,
        ),
        SizedBox(height: 8.0),
        new TextField(
          controller: descriptionTextField,
          decoration: new InputDecoration(
            border: new OutlineInputBorder(),
            hintText: 'Add your message here...',
            helperText: 'Keep it short, this is just a demo.',
          ),
          maxLines: 6,
        ),
        SizedBox(height: 20.0),
        reportButton
      ],
    );
  

  void reportButtonAction() 
    Navigator.of(context).pop();
  

希望有用:)

【讨论】:

以上是关于在 TextInputType 更改后控制器重置的 Flutter TextField的主要内容,如果未能解决你的问题,请参考以下文章

在代码中更改框架后自动布局重置视图

我将如何更改我的程序,以便在方法正确后计时器停止

如何在提交表单后使用“加载”更改按钮文本并在以角度提交后重置表单

如何在更改相机权限后阻止iOS应用重置?

Flutter TextInputType.number 不强制使用仅数字键盘

text git add后重置更改。