问题
How can I decrease the size of items using the ListView.builder
I already tried to tinker with everything in ItemCategory
but the size remains the same.
Using the ListView the size is the smallest good according to this images below:
Using the Flutter - Strange ListView behavior after refresh code the items are well-sized, but by changing the ListView
toListView.builder
the size changes completely and the ItemCategory
class is the same
without ListView.builder
with ListView.builder
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 = [];
List lista2DB = [];
List listaCategory;
final List<Widget> children = <Widget>[];
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'}]
];
for(var i in this.listaDB) {
var category = i[0]['category'];
children.add(
new ItemCategory(
key: new Key(randomString(20)),
category: category,
)
);
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Categories'),
backgroundColor: blueAppBar,
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.refresh),
onPressed: () {
setState(() {
children.clear();
for(var i in this.lista2DB) {
var category = i[0]['category'];
children.add(
new ItemCategory(
key: new Key(randomString(20)),
category: category,
)
);
}
});
},
)
],
),
body: new ListView.builder(
itemBuilder: (BuildContext context, int index) => children[index],
itemExtent: 128.0,
itemCount: children.length,
),
);
}
}
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),
],
)
)
],
),
)
],
),
);
}
}
回答1:
To work with the correct size simply change the value itemExtent: 128.0
to a smaller number such asitemExtent: 46.0
That defines the size of each child, you can remove it and the builder will calculate the size for each item based on its dimensions. Removing itemExtent
to be automatically calculate.
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.builder(
key: new Key(randomString(20)), //new
itemBuilder: (BuildContext context, int index) => children[index],
//itemExtent: 128.0,
itemCount: children.length,
),
By making this change the list is mounted correctly.
回答2:
Its good practice when we use itemExtent
because
Specifying an [itemExtent] is more efficient than letting the children determine their own extent because the scrolling machinery can make use of the foreknowledge of the children's extent to save work, for example, when the scroll position changes drastically.
So, when we declare any value for itemExtent
it will help Listview to render fastly, as now calculation of height among widget is not the concern. Hence static height works in this case.
来源:https://stackoverflow.com/questions/48673795/flutter-listview-builder-with-very-large-size-and-does-not-change