Flutter:ListView.builder中的TextField

12

大家好,我有一些数据存储在Cloud Firestore中,并使用ListView.builder来加载这些数据。 在这个ListView.builder中,我使用了Network.Image,ListTile来显示标题和副标题,还有另一个ListTile,其中包含一个Textfield用于添加评论和一个iconbutton。 我的目标是获取textfield的文本内容,并在点击按钮时将其显示为alertDialog。到目前为止,我已经为textfield添加了控制器,但无论我在textfield中输入任何内容,它都会更改所有的textfield。我曾尝试创建一个列表来指定一个唯一的控制器,以便我可以停止所有textfield的更改,但是我失败了。是否有任何方法可以做到这一点?所有的textfield和iconbuttons必须是唯一的,所以当我点击iconbutton时,我需要看到已输入textfield的文本。

3个回答

49

尝试使用

List<TextEditingController> _controllers = new List();
//try below in null-safe
//List<TextEditingController>? _controllers = [];

在你的ListView.builder内为每个项添加一个新控制器。

ListView.builder(
            itemBuilder: (context,index){
              _controllers.add(new TextEditingController());
              //try below in null-safe
              //_controllers!.add(TextEditingController());
              //Your code here

            }),

要访问控制器的文本,您需要使用索引值:

_controllers[index].text

请确保最终处理所有textControllers。


谢谢你的帮助,Ashutosh,你救了我的一天,伙计。 - Lastmentor
1
你如何处理这个文本控制器列表? - Davii The King
为了释放文本控制器,我将其放在我的dispose()函数中:for (TextEditingController c in _controllers) { c.dispose(); } - Rivers Cuomo
4
我不知道你的答案是否正确。你的代码会在每次滚动时创建新的控制器并重新创建列表中的项!而且控制器的长度将不同于你的列表长度。 - Elblasy
你会如何在嵌套的ListView.builder上实现相同的答案? - Kim Lo

7
你可能需要考虑为每一行创建一个新的自定义小部件。您可以利用(在调用相应的控制器on click
  • TextFieldonChanged回调中存储相应项目的新值on change)。

    在这两种情况下,您都有一个相当讨厌的文本控制器或字符串值列表。

    请记住,ListView.builder只会构建在视口内或附近的项目(随着您滚动)。

    仅为实际可见的那些子项调用构建器

    这意味着您可以多次构建相同的行

    考虑为每一行使用自定义小部件(扩展StatefulWidget

    这将减轻所有角色所涉及的协调工作,并将任何结果状态向下推到叶节点

    如果使用TextEditingController
    • 您只需要担心一个控制器
    • 在小部件的dispose()方法中调用_textController.dispose()
    如果使用onChanged回调(仅适用于TextField而非TextFormField):
    • 在自定义小部件中创建一个字符串变量作为状态 inputValue
    • 处理空值情况
    • 在点击按钮时从该变量中读取

    看起来使用TextEditingController可能是最简单的方法,但我想提供两种选项供您考虑。


  • 如何在ListView.builder中处理控制器? - Ali Punjabi

    2
    ListView.builder(
             shrinkWrap: true,
             physics: ScrollPhysics(),
             itemCount: list.length,
             itemBuilder: (BuildContext context, int index) {
             _controllers.add(new TextEditingController());
               return Container(
                   child: TextField(
                      textAlign: TextAlign.start,
                      controller:   _controllers[index],
                      autofocus: false,
                      keyboardType: TextInputType.text,),))
    

    你如何在类似这样嵌套的ListView.builder上设置控制器? - Kim Lo

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接