Hi everyone i have some data at Cloud Firestore and a ListView.builder to load the data in it. In this ListView.builder i have Network.Image, ListTile to show the title and subtitle and another ListTile which has a Textfield to add some comment and an iconbutton. My goal is to get the text of the textfield and show as a alertDialog when the button clicked. Until now i added a controller to the textfield but whenever i type anything in the textfield it changes all the textfields. I have tried creating a List to specify a unique controller so i can stop the all of the changes in textfields but i have failed. Is there any way i can do this. All this textfields and iconbuttons must be unique so when i clicked the iconbutton i need to see the text of the typed textfield.
3 Answers
Try using
List<TextEditingController> _controllers = new List();
//try below in null-safe
//List<TextEditingController>? _controllers = [];
And inside your ListView.builder
add a new controller for each item.
ListView.builder(
itemBuilder: (context,index){
_controllers.add(new TextEditingController());
//try below in null-safe
//_controllers!.add(TextEditingController());
//Your code here
}),
To access the controller's text you will need the index value
_controllers[index].text
Make sure to dispose of all textControllers in the end.

- 11,757
- 3
- 13
- 40

- 821
- 7
- 11
-
Thanks for the help Ashutosh u saved my day m8 – Lastmentor Sep 08 '18 at 13:00
-
1how do you dispose this list of text controllers? – Davii The King Jan 28 '21 at 15:40
-
To dispose of the text controllers I'm putting this in my dispose() function: `for (TextEditingController c in _controllers) { c.dispose(); }` – Rivers Cuomo May 03 '21 at 15:46
-
4i don't know how is your answer is right one your code will create new controller every scroll and recreate item in list ! and length of controller won't be the same as length of your list – elblasy May 03 '22 at 16:58
-
how would you implement the same answer on a nested listview.builder? – Kim Lo May 16 '22 at 06:46
You might want to consider making a new type of custom Widget for each row.
You can leverage a
TextEditingController
(where you call the corresponding controlleron click
or theTextField
'sonChanged
callback (where you store the new value for the corresponding itemon change
In both cases you have a somewhat nasty list of either text controllers or String values.
Remember, ListView.builder is only going to build the items that are in or near the viewport (as you scroll).
the builder is called only for those children that are actually visible
That means that you can have the same row built multiple times (
Consider using a custom widget for each row (extend StatefulWidget
)
This will alleviate the coordination involved with all the roles and it will push any resulting state further down the tree to the leaf nodes
If using a TextEditingController
:
- you only have one controller to worry
- call
_textController.dispose()
in the widget'sdispose()
method
If using a onChanged callback (available on TextField
not TextFormField
)
- create a String variable as state in the custom widget
inputValue
- handle the null cases
- read from this when the button is tapped
It looks like the TextEditingController may be easiest, but I wanted to mention both options for your consideration.

- 16,659
- 5
- 31
- 25
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,),))

- 267
- 5
- 14

- 21
- 2
-
how do you set a controller on a listview.builder like this but nested? – Kim Lo May 16 '22 at 06:58