ListView是最常用的可滚动组件之一,它可以沿一个方向线性排布所有子组件,并且它也支持列表项懒加载(在需要时才会创建)。
我们看看ListView的默认构造函数定义:
ListView({
...
//可滚动widget公共参数
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController? controller,
bool? primary,
ScrollPhysics? physics,
EdgeInsetsGeometry? padding,
//ListView各个构造函数的共同参数
double? itemExtent, // 该参数如果不为null,则会强制children的“长度”为itemExtent的
Widget? prototypeItem, //通知list 我所有的子项都和这个的高度一样 ,方便计算
//该属性表示是否根据子组件的总长度来设置ListView的长度
//当ListView在一个无边界(滚动方向上)的容器中时,shrinkWrap必须为true。
bool shrinkWrap = false,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
double? cacheExtent, // 预渲染区域长度
//子widget列表
List<Widget> children = const <Widget>[],
})
// 一个简单的listView
class ListViewState1 extends StatelessWidget{
Widget build(BuildContext context) {
// TODO: implement build
return ListView(
shrinkWrap: true,
padding: EdgeInsets.all(20),
children: const <Widget>[
Text('Im dedicating every day to you',style: TextStyle(height: 2),),
Text('Domestic life was never quite my style',style: TextStyle(height: 2),),
Text('When you smile, you knock me out, I fall apart',style: TextStyle(height: 2),),
Text('And I thought I was so smart',style: TextStyle(height: 2),),
Text('Im dedicating every day to you',style: TextStyle(height: 2),),
Text('Domestic life was never quite my style',style: TextStyle(height: 2),),
Text('When you smile, you knock me out, I fall apart',style: TextStyle(height: 2),),
Text('And I thought I was so smart',style: TextStyle(height: 2),),
Text('Im dedicating every day to you',style: TextStyle(height: 2),),
Text('Domestic life was never quite my style',style: TextStyle(height: 2),),
Text('When you smile, you knock me out, I fall apart',style: TextStyle(height: 2),),
Text('And I thought I was so smart',style: TextStyle(height: 2),),
],
);
}
}
ListView.builder 适合列表项比较多或者列表项不确定的情况
itemBuilder:它是列表项的构建器
itemCount:列表项的数量,如果为null,则为无限列表。
// ListView.builder + prototypeItem + itemCount 展示
// ListTile 一个 简单的组件
class ListViewState3 extends StatelessWidget{
Widget build(BuildContext context) {
// TODO: implement build
return ListView.builder(
prototypeItem: ListTile(title: Text("1")),
itemCount: 56,
itemBuilder: (context, index) {
return ListTile(title: Text("$index"));
},
);
}
}
ListView.separated
ListView.separated可以在生成的列表项之间添加一个分割组件,它比ListView.builder多了一个separatorBuilder参数,该参数是一个分割组件生成器。
class ListViewState4 extends StatelessWidget{
//下划线widget预定义以供复用。
Widget divider1=Divider(color: Colors.blue,);
Widget divider2=Divider(color: Colors.green);
List<String> list2 = [
"1","2","3","4","5",
"1","2","3","4","5",
"1","2","3","4","5",
"1","2","3","4","5",
"1","2","3","4","5",
"1","2","3","4","5",
"1","2","3","4","5"];
Widget build(BuildContext context) {
// TODO: implement build
return Scrollbar(child: ListView.separated(
itemCount: list2.length,
itemBuilder: (BuildContext context ,int index){
return ListTile(title: Text(list2[index]));
},
separatorBuilder: (BuildContext context, int index) {
return index%2==0?divider1:divider2;
},
));
}
}
固定高度列表
给列表指定 itemExtent 或 prototypeItem 会有更高的性能,所以当我们知道列表项的高度都相同时,强烈建议指定 itemExtent 或 prototypeItem
实例 : 给一个listview 动态添加数据
1 动态添加需要 State 所有需要构建 StatefulWidget
class MyListViewState0 extends StatefulWidget {
const MyListViewState0({Key? key}) : super(key: key);
State<MyListViewState0> createState() => _MyState0();
}
class _MyState0 extends State<MyListViewState0> {
// 初始化 数据源
List<String> list2 = [
"1","2","3","4","5",
"1","2","3","4","5",
"1","2","3","4","5",
"1","2","3","4","5",
"1","2","3","4","5",
"1","2","3","4","5",
"1","2","3","4","5"];
Widget build(BuildContext context) {
return ConstrainedBox(
constraints: BoxConstraints.tightFor(width: double.infinity),
child: Column(
children: <Widget>[
ElevatedButton(onPressed: (){
// 刷新state
setState(() {
//点击按钮时 itemss 自加一
itemss ++ ;
// 添加到数据中
list2.insert(0, "-----------$itemss");
});
}, child: Text("点击1")),
Expanded(child: ListViewState2(list2))
],
)
);
}
}
class ListViewState2 extends StatelessWidget{
List<String> list = [] ;
ListViewState2(List<String> item,{Key? key}) : super(key: key){
list = item ;
}
Widget build(BuildContext context) {
// TODO: implement build
return Scrollbar(child: ListView.builder(
itemCount: list.length,
itemExtent: 50,
itemBuilder: (BuildContext context ,int index){
return Text(list[index]);
}
));
}
}