Reputation: 13304
Could they help me solve and understand why ListView
's strange behavior after a refresh?
In the example below I created a list with 24 elements and I go to the last item in the list and tap the icone refresh that will update the list. Only after the update does the ListView
no longer show all elements.
And to ensure each element always has a different Key through the randomString
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new CategoryPage(),
);
}
}
class CategoryPage extends StatefulWidget {
@override
CategoryPageState createState() => new CategoryPageState();
}
class CategoryPageState extends State<CategoryPage> {
Color blueAppBar = new Color(0xFF26C6DA);
List<Widget> listCategories = [];
List listaDB = [];
var listaCategory;
String randomString(int length) {
var rand = new Random();
var codeUnits = new List.generate(
length,
(index){
return rand.nextInt(33)+89;
}
);
return new String.fromCharCodes(codeUnits);
}
@override
void initState() {
this.listaDB =
[
[{'category': 'foo01'}],
[{'category': 'foo02'}],
[{'category': 'foo03'}],
[{'category': 'foo04'}],
[{'category': 'foo05'}],
[{'category': 'foo06'}],
[{'category': 'foo07'}],
[{'category': 'foo08'}],
[{'category': 'foo09'}],
[{'category': 'foo10'}],
[{'category': 'foo11'}],
[{'category': 'foo12'}],
[{'category': 'foo13'}],
[{'category': 'foo14'}],
[{'category': 'foo15'}],
[{'category': 'foo16'}],
[{'category': 'foo17'}],
[{'category': 'foo18'}],
[{'category': 'foo19'}],
[{'category': 'foo20'}],
[{'category': 'foo21'}],
[{'category': 'foo22'}],
[{'category': 'foo23'}],
[{'category': 'foo24'}]
];
}
@override
Widget build(BuildContext context) {
List<Widget> buildListCategories(List list) {
this.listCategories = [];
for(var i in list) {
var category = i[0]['category'];
this.listCategories.add(
new ItemCategory(
key: new Key(randomString(20)),
category: category,
)
);
}
return this.listCategories;
}
this.listaCategory = buildListCategories(this.listaDB);
return new Scaffold(
appBar: new AppBar(
title: new Text('Categories'),
backgroundColor: blueAppBar,
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.refresh),
onPressed: () {
setState(() {
this.listaCategory = buildListCategories(this.listaDB);
});
},
)
],
),
body: new ListView(
padding: new EdgeInsets.only(top: 8.0, right: 0.0, left: 0.0),
children: this.listaCategory
),
);
}
}
class ItemCategory extends StatelessWidget {
final String category;
ItemCategory({
Key key,
this.category}) : super(key: key);
@override
Widget build(BuildContext context) {
return new Container(
decoration: new BoxDecoration(
border: new Border(
top: new BorderSide(style: BorderStyle.solid, color: Colors.black26),
),
color: new Color(0xFFFAFAFA),
),
margin: new EdgeInsets.only(top: 0.0, bottom: 0.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Expanded(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Container(
margin: new EdgeInsets.only(left: 16.0),
padding: new EdgeInsets.only(right: 40.0, top: 4.5, bottom: 4.5),
child: new Row(
children: <Widget>[
new Container(
margin: new EdgeInsets.only(right: 16.0),
child: new Icon(
Icons.brightness_1,
color: Colors.black,
size: 35.0,
),
),
new Text(this.category),
],
)
)
],
),
)
],
),
);
}
}
Upvotes: 1
Views: 2334
Reputation: 13304
Since the problem is in the key
, the ListView
also needs a key
, because when updating to another list, if each list does not have its own key
the list is mounted in the wrong way.
The ListView
code should look like this:
body: new ListView(
key: new Key(randomString(20)), //new
padding: new EdgeInsets.only(top: 8.0, right: 0.0, left: 0.0),
children: this.listaCategory
),
By making this change the list is mounted correctly.
Upvotes: 2
Reputation: 1047
You still call buildListCategories twice if you push the button (in the setState and in the build method), but that is not the problem. Also I would not nest the methods. Apparently something goes wrong with the key. If you don't set the key everything is fine. I am not sure why that breaks the listview, but I also don't think it adds anything.
I made a gist with the fixed code: https://gist.github.com/renefloor/0fed1bbd43567b45ed2605f57ecce29f
Upvotes: 1