课程名称:Flutter从入门到进阶 实战携程网App 一网打尽核心技术
课程章节:Flutter进阶提升:玩转列表组件
课程讲师:CrazyCodeBoy
课程内容
1.基于 ListView 实现水平和垂直方向滚动的列表
- Flutter 中通过列表组件 ListView 实现 UI 上列表的展示效果;
- ListView 默认的滚动方向是垂直方向,可以通过ListView 的scrollDirection 属性进行修改;
- ListView 的children 属性接收 List 类型数据;
ListView属性介绍:
ListView({
Axis scrollDirection = Axis.vertical, //列表滚动方向,默认为垂直方向
ScrollController controller, //控制器,与列表滚动相关,比如监听列表的滚动事件
ScrollPhysics physics, //列表滚动至边缘后继续拖动的物理效果,Android与iOS效果不同。Android会呈、现出一个波纹状(对应ClampingScrollPhysics),而iOS上有一个回弹的弹性效果(对应BouncingScrollPhysics)。
bool shrinkWrap = false, //该属性将决定列表的长度是否仅包裹其内容的长度。
EdgeInsetsGeometry padding, //列表内边距
this.itemExtent, //子元素长度
double cacheExtent, //预渲染区域长度
List<Widget> children = const <Widget>[], //容纳子元素的组件数组
})
示例代码:
void main() => runApp(MyApp());
const CITY_NAMES = [ '北京', '上海', '广州', '深圳', '杭州', '苏州', '成都', '武汉', '郑州', '洛阳', '厦门', '青岛', '拉萨' ];
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final title = '水平';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Container(
height: 200,
child: ListView(
scrollDirection: Axis.horizontal,
children: _buildList(),
),
),
),
);
}
List<Widget> _buildList() {
return CITY_NAMES.map((city) => _item(city)).toList();
}
Widget _item(String city) {
return Container(
width: 160,
margin: EdgeInsets.only(right: 5),
alignment: Alignment.center,
decoration: BoxDecoration(color: Colors.teal),
child: Text(
city,
style: TextStyle(color: Colors.white, fontSize: 20),
),
);
}
}
2.基于ExpansionTile实现可展开的列表
- Flutter 中的可折叠列表通过 ExpansionTile 实现;
- ExpansionTile 要求的数据格式是二维列表;
ExpansionTile 属性介绍:
const ExpansionTile({
Key key,
this.leading, //标题左侧要展示的widget
@required this.title, //要展示的标题widget
this.backgroundColor, //背景
this.onExpansionChanged, //列表展开收起的回调函数
this.children = const <Widget>[], //列表展开时显示的widget
this.trailing, //标题右侧要展示的widget
this.initiallyExpanded = false, //是否默认状态下展开
})
3.基于GridView实现网格布局
GridView 和 ListView 两者都继承自BoxScrollView,所以两者的属性大部分是相同的,用法也相似。
GridView 属性介绍:
GridView({
Key key,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller,
ScrollPhysics physics,
bool shrinkWrap = false,
EdgeInsetsGeometry padding,
@required this.gridDelegate,
double cacheExtent,
List<Widget> children = const <Widget>[],
})
除了一个必填参数gridDelegate外,全和ListView默认构造函数的参数一样。gridDelegate是GridView组件如何控制排列子元素的一个委托。gridDelegate的类型是SliverGridDelegate。SliverGridDelegate其实是一个抽象类,而且一共有两个实现类:
- SliverGridDelegateWithFixedCrossAxisCount 用于固定列数的场景;
- SliverGridDelegateWithMaxCrossAxisExtent 用于子元素有最大宽度限制的场景;
4.下拉刷新与上拉加载更多功能的实现
将ListView包裹在RefreshIndicator中,可实现列表下拉刷新的效果。
RefreshIndicator 属性介绍:
const RefreshIndicator({
Key key,
@required this.child,
this.displacement: 40.0, //触发下拉刷新的距离
@required this.onRefresh, //下拉回调方法,方法需要有async和await关键字,没有await,刷新图标立马消失,没有async,刷新图标不会消失
this.color, //进度指示器前景色 默认为系统主题色
this.backgroundColor, //背景色
this.notificationPredicate: defaultScrollNotificationPredicate,
})
为了给列表添加上了加载更多的功能,我们可以借助ScrollController,列表支持设置controller参数,通过ScrollController监听列表滚动的位置,来实现加载更多的功能。
示例代码:
class _MyAppState extends State<MyApp> {
ScrollController _scrollController = ScrollController();
@override
void initState() {
_scrollController.addListener(() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
_loadData();
}
});
super.initState();
}
课程总结
这一节介绍了 Flutter 中的列表组件 ListView,Flutter SDK中已经提供了一个RefreshIndicator控件,所以结合RefreshIndicator控件,让其包裹ListView控件,结合滑动监听ScrollController,并且设置头部,尾部加载更多等界面,就可以完成一个通用的下拉刷新,上拉加载更多的通用控件。