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
Related
[
Can I get a logic/code for highlighting just the selected value from this list view which is inside a container and it is scrollable also that the axis is set to Horizontal.
I have used a list view builder to align the same and also generated the list of numbers.
Please check the sample image of the widget attached.
Blockquote
]1
It's hard to tell you exactly how to do it without any code examples, and I'm also not sure what you mean by selected. Is that already decided before building the list, or is it decided when the user selects from the list?
If it is already decided, you can pass a value from the parent component that tells the list to highlight a certain value.
If a user is selecting the value to highlight, you can use a combination of setState and onTap with GestureDetector. Here's a potential rough skeleton:
int selectedIndex?;
ListView.builder(
itemCount: litems.length,
itemBuilder: (BuildContext ctx, int index) {
return GestureDetector(
onTap: () {
setState(() {
selectedIndex = index;
});
},
child: Container(
backgroundColor: selectedIndex == index ? highlightedColor : undefined;
child: {{child content}}
),
);
}
)
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.
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.
I have two listview screen on my app. User can navigate between them using BottomNavigationBar control.
On listview.builder function, I return something like this
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('...'),
subtitle: Text('...'),
onTap: () {
...
}
)
});
I found onTap handler seems mixed between those 2 listviews.
When I open first list view, flutter serve the correct onTap,but when I switch to second listview, flutter still serving the first listview onTap.
Seems the onTap is cached by flutter (title & subtitle seems okay). Any idea?
Sample source code: https://github.com/jazarja/flutter_app
The problem is in your compararing transition values. Because you are first reversing the animation transition of current view.
In your botton_nav.dart, change this:
return aValue.compareTo(bValue);
to this:
return bValue.compareTo(aValue);
Yes the problem is that the animations haven't completed by the time the comparison is being done so the widget at the top of the stack is always 1 tab selection behind. You actually don't need to build a stack at all, just replace Center(child: _buildTransitionStack()) here with _navigationViews[_currentIndex].transition(_type, context) and it should work.
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,),))