ListView介绍
- ListView是最常用的可滚动widget,它可以沿一个方向线性排布所有子widget
- 利用默认的构造函数children参数,传入一个Widget列表(List)创建的ListView实例,如下,这种方式适合只有少量的子widget的情况,因为这种方式需要将所有children都提前创建好(这需要做大量工作),而不是等到子widget真正显示的时候再创建。
ListView(
shrinkWrap: true,
padding: const EdgeInsets.all(10.0),
children: <Widget>[
const Text('ONE'),
const Text('TWO'),
const Text('Three'),
],
);
- ListView.builder适合列表项比较多(或者无限)的情况,因为只有当子Widget真正显示的时候才会被创建,适合动态展现。
- itemBuilder:它是列表项的构建器,类型为IndexedWidgetBuilder,返回值为一个widget。当列表滚动到具体的index位置时,会调用该构建器构建列表项。
- itemCount:列表项的数量,如果为null,则为无限列表。
- ListView.separated可以生成列表项之间的分割器
- 它比ListView.builder多了一个separatorBuilder参数,该参数是一个分割器生成器。如下例子,奇数行添加一条蓝色下划线,偶数行添加一条绿色下划线。
class MallListBuilderSeparatView extends StatelessWidget {
Widget _listItemBuilder(BuildContext context, int index){
return Container(
color: Colors.white,
margin: EdgeInsets.all(4.0),
child: Column(
children: <Widget>[
Image.network(posts[index].imageUrl),
SizedBox(height: 16.0), // 图片下面预留的高度
Text(
posts[index].title,
style:Theme.of(context).textTheme.title
),
Text(
posts[index].author,
style:Theme.of(context).textTheme.subhead
),
],
), // 从上到下排列的容器
);
}
@override
Widget build(BuildContext context) {
//下划线widget预定义以供复用。
Widget divider1=Divider(color: Colors.blue,);
Widget divider2=Divider(color: Colors.green);
return ListView.separated(
itemCount: 3,
//列表项构造器
itemBuilder: _listItemBuilder,
//分割器构造器
separatorBuilder: (BuildContext context, int index) {
return index%2==0?divider1:divider2;
},
);
}
}
构造函数介绍
- scrollDirection 控制滚动方向默认Axis.vertical
- reverse 在滚动方向默认Axis.vertical时 reverse为false时,那么滑动方向就是从上往下。其实此属性本质上是决定可滚动widget的初始滚动位置是在“头”还是“尾”,取false时,初始滚动位置在“头”,反之则在“尾”。
- itemExtent:该参数如果不为null,则会强制children的"长度"为itemExtent的值。
- 这里的"长度"是指滚动方向上子widget的长度,即如果滚动方向是垂直方向,则itemExtent代表子widget的高度,如果滚动方向为水平方向,则itemExtent代表子widget的长度。
- 在ListView中,指定itemExtent比让子widget自己决定自身长度会更高效,这是因为指定itemExtent后,滚动系统可以提前知道列表的长度,而不是总是动态去计算,尤其是在滚动位置频繁变化时(滚动系统需要频繁去计算列表高度)。
列表Demo
import 'package:flutter/material.dart';
import '../mode/fake_post.dart';
// 独立 _listItemBuilder
class MallListView extends StatelessWidget {
Widget _listItemBuilder(BuildContext context, int index){
return Container(
color: Colors.white,
margin: EdgeInsets.all(4.0),
child: Column(
children: <Widget>[
Image.network(posts[index].imageUrl),
SizedBox(height: 16.0), // 图片下面预留的高度
Text(
posts[index].title,
style:Theme.of(context).textTheme.title
),
Text(
posts[index].author,
style:Theme.of(context).textTheme.subhead
),
],
), // 从上到下排列的容器
);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return ListView.builder(
itemCount: posts.length,
itemBuilder: _listItemBuilder,//构建列表视图的项目
); // 创建列表视图;
}
}
main 主文件
import 'package:flutter/material.dart';
import 'mall/mall-listview.dart';
void main() => runApp(App());
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Home(),
theme: ThemeData(
primarySwatch: Colors.blue, // 应用主题颜色
highlightColor: Color.fromRGBO(255, 255, 255, 0.5),// 点击后背景高亮的颜色
splashColor: Colors.white54 // 水波纹yanse
),
);
}
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return DefaultTabController(
length: 3,
child: Scaffold(
body: MallListView()
),
);
}
}
模拟的数据文件 fake_post.dart
class Post {
const Post({
this.title,
this.author,
this.imageUrl,
});
final String title;
final String author;
final String imageUrl;
}
final List<Post> posts = [
Post(
title: 'Apple iphone X',
author: 'JD',
imageUrl: 'https://m.360buyimg.com/babel/jfs/t1/7734/6/15470/209997/5c6fcbc9Ebd1c0f0b/e40b7b0dcac61c54.jpg!q70.jpg'
),
Post(
title: '荣耀V20 胡歌同款 麒麟980',
author: 'JD',
imageUrl: 'https://m.360buyimg.com/babel/jfs/t18157/222/1822300674/231514/6c179af8/5ad87390N086a3c91.jpg!q70.jpg'
),
Post(
title: '小米9 xiaomi新品三摄 ',
author: 'JD',
imageUrl: 'https://m.360buyimg.com/babel/jfs/t1/7734/6/15470/209997/5c6fcbc9Ebd1c0f0b/e40b7b0dcac61c54.jpg!q70.jpg'
)
];