sliver
- SingleChildScrollView
//单一child
SingleChildScrollView(
//指定方向,默认竖直
scrollDirection: Axis.horizontal,
//需滚动的child
child: Text('超级多的文字,超级多的文字' * 1000, softWrap: true),
),
- ListView
直接显示 ,children: Widget 数组
List<String> _list = ['1', '2', '3', '4'];
ListView(
children: <Widget>[
Text(_list[0]),
Text(_list[1]),
Text(_list[2]),
Text(_list[3]),
],
),
ListView(
children: _list
.map((s) => ListTile(
title: Text(s),
))
.toList(),
),
ListView(
//List<Widget>
children: List.generate(
_list.length,
(index) => ListTile(
title: Text(_list[index]),
)
),
),
ListView.builder
以每一个条目的形式展示
itemBuilder:(context,index)=>
List<String> _list = ['1', '2', '3', '4'];
ListView.builder(
//(context, index)=>widget
itemBuilder: (context, index) => ListTile(
title: Text(_list[index]),
),
//指定item的高度
itemExtent: 50.0,
itemCount: _list.length,
),
ListView.custom 代理
//设置ListView整体代理
ListView.custom(
childrenDelegate: SliverChildListDelegate(
//List<Widget>
List.generate(
_list.length,
(index) => ListTile(
title: Text(_list[index]),
),
),
),
),
//设置条目代理,注意,需指定childCount,否则会出现越界
ListView.custom(
childrenDelegate: SliverChildBuilderDelegate(
//(context,index) => widget
(context, index) => ListTile(
title: Text(_list[index]),
),
childCount: _list.length,
),
),
ListView.separated 添加分割线
List<String> _list = ['1', '2', '3', '4'];
ListView.separated(
itemBuilder: (context, index) => ListTile(
title: Text(_list[index]),
),
separatorBuilder: (context, index) => Padding(
child: Divider(
color: Colors.grey,
height: 0.5,
),
padding: const EdgeInsets.symmetric(horizontal: 16.0),
),
itemCount: _list.length),
ExpansionTile 可展开的列表
//单个
ExpansionTile(
leading: Icon(Icons.add),
trailing: Icon(Icons.delete),
//展开之后的颜色
backgroundColor: Colors.red,
onExpansionChanged: (expand) {
if (expand) {
print("expand:展开啦");
} else {
print("expand:合住啦");
}
},
//true:默认是展开 false:默认是关闭
initiallyExpanded: true,
title: Text('标题'),
children: List.generate(
_list.length,
(index) => ListTile(
title: Text(_list[index]),
),
),
),
//多个
@override
Widget build(BuildContext context) {
Widget getChild() {
return ExpansionTile(
leading: Icon(Icons.add),
trailing: Icon(Icons.delete),
//展开之后的颜色
backgroundColor: Colors.red,
onExpansionChanged: (expand) {
if (expand) {
print("expand:展开啦");
} else {
print("expand:合住啦");
}
},
//true:默认是展开 false:默认是关闭
initiallyExpanded: true,
title: Text('标题'),
children: List.generate(
_list.length,
(index) => ListTile(
title: Text(_list[index]),
),
),
);
}
return SafeArea(
child: Scaffold(
body: ListView.builder(
itemBuilder: (context, index) => getChild(),
itemCount: _list.length,
),
),
);
}
- GridView
//gridDelegate 限定个数
GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//单行的个数
crossAxisCount: 5,
//主轴间距
mainAxisSpacing: 10,
//相对轴间距
crossAxisSpacing: 20,
//宽高比
childAspectRatio: 1),
children: List.generate(
_list.length,
(index) => Container(
color: Colors.yellow,
alignment: Alignment.center,
child: Text(_list[index]),
),
),
),
//gridDelegate 限定宽度
GridView(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
//单个cell的最大宽度(只是一个约数,举例
//500 占据屏幕宽度比一半大,又比全屏小,则会计算一排显示两个
//600 比全屏大,则一排显示1个 )
maxCrossAxisExtent: 500,
//主轴间距
mainAxisSpacing: 10,
//相对轴间距
crossAxisSpacing: 20,
//宽高比
childAspectRatio: 1),
children: List.generate(
_list.length,
(index) => Container(
color: Colors.yellow,
alignment: Alignment.center,
child: Text(_list[index]),
),
),
),
//GridView.builder 注意需要提供itemCount,否则如果列表太短,占不满一屏,则会报越界错误
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5,
childAspectRatio: 1,
crossAxisSpacing: 10,
mainAxisSpacing: 10),
itemBuilder: (context, index) => Container(
child: Text(_list[index]),
color: Colors.yellow,
alignment: Alignment.center,
),
itemCount: _list.length,
),
GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 100,
childAspectRatio: 1,
crossAxisSpacing: 10,
mainAxisSpacing: 10),
itemBuilder: (context, index) => Container(
child: Text(_list[index]),
color: Colors.yellow,
alignment: Alignment.center,
),
itemCount: _list.length,
),
GridView.count(
crossAxisCount: 4,
crossAxisSpacing: 20,
mainAxisSpacing: 10,
childAspectRatio: 2.0,
children: List.generate(
_list.length,
(index) => Container(
color: Colors.greenAccent,
alignment: Alignment.center,
child: Text(_list[index]),
),
),
),
GridView.extent(
maxCrossAxisExtent: 200,
crossAxisSpacing: 20,
mainAxisSpacing: 10,
childAspectRatio: 2.0,
children: List.generate(
_list.length,
(index) => Container(
color: Colors.greenAccent,
alignment: Alignment.center,
child: Text(_list[index]),
),
),
),
GridView.custom
GridView.custom(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
childAspectRatio: 1,
mainAxisSpacing: 10,
crossAxisSpacing: 10),
childrenDelegate: SliverChildListDelegate(
List.generate(
_list.length,
(index) => Container(
child: Text(_list[index]),
color: Colors.greenAccent,
alignment: Alignment.center,
),
),
),
),
GridView.custom(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
childAspectRatio: 1,
mainAxisSpacing: 10,
crossAxisSpacing: 10),
childrenDelegate: SliverChildBuilderDelegate(
(context, index) => Container(
alignment: Alignment.center,
color: Colors.greenAccent,
child: Text(_list[index]),
),
childCount: _list.length,
),
),
CustomScrollView 滑动粘合剂
List<String> _list = ['1','2','3','4','5','6','7','8','9',];
List<String> _list1 = ['a','b','c','d','e','f','g','h','j','1','2','3',];
Widget getListItem(int index) {
return ListTile(
title: Text(_list1[index]),
);
}
Widget getGridItem(int index) {
return Container(
child: Text(_list[index]),
color: Colors.greenAccent,
alignment: Alignment.center,
);
}
CustomScrollView(
slivers: <Widget>[
SliverGrid(
delegate: SliverChildBuilderDelegate(
(context, index) => getGridItem(index),
childCount: _list.length,
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 1),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => getListItem(index),
childCount: _list1.length,
),
),
],
),
添加滑动返回
ScrollController _scrollController;
@override
void initState() {
_scrollController = ScrollController();
super.initState();
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
Scaffold(
body: CustomScrollView(
controller: _scrollController,
physics: BouncingScrollPhysics(),
slivers: <Widget>[
SliverGrid(
delegate: SliverChildBuilderDelegate(
(context, index) => getGridItem(index),
childCount: _list.length,
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 1),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(_, index) => getListItem(index),
childCount: _list1.length,
),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_scrollController.animateTo(0.0,
duration: Duration(milliseconds: 100),
curve: Curves.decelerate);
},
child: Icon(Icons.add),
backgroundColor: Colors.greenAccent,
),
),
- SliverAppBar
SliverAppBar(
expandedHeight: 250,
backgroundColor: Colors.yellow,
leading: Icon(Icons.add),
centerTitle: true,
title: Text('这里是标题'),
//floating/snap 下滑时滑动到一定比例,开始滑动SliverAppBar,直至
//SliverAppBar全部滑出时,下部分才能继续滑动
floating: true,
//必须配置floating属性为false,否则报错,添加为true的时候,SliverAppBar出
//现一部分,则会根据向上滑或向下滑,弹出剩下部分
snap: true,
//title 是否会保留 true:保留,false不保留
pinned: true,
flexibleSpace: FlexibleSpaceBar(
//随着背景移动的标题
title: Text('这是什么标题'),
collapseMode: CollapseMode.parallax,
background: Image.asset(
"images/homepage_title.jpg",
fit: BoxFit.cover,
),
),
),
//占据一屏的位置
SliverFillRemaining(
child: Center(
child: Text('这个?'),
),
),