1.ListView实现列表布局(类似RecyclerView水平/垂直模式):
(1)实现列表布局:
方式1(推荐,适用大量item,动态创建item):
ListView.builder( //列表布局
scrollDirection: Axis.vertical, //(默认)vertical垂直排列,horizontal水平排列
itemCount: 总个数, //item总个数
itemExtent: 高度值, //item高度(vertical)或宽度(horizontal)
itemBuilder: (BuildContext context, int index) { //列表滚动到index位置时,才构建此item
return item布局;
}
)
方式2(效果同方式2,item间添加分割线):
ListView.separated( //列表布局
... //省略其他相同属性
itemCount: 总个数, //item总个数
itemBuilder: (BuildContext context, int index) { //列表滚动到index位置时,才构建此item
return item布局;
}
separatorBuilder: (BuildContext context, int index) { //分割器构造器
return Divider(color: Colors.black); //Divider为分割线
}
}
方式3(适用少量item):
ListView( //列表布局
scrollDirection: Axis.vertical, //(默认)vertical垂直排列,horizontal水平排列
itemExtent: 高度值, //item高度(vertical)或宽度(horizontal)
//prototypeItem: 高度值, //效果等同itemExtent,与itemExtent互斥
shrinkWrap: false, //true时累加item总长度并设置ListView长度,(默认)false占用最大空间
children: <Widget>[ //item布局列表,提前将所有item构建好
...
]
)
(2)监听滚动事件、滚动到指定位置:
//定义到State类全局变量
ScrollController scrollController = ScrollController();
...
//在initState方法中监听滚动事件
scrollController.addListener(() {
//...处理滚动事件
});
...
//动画滚动到指定位置
scrollController.animateTo(指定位置, duration: Duration(milliseconds: 动画时长), curve: Curves.ease); //curve为动画曲线
//跳转到指定位置
scrollController.jumpTo(指定位置);
...
//在dispose方法中释放,避免内存泄露
scrollController.dispose();
(3)监听滚动通知:
NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) {
double progress = notification.metrics.pixels / notification.metrics.maxScrollExtent;
int rate = (progress * 100).toInt(); //实际进度值0-100
return false; //返回false
},
child: ListView.builder( //child内得有ListView
...
)
)
2.AnimatedList实现列表布局(类似ListView,支持添加/删除):
(1)实现列表布局:
final listKey = GlobalKey<AnimatedListState>(); //定义全局状态
...
AnimatedList( //列表布局
key: listKey, //传入全局状态变量,添加/删除时用到
initialItemCount: 总个数,
itemBuilder: ( //构建item布局
BuildContext context,
int index,
Animation<double> animation,
) {
// return item布局; //直接返回item布局,在添加时没有动效
return FadeTransition( //使用动画类(此处为渐隐)包装item布局,在添加时有动效
opacity: animation,
child: ..., //省略item布局
);
},
)
(2)添加/删除item:
//新增item
listKey.currentState!.insertItem(
item的index,
duration: Duration(milliseconds: 500)); //动画持续时间
...
//删除item
listKey.currentState!.removeItem(
item的index,
(context, animation) { //删除动画实现
// return item布局; //直接返回item布局,在删除时没有动效
return FadeTransition( //使用动画类(此处为渐隐+缩小)包装item布局,在删除时有动效
opacity: animation,
child: SizeTransition( //缩小删除item的高度
sizeFactor: animation,
axisAlignment: 0.0,
child: item布局,
),
);
},
duration: Duration(milliseconds: 500), //动画持续时间
);
3.GridView实现网格布局(类似Android的GridView)
(1)实现列表布局:
方式1(推荐,适用大量item,动态构建item):
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4, //水平方向子元素个数
childAspectRatio: 1.0, //子元素宽高比
),
itemCount: 元素总个数,
itemBuilder: (context, index) { //构建item布局,列表滚动到index位置时,才构建此item
return item布局;
}
)
方式2(指定子元素个数,适用少量item):
GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
mainAxisSpacing: 10.0, //垂直方向子元素的间距
crossAxisSpacing: 10.0, //水平方向子元素的间距
crossAxisCount: 4, //水平方向子元素个数
childAspectRatio: 1.0 //子元素宽高比
),
children: <Widget>[ //item布局列表,提前将所有item构建好
...
]
);
方式3(指定子元素个数,适用少量item):
GridView.count(
crossAxisCount: 4, //水平方向子元素个数
childAspectRatio: 1.0 //子元素宽高比
children: <Widget>[ //item布局列表,提前将所有item构建好
...
]
);
方式4(指定子元素最大长度,适用少量item):
GridView(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
mainAxisSpacing: 10.0, //垂直方向子元素的间距
crossAxisSpacing: 10.0, //水平方向子元素的间距
maxCrossAxisExtent: 100.0,//子元素在水平方向最大长度
childAspectRatio: 1.0 //子元素宽高比
),
children: <Widget>[ //item布局列表,提前将所有item构建好
...
]
)
方式5(指定子元素最大长度,适用少量item):
GridView.extent(
maxCrossAxisExtent: 100.0, //子元素在水平方向最大长度
childAspectRatio: 1.0 //子元素宽高比
children: <Widget>[ //item布局列表,提前将所有item构建好
...
]
)
4.CustomScrollView嵌套多个Sliver组件(滚动事件不冲突):
说明:
常见的非列表Sliver组件:
SliverAppBar(AppBar)、SliverToBoxAdapter、SliverPersistentHeader(滑动到顶部固定)
常见的列表Sliver组件:
SliverList(ListView)、
SliverFixedExtentList(ListView item高度固定)、SliverAnimatedList(添加/删除item时有动画)、SliverGrid、
SliverPrototypeExtentList(ListView指定prototypeItem)、SliverFillViewport(PageView)
CustomScrollView(
slivers: [ //Sliver组件列表
..., //Sliver组件1
..., //Sliver组件2
]
)
5.NestedScrollView嵌套两个可滚动Widget(滚动事件不冲突):
NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[ //sliver组件列表,
sliver组件(...) //例如SliverAppBar
];
},
body: 列表组件, //列表Widget,例如ListView
);