ListView
构造方法
ListView()
适合数量少的,一下子全部创建出来
return ListView(
children: [
ListTile( // 类似于 UITableViewCell
leading: Icon(Icons.people),
title: Text("Title - "),
subtitle: Text("Subtitle"),
trailing: Icon(Icons.delete),
onTap: () { //点击方法
print('sss');
},
),
Divider(
height: 0.5,
thickness: 0.5,
),
ListTile(
leading: Icon(Icons.people),
title: Text("Title - "),
subtitle: Text("Subtitle"),
trailing: Icon(Icons.delete),
),
Divider(
height: 0.5,
thickness: 0.5,
),
ListTile(
leading: Icon(Icons.people),
title: Text("Title - "),
subtitle: Text("Subtitle"),
trailing: Icon(Icons.delete),
),
Divider(
height: 0.5,
thickness: 0.5,
),
ListTile(
leading: Icon(Icons.people),
title: Text("Title - "),
subtitle: Text("Subtitle"),
trailing: Icon(Icons.delete),
),
Divider(
height: 0.5,
thickness: 0.5,
),
],
);
ListView.builder
动态创建,视图可见时创建,可以设置行高
return ListView.builder(
itemExtent: 50, //行高
itemCount: 100, //item 个数
itemBuilder: (BuildContext cxt, int index) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text("text:$index"),
Text("ssss"),
Divider(
height: 0.5,
thickness: 0.5,
color: Colors.red,
),
],
);
});
ListView.separated
相对于 ListView.builder 多了分割线, 目前看是自动计算行高
return ListView.separated(
itemBuilder: (BuildContext ct, int index) {
return ListTile(
leading: Icon(Icons.people),
title: Text("Title - $index"),
subtitle: Text("Subtitle"),
trailing: Icon(Icons.delete),
onTap: () {
print('点击了 - 第$index行');
},
);
},
// 分割线对象
separatorBuilder: (BuildContext ct, int index) {
return Divider(//可以直接 Divider()
height: 0.5,//分割线占据的高度
thickness: 0.5,//分割线高度
);
},
itemCount: 100);
GridView
构造方法
GridView.count
和 ListView() 构造方法一样,适合小数量的,一下子全部加载出来
return GridView.count(
mainAxisSpacing: 8,//主轴间距
crossAxisSpacing: 8,//交叉轴间距
primary: false,
crossAxisCount: 4,//交叉轴 item 个数
children: [
Container(
child: Text("sss"),
// color: Color.fromRGBO(Random().nextInt(256), Random().nextInt(256),
// Random().nextInt(256), 1)
color: Color.fromARGB(Random().nextInt(256), Random().nextInt(256),
Random().nextInt(256), Random().nextInt(256)),
),
Container(
child: Text("sss"),
color: Color.fromRGBO(Random().nextInt(256), Random().nextInt(256),
Random().nextInt(256), 1)),
Container(
child: Text("sss"),
color: Color.fromRGBO(Random().nextInt(256), Random().nextInt(256),
Random().nextInt(256), 1)),
Container(
child: Text("sss"),
color: Color.fromRGBO(Random().nextInt(256), Random().nextInt(256),
Random().nextInt(256), 1)),
Container(
child: Text("sss"),
color: Color.fromRGBO(Random().nextInt(256), Random().nextInt(256),
Random().nextInt(256), 1)),
Container(
child: Text("sss"),
color: Color.fromRGBO(Random().nextInt(256), Random().nextInt(256),
Random().nextInt(256), 1)),
],
);
GridView.builder
必须实现 gridDelegate 代理方法,又有两个代理方法可选
固定交叉轴 item 个数
- SliverGridDelegateWithFixedCrossAxisCount 交叉轴 item 最大宽度
- SliverGridDelegateWithMaxCrossAxisExtent
return GridView.builder(
itemCount: 100,
//交叉轴固定 item 个数
// gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// crossAxisCount: 2, //交叉轴的 item 个数
// mainAxisSpacing: 8, //上下
// crossAxisSpacing: 8, //左右
// childAspectRatio: 1.0),
//交叉轴 item 最大宽度
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 100, //交叉轴的item 最大宽度
mainAxisExtent: 100),
itemBuilder: (BuildContext cxt, int index) {
return Container(
child: Center(
child: Text("$index"),
),
color: Color.fromARGB(Random().nextInt(256), Random().nextInt(256),
Random().nextInt(256), Random().nextInt(256)),
);
});
Slivers
我们通常把 Slivers 放在一个 CustomScrollView 里面, CustomScrollView有一个属性slivers, 里面放一些 sliver (切片)
Sliver 通常翻译为裂片,薄片,你可以将每一个独立的滚动视图当做一个 sliver 有下面几种 sliver:
- SliverList: 就是之前使用的 ListView
- SliverGrad: 就是之前使用的 GridView
- SliverPadding: 设置 Sliver的内边距, 滚动的时候内边距可以跟着滚动
- SliverAppBar: 添加一个 AppBar, 通常用来作为 CustomScrollView 的 HeaderView
- SliverSafeArea: 设置内容显示在安全区域
SliverAppBar
SliverAppBar(
pinned: true, // nav 是否固定
expandedHeight: 200, //最小就是nav 高度44 大的话下拉文字会跟着变大
flexibleSpace: FlexibleSpaceBar(
title: Text("Joho - SliverAppBar"),
background: Image.asset(
"images/snow.jpeg",
fit: BoxFit.cover,
),
),
),
SliverList
child: CustomScrollView(
//slivers == children
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext cxt, int index) {
return ListTile(
leading: Icon(Icons.people),
title: Text("联系人: $index"),
);
},
childCount: 100,
),
)
],
),
SliverGrid
SliverGrid(
delegate: SliverChildBuilderDelegate((BuildContext ct, int index){
return Container(
color: Color.fromRGBO(Random().nextInt(256),
Random().nextInt(256), Random().nextInt(256), 1),
child: Text("Grid - $index"),
);},
childCount: 10),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 8,
crossAxisSpacing: 8
)
),
监听滚动
ScrollController
- 监听滚动,但不知道何时开始滚动
- 增加监听:controller.addListener
- 当前偏移量:controller.offset
- 回到顶部
_controller.animateTo(0,duration:Duration(seconds:1),curve:Curves.ease);
ScrollController _controller = ScrollController();
@override
void initState() {
super.initState();
_controller.addListener(() { //添加监听
print("${_controller.offset}");
});
}
CustomScrollView(
//scrollview 绑定 controller
controller: _controller,
)
//滚动
_controller.animateTo(0,
duration: Duration(seconds: 1), curve: Curves.ease);
NotificationListener
可以监听滚动状态
- ScrollStartNotification 开始滚动
- ScrollUpdateNotification 正在滚动
- ScrollEndNotification 滚动结束
滚动距离
- 当前滚动距离:notifation.metrics.pixels
- 总共滚动长度:notifation.metrics.maxScrollExtent
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Joho'),
),
body: Container(
child: NotificationListener(
onNotification: (ScrollNotification notifation) {
if (notifation is ScrollStartNotification) {
print("开始滚动...");
} else if (notifation is ScrollUpdateNotification) {
print("正在滚动");
//当前滚动距离
final currentPixel = notifation.metrics.pixels;
//最大长度
final totalPixel = notifation.metrics.maxScrollExtent;
} else if (notifation is ScrollEndNotification) {
print("结束滚动...");
}
return false;
},
child: xxxx,
}
)