How do i monitor which ListView item is selected in Flutter? - flutter

In my listView i have the itemBuilder value set to a custom widget
Widget programsRowWidget(BuildContext context, List<MembershipPrograms> programs) {
return Expanded(
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: programs.length,
itemBuilder: (context, index) {
return UsersProgramListItem(program: programs[index]);
}
),
);
In that widget the root element is a Card, whose child is an InkWell. I want to use it's onTap property to control if the item is selected or not. How do i monitor which item in the listView is selected from the listView in the parent widget shown above, and how do i allow only one item to be selected?

How do i monitor which item in the listView is selected from the listView in the parent widget shown above
You can use bool flags such as isSelected and isSelectable, which is passed to a widget in a builder function. The main aspect there is to separate logic of selection from ListView.builder to upper widget or to object of your element.
How do i allow only one item to be selected?
Use flags. When one item is selected - the flag of selectable for others can be set to false.

Related

Making parent adjust to size of child widget

I am using a ListView Builder, and that has to be wrapped inside a Container. If i don't give a height parameter then i get Vertical viewport was given unbounded height. Now, because of this if i only have 1 item in the list, any content comes after the container, which wastes a lot of screen real estate and doesn't look aesthetically pleasing.
How can i make the parent widget i.e Container() to adjust to the size of child widget ListView.builder() ?
Add this shrinkWrap: true to your ListView and Remove Height from container.
snippet code:
return Container(
child: ListView.builder(itemBuilder: (context, index) {
return listItem(itemArray[index]),
},
itemCount: itemArray.length,
shrinkWrap: true),
);

How to refresh ListView after Sorting in Flutter?

I have a ListView which contains my customers. This ListView currently is a Stateless Widget. After sorting the list of customers inside the parent, I need to refresh the list.
parent where the List is displayed (Parent is stateful):
MyLieferListe(
bestellungen.anzahlPositionen,
bestellungen.kunde,
notifyParent: refresh,
),
MyLieferListe (currently Stateless):
SingleChildScrollView(
child: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
getBeleg();
this.notifyParent(kunden[index]);
},
child: MyBestellungText(
kunden[index].kundenbezeichnung,
kunden[index].kundenNr,
"${kunden[index].strasse}, ${kunden[index].plz} ${kunden[index].ort}",
kunden[index].tourHinweis),
);
},
itemCount: kunden.length,
),
),
How to refresh the ListView of the Child which is displayed inside of the parent?
Firstly you have to make your list stateful because on changing the list. You have to call setState.
A bad solution would be to use Navigator.pushReplacement.
A good solution would be to make your list a stateful widget.
A state change triggers a rebuild in Flutter, so in order to ensure your widget rebuilds after you sort the list, you should call setState
// a state variable
List<Kunde> kunden;
onSortButtonClick() {
List<Kunde> newKunden = kunden.sort(...);
// store to the state
setState((){
kunden = newKunden;
});
}
build(WidgetContext context) {
return ListView.builder(/* use kunden, from state, in here */)
}
As you mention, your parent is already stateful. You should move bestellungen.kunde to the state variables (set it first in initState and use setState every time you change it), then it should automatically rebuild widget if you update kunden via setState.
Alternatively, you could make the child widget stateful and put kunden in the state of that widget. Theoretically, that should be slightly better since you then only rebuild the child, not the parent, but it realistically shouldn't make much difference in this case.

Is it possible to use ReorderableListView in a "wrapping" mode?

I would like the ReorderableListView not to take up the whole height which is given to it, but to be as tall as the item views that it contains.
I could make the list either flex and fill the whole height it is given, or put it in a SizedBox and have a fixed height.
I'd like to add an + Add list tile directly under the list items (similar to Google Keep on Android)
Thank you
You can try this:
Wrap your List with an Expanded widget.
Fetch the number of items in your list and return the Add List tile widget at the length-1 position of your list.
You can alter the size of your ListView in correlation to the number of items fetched from the list.
Expanded will help you alter the length dynamically.
eg:
Expanded(
child: new ListView.builder
(
itemCount: litems.length,
itemBuilder: (BuildContext ctxt, int Index) {
return new Text(litems[Index]);
if(length==length-1){
//**call your Add List tile widget here**
}
}
)
)

Flutter remove item from list

My question is about flutter's listview.
When I delete item from a list and set the state
setState(() {
items.removeAt(500);
});
flutter listview.builder scrolls to the top. I want it not to scroll after deleting item from the list.
What's your suggestion?
Thanks in advance.
our widget tree is simple we creating list like
ListView.builder(
itemCount: messages.lenght,
itemBuilder: (ctx,index){
return GestureDetector(
onTap: (){
showModalBottomSheet()...
}
);
}
)
on bottom sheet there is a function calls setState() and delete item then ListView scrolls to top

Flutter : Textfield in ListView.builder

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.
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.
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 controller
on click or the
TextField's onChanged callback (where you store the new value for
the corresponding item on 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's dispose() 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.
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,),))