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

时间:2018-07-25 11:58:45

标签: dart flutter

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

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的另一个TextField时,“名称”字段将被清除没有明显的原因。反之亦然。

3 个答案:

答案 0 :(得分:6)

我不得不将TextEditingControllers放入一个有状态的小部件中,该小部件最终确实可以工作。感谢乔纳·威廉姆斯的快速回复!

答案 1 :(得分:0)

在您的情况下,您必须声明一个StatefulWidget。如果在内部构建函数中定义了控制器,则会引起类似的问题

答案 2 :(得分:0)

TextFields值重置可能由于两个主要原因而发生

  • 无状态小工具
  • 将TextEditingController的属性声明为final

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

下面是有状态小部件的完整示例,该小部件不会在切换时重置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();
  }
}

希望它有用:)