在 Flutter 中使用 TextFormField 添加项目列表

问题描述

我正在尝试实施该功能添加电子邮件输入列表但用户。这是我目前所拥有的

  List<String> _notificationEmails =[];
  var _notificationEmailsController = TextEditingController();
  Widget _buildNotificationEmailsinput() {
    return TextFormField(
      controller: _notificationEmailsController,style: inputTextStyle,maxLines: null,validator: (String value) {
        print(value);
        if (value.isEmpty) {
          return 'Emails required';
        }
        return null;
      },onChanged: (String value){
        if(value.substring(value.length-1)==','){
          print('here');
            setState(() {
              _notificationEmails.add(value.substring(0,value.length-1));
            });
          _notificationEmailsController.clear();
        }
        print(_notificationEmails);
      },);
  }

我的预期结果是,当用户输入电子邮件然后在其后添加一个逗号时,电子邮件会附加到列表中并清除输入字段,但我得到了导致此 _notificationEmails.add(value.substring(0,value.length-1)); 运行的操作循环到无穷大。

这是日志

[   +3 ms] Flutter: [je@gmail.com,je@gmail.com,je@gm<…>

这种情况一直持续下去。我做错了什么?

更新

如果它有帮助,我已经意识到这个问题是因为每次调用 _notificationEmailsController.clear(); 时,它都会触发 onChange() 因此循环。

解决方法

更新:请在 TextEditingController.clear 内调用 Future.delayed。因为根据 clear...

的描述

这个方法应该只在帧之间调用,例如回应 用户操作,而不是在构建、布局或绘制阶段。

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: MyApp(),));
}

class MyApp extends StatefulWidget {
  @override
  _MyApp createState() => _MyApp();
}

class _MyApp extends State<MyApp> {
  final List<String> _notificationEmails = <String>[];
  final TextEditingController _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            _buildNotificationEmailsInput(),Expanded(
              child: ListView.builder(
                itemCount: _notificationEmails.length,itemBuilder: (_,int idx) => ListTile(
                  title: Text(_notificationEmails[idx]),),],);
  }

  Widget _buildNotificationEmailsInput() {
    return TextFormField(
      controller: _controller,validator: (String value) {
        print('VALIDATOR: $value');
        if (value.isEmpty) {
          return 'Emails Required';
        }
        return null;
      },onChanged: (String value) {
        if (value.substring(value.length - 1) == ',') {
          print('>>>>>> value = $value : controller = ${_controller.hashCode}');
          setState(() {
            _notificationEmails.add(value.substring(0,value.length - 1));
          });
          Future<void>.delayed(
            const Duration(milliseconds: 10),_controller.clear,);
          print(_notificationEmails);
        }
      },);
  }
}