在 iOS 模拟器键盘上按 enter / return 按钮不存储 TextField onChanged 数据 为什么?

Pressing enter / return button on iOS simulator keyboard doesn't store the TextField onChanged data Why?

我正在创建一个 TodoList 并使用 onChanged 参数将 TextField 的值存储在一个变量中。

当我在 iOS 模拟器上点击外部关闭软件键盘时,它会正确存储值。

如果我使用软件键盘上的输入/return按钮它存储空值。

为什么会这样?

我该怎么做才能避免这种行为?

我正在使用提供程序包作为状态管理解决方案。

class AddThingScreen extends StatelessWidget {
  String title;


  @override
  Widget build(BuildContext context) {

    return Container(
      color: Color(0xff757575),
      child: Container(
        padding: EdgeInsets.all(20),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.only(
            topRight: Radius.circular(20),
            topLeft: Radius.circular(20),
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Text(
              'Add thing',
              style: TextStyle(
                color: Colors.lightBlueAccent,
                fontSize: 36.0,
              ),
            ),
            TextField(
              controller: textEditingController,
              autofocus: true,
              autocorrect: true,
              textAlign: TextAlign.center,
              decoration: InputDecoration(
                focusColor: Colors.lightBlueAccent,
              ),
              onChanged: (newThingTitle) {
                title = newThingTitle;
              },
            ),
            FlatButton.icon(
              color: Colors.lightBlueAccent,
              icon: Icon(
                Icons.add,
                color: Colors.white,
              ),
              label: Text(
                'Add it',
                style: TextStyle(
                  color: Colors.white,
                ),
                textAlign: TextAlign.center,
              ),
              onPressed: () {
                Provider.of<ThingData>(context).addThing(title);
                Navigator.pop(context);
              },
            )
          ],
        ),
      ),
    );
  }
}

如您所见,我调用了一个存储在我的 ThingData class 中的方法,该方法将新事物添加到列表中,然后通知监听器。

class ThingData extends ChangeNotifier {
  List<Thing> _things = [
    Thing(name: 'Buy Cheese', isDone: false),
    Thing(name: 'Buy Flatbread', isDone: true),
    Thing(name: 'Buy Hot Sauce', isDone: false),
  ];

  int get thingCount {
    return _things.length;
  }

  UnmodifiableListView<Thing> get thingsList {
    return UnmodifiableListView<Thing>(_things);
  }

  void addThing(String newThingTitle) {
    final thing = Thing(name: newThingTitle);
    _things.add(thing);
    notifyListeners();
  }
}

因为你在 StatelessWidget.

的构建方法的 body 中定义了 title

如果你真的想存储标题的状态,你需要使用StatelessWidget:

class AddThingScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _AddThingScreenState();
  }
}

class _AddThingScreen State extends State<AddThingScreen> {
  String title;

  @override
  initState() {
    super.initState();
    title = '';
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Color(0xff757575),
      child: Container(
        padding: EdgeInsets.all(20),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.only(
            topRight: Radius.circular(20),
            topLeft: Radius.circular(20),
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Text(
              'Add thing',
              style: TextStyle(
                color: Colors.lightBlueAccent,
                fontSize: 36.0,
              ),
            ),
            TextField(
              autofocus: true,
              autocorrect: true,
              textAlign: TextAlign.center,
              decoration: InputDecoration(
                focusColor: Colors.lightBlueAccent,
              ),
              onChanged: (newThingTitle) {
                setState(() => {
                  title = newThingTitle;
                });
              },
            ),
            FlatButton.icon(
              color: Colors.lightBlueAccent,
              icon: Icon(
                Icons.add,
                color: Colors.white,
              ),
              label: Text(
                'Add it',
                style: TextStyle(
                  color: Colors.white,
                ),
                textAlign: TextAlign.center,
              ),
              onPressed: () {
                Provider.of<ThingData>(context).addThing(title);
                Navigator.pop(context);
              },
            )
          ],
        ),
      ),
    );
  }
}

您需要向 TextField 添加键盘操作:

TextFormField( 
  ...
  textInputAction: TextInputAction.done,
  ...
)

然后使用 onFieldSubmited 回调处理行为,如下所示:

TextFormField( 
  ...
  textInputAction: TextInputAction.done,
  onFieldSubmitted: (newThingTitle) {
    title = newThingTitle;
  },
  ...
)