I've added a list element by using the following method:
listToAddTo.add(italianFood());
However, when I try removing the same element by using the method:
listToAddTo.remove(italianFood());
it does not work.
I've tried using the removeWhere method with the parameters item == italianFood(), the retainWhere method with the item != italianFood() parameters, and the removeAt method with the listToAddTo.indexOf(italianFood()) parameters, however, none of those seem to work.
When I try printing the list, I get the following result:`
ListView(
scrollDirection: vertical,
primary: using primary controller,
scrollPhysics: AlwaysScrollableScrollPhysics,
shrinkWrap: shrink-wrapping
)
Above methods with this result also seem to have no effect.
Necessary code is as follows:
List listToAddTo = [];
ListView italianFood() {
return ListView(
shrinkWrap: true,
children: <Widget>[
listEntry(
'Fast Food Nana',
'Mon - Sun 06:00 - 04:00',
Container(
child: IconButton(
icon: Icon(
Icons.motorcycle,
size: 30.0,
),
),
),
IconButton(
icon: Icon(
Icons.navigation,
size: 30.0,
),
),
),
],
);
Container filterItem(String label, value, onChanged) {
return Container(
decoration: BoxDecoration(color: Colors.white),
child: CheckboxListTile(
value: value,
title: Text(label),
onChanged: onChanged,
),
);
bool isTrue = false;
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Container(
margin: const EdgeInsets.only(top: 45.0),
child: ListView.builder(
itemCount: listToAddTo.length,
itemBuilder: (BuildContext context, int Index) {
return (listToAddTo[Index]);
},
),
),
ExpansionTile(
title: Text('Filters'),
children: <Widget>[
filterItem(
'Italian',
isTrue,
(bool value) {
setState(() {
if (isTrue == false) {
listToAddTo.add(italianFood());
isTrue = !isTrue;
} else {
listToAddTo.removeAt(listToAddTo.indexOf(italianFood()));
isTrue = !isTrue;
}
});
print(listToAddTo);
print(italianFood());
},
),
],
),
],
);
You can't remove it because are different objects.
Every time you use italianFood() you create a new instance of the class.
Create a gloval variable :
ListView _myItalianFood;
Instantiate:
in your add method:
_myItalianFood = italianFood();
listToAddTo.add(_myItalianFood);
Remove:
listToAddTo.remove(_myItalianFood);
The problem is that italianFood() returns a new ListView instance on each call. So when you call listToAddTo.add(italianFood()) you are creating a new ListView instance (let's call it LV1) and you end up with listToAddTo being [LV1].
When you call listToAddTo.remove(italianFood()) you are creating a new ListView instance (let's call it LV2) and asking listToAddTo to remove anything that is equal to LV2, so this ends up doing nothing since LV2 is not in listToAddTo.
You could fix this by making italianFood a field.
final italianFood = ListView(shrinkWrap: true, ...);
Related
I entered the data from json, everything works fine, but now only the first element is displayed. How can I write here like foreach so that all elements with a loop are displayed.
You can see the code here
You should wrap the data with listview builder.
Try code something like this:
...
else if(snapshot.hasData ){
return ListView.builder (
itemCount: snapshot.data.length, \\length of snapshot data
itemBuilder: (BuildContext ctxt, int index) {
return Container(
child:Column(
children: <Widget>[
new Padding(padding: const EdgeInsets.all(5.0)),
new Container(
child: new Text(
'Тип штрафа: ${data[index]['VDescription']}'
),
),
new Container(
child: new Text(
'Адрес: ${data[index]['VLocation']}'
),
),
new Container(
child: new Text(
'Дата: ${data[index]['VTime']}'
),
),
],
),
);
}
);
I hope this will work. :)
I want to make a nested list view in the following manner
How can I do this? I only want the nested list view for one of the radio tiles not all of them.
I tried including both ListView builder in another List however there was rendering problem.
My code:
Column(
children: <Widget>[
.....
Expanded(
child:
ListView.builder(
padding: EdgeInsets.all(0.0),
itemCount: tasks.length,
itemBuilder: (context, index) {
return RadioListTile<String>(
//contentPadding: EdgeInsets.symmetric(horizontal: 16.0),
title: Text(tasks[index], style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w400)),
value: tasks[index],
groupValue: selectedRadio,
onChanged: (val){
setSelectedRadio(val);
}
);
},
),
),
],
);
You cannot build a ListView inside a ListView as you will confuse the scroll behaviour. You should use List widget that does not scroll, such as Column.
ListView.builder(
padding: EdgeInsets.all(0.0),
itemCount: tasks.length,
itemBuilder: (context, index) {
if (// single RadioListTile) {
return RadioListTile<String>(
title: Text(tasks[index], style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w400)),
value: tasks[index],
groupValue: selectedRadio,
onChanged: (val) => setSelectedRadio(val),
);
}
else if (// nested RadioListTile) {
return Column(
children: <Widget>[
// RadioListTile1,
// RadioListTile2,
// RadioListTile3,
],
);
}
},
),
You can totally include a list view inside of another list view. But the inside list view has to have shrinkWrap set to true
I'm making a new stateful widget that would show a listview according to the option selected, which are ONE and TWO here. The value of index changes once the GestureDetector is tapped, fontsize and color of the text changes. but, the Container with pages[index] does not rebuild
I don't know what is wrong since, one of the container in the column rebuilds and the other doesn't.
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return MatchStatsState();
}
}
class MatchStatsState extends State<MatchStats>{
List<Widget> pages = [
ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
BattingStatsView(CskBatting),
BowlingStatsView(cskBowling),
],
),
ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
BattingStatsView(kxipBatting),
BowlingStatsView(kxipBowling)
],
),
];
Color activeColor = Colors.yellow;
Color inactiveColor = Colors.white;
num activeFontSize = 20.0;
num inactiveFontSize = 15.0;
int index = 0;
#override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
height: MediaQuery.of(context).size.height*0.4,
width: MediaQuery.of(context).size.width*0.95,
child: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height*0.05,
width: MediaQuery.of(context).size.width*0.95,
child: Row(
children: <Widget>[
GestureDetector(
onTap: (){
setState(() {
index = 0;
});
},
child: Container(
width: MediaQuery.of(context).size.width*0.45,
child: Text("ONE",style: TextStyle(color: index == 0?activeColor:inactiveColor,fontSize: index == 0? activeFontSize: inactiveFontSize)),
),
),
GestureDetector(
onTap: (){
setState(() {
index = 1;
});
},
child: Container(
width: MediaQuery.of(context).size.width*0.45,
child: Text("TWO",style: TextStyle(color: index == 1?activeColor:inactiveColor, fontSize: index == 1? activeFontSize: inactiveFontSize)),
),
),
],
),
),
Container(
height: MediaQuery.of(context).size.height*0.35,
width: MediaQuery.of(context).size.width*0.95,
child: pages[index]
),
]
)
);
}
}
I want the second container in the column to rebuild when the value of index changes, how could I achieve that?
Try with this:
create a method that return a List Widget like this:
List<Widget> buildPages() {
return [
ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
BattingStatsView(CskBatting),
BowlingStatsView(cskBowling),
],
),
ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
BattingStatsView(kxipBatting),
BowlingStatsView(kxipBowling)
],
),
];
}
Widget getProperWidget(int index) {
return buildPages()[index];
}
Than your column container:
Container(
height: MediaQuery.of(context).size.height*0.35,
width: MediaQuery.of(context).size.width*0.95,
child: getproperWidget(index)
),
Remember to override the initState.
I think the cause of this issue is the element tree doesn't recognize the change that has been done in the widget tree , so you can add Key to the container which holds pages[index] or
you can do something like this :
Widget getWidget(int index){
return Container(
child:pages[index],
);
}
instead of using Container in the widget tree, use a function that will be called every time the ui re renders .
I hope that can help
I'm trying to make a list of items using ListWheelScrollView and I want to have the ability of tapping on items but it seems onTap doesn't work.
Here is a simple code
List<int> numbers = [
1,
2,
3,
4,
5
];
...
Container(
height: 200,
child: ListWheelScrollView(
controller: fixedExtentScrollController,
physics: FixedExtentScrollPhysics(),
children: numbers.map((month) {
return Card(
child: GestureDetector(
onTap: () {
print(123);
},
child: Row(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
month.toString(),
style: TextStyle(fontSize: 18.0),
),
)),
],
),
));
}).toList(),
itemExtent: 60.0,
),
)
Is there something wrong with this code ? I'm pretty sure something like this will work on a ListView or other scrolling widgets.
I solved the problem. I hope is helpful.
create a int variable in State class.
class _MenuWheelState extends State {
int _vIndiceWheel;
in the Function onSelectedItemChanged of the ListWheelScrollView set the variable:
onSelectedItemChanged: (ValueChanged) {
setState(() {
_vIndiceWheel = ValueChanged; });
},
create a GestureDetecture and put the ListWheelScrollView inside:
GestureDetector(
child: ListWheelScrollView(...
create onTap function at the GestureDetecture like this code:
// this is necessary
if (_vIndiceWheel == null) {
_vIndiceWheel = 0;
}
switch (_vIndiceWheel) {
case 0:
{
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return YourSecondScreen();
},
...
When I'm, not using the ListView.builder constructor in Flutter, the individual item is shown as expected from the JSON API:
when I use ListView.builder, nothing shows up. no Error!
I also tried a listview with Texts only that doesn't seem to work either.
Here's the code:
#override
Widget build(BuildContext context) {
return Container(
child: new Scaffold(
appBar: AppBar(
title: Text("the title"),//TODO edit this
backgroundColor: Colors.blueAccent),
body:
Column(
children: <Widget>[
FutureBuilder<List<dynamic>>(
future: getPosts2(),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? ListViewPosts(postsFrom: snapshot.data)
: Center(child: CircularProgressIndicator());
},
),
],
),
),
);
}
}
And here is the ListViewPosts Stateless Widget:
class ListViewPosts extends
StatelessWidget {
final List<dynamic> postsFrom;
ListViewPosts({Key key,
this.postsFrom}) : super(key: key);
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
FadeInImage.assetNetwork(
placeholder: 'assets/images/placeholder.png',
image: postsFrom[1]["featured_media"] == 0
? 'assets/images/placeholder.png'
: postsFrom[1]["_embedded"]["wp:featuredmedia"]
[0]["source_url"],
),
FadeInImage.assetNetwork(
placeholder: 'assets/images/placeholder.png',
image: postsFrom[2]["featured_media"] == 0
? 'assets/images/placeholder.png'
: postsFrom[2]["_embedded"]["wp:featuredmedia"]
[0]["source_url"],
),
new Row(
children: <Widget>[
Expanded(
child: Text(
"نووسهر: " +
postsFrom[1]["_embedded"]["author"][0]
["name"],
textAlign: TextAlign.right,
),
),
Expanded(
child: Text(
dateConvertor(
postsFrom[2]["date"].toString()),
textAlign: TextAlign.left,
),
),
],
),
ListView.builder(
itemCount: postsFrom.length, //== null ? 0 : postsFrom.length,
itemBuilder: (context, int index) {
Card(
child: Column(
children: <Widget>[
Text(postsFrom.toString()),
Container(
child: hawalImage(postsFrom, index),
),
new Padding(
padding: EdgeInsets.all(5.0),
child: new ListTile(
title: new Text("whatEver"),
subtitle: new Row(
children: <Widget>[
Expanded(
child: new Text(postsFrom[index]["title"]["rendered"]),
),
Expanded(
child: hawalDate(postsFrom, index),
),
],
),
),
),
new ButtonTheme.bar(
child: hawalBtnBar(),
),
],
),
);
},
),
You have to write return Card at the beginning of the curly brackets in the builder function. Also I would be cautious with using Expanded there, it might cause some errors.
Also you put a ListView inside a Column without defining it's height, so it will take up space indefinitely. Wrap it in a widget that provides height constraints(SizedBox, Expanded, ...)
Inside the Listview.builder() you could try to add the property shrinkWrap: true.
This worked for me. I was facing a similar issue.
Use with Expanded. Hopefully, it will solve your problem.
You have to write return Card at the beginning of the curly brackets in the builder function. Also I would be cautious with using Expanded there, it might cause some errors.