ListView 内部组合了 Scrollable、Viewport 和 Sliver,需要注意:
///
/// ListView 线性列表
class ListViewApp extends StatelessWidget {
const ListViewApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => _ListViewPage();
}
class _ListViewPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ListViewState();
}
class _ListViewState extends State<_ListViewPage> {
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) => MaterialApp(
home: PageView(
children: [
Scaffold(
appBar: AppBar(
title: const Text('这是用构造函数创建的'),
centerTitle: true,
),
body: ListView(
//控件高度
itemExtent: 200,
//横向滚动
scrollDirection: Axis.horizontal,
//分割线包裹
children: ListTile.divideTiles(
color: Colors.black,
context: context,
tiles: [
Container(
margin: const EdgeInsets.only(
left: 10, right: 10, top: 100, bottom: 100),
decoration: ShapeDecoration(
image: const DecorationImage(
image: NetworkImage(
'https://th.bing.com/th/id/OIP.1_lUKm-qhDMmh_zz3fw7EwHaE7?w=284&h=189&c=7&r=0&o=5&dpr=2&pid=1.7'),
fit: BoxFit.cover),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadiusDirectional.circular(20))),
child: const Align(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Text(
"Container decoration实现圆角(radius = 20)",
style: TextStyle(color: Colors.blueAccent),
),
),
alignment: Alignment.bottomCenter,
),
),
Container(
alignment: Alignment.center,
margin: const EdgeInsets.only(
left: 10, right: 10, top: 100, bottom: 100),
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
color: Colors.blueAccent),
padding: const EdgeInsets.all(20),
child: const Text(
'这是文本item',
style: TextStyle(fontSize: 30, color: Colors.white),
),
),
Container(
margin: const EdgeInsets.only(
left: 10, right: 10, top: 100, bottom: 100),
decoration: ShapeDecoration(
image: const DecorationImage(
image: NetworkImage(
'https://th.bing.com/th/id/OIP.1_lUKm-qhDMmh_zz3fw7EwHaE7?w=284&h=189&c=7&r=0&o=5&dpr=2&pid=1.7'),
fit: BoxFit.cover),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadiusDirectional.circular(20))),
width: double.maxFinite,
child: const Align(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Text(
"Container decoration实现圆角(radius = 20)",
style: TextStyle(color: Colors.blueAccent),
),
),
alignment: Alignment.bottomCenter,
),
),
Container(
margin: const EdgeInsets.only(
left: 10, right: 10, top: 100, bottom: 100),
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
color: Colors.blueAccent),
alignment: Alignment.center,
padding: const EdgeInsets.all(20),
child: const Text(
'这是文本item',
style: TextStyle(fontSize: 30, color: Colors.white),
),
),
]).toList(),
),
),
//使用builder函数创建的
Scaffold(
appBar: AppBar(
title: const Text('这是build函数创建的'),
centerTitle: true,
),
body: ListView.builder(
//item总条数,如果不设置就是无限多条
itemCount: 20,
//item高度
itemExtent: 80,
itemBuilder: (BuildContext context, int index) {
return ListTile(
//文本内容上面添加个图标
leading: const CircleAvatar(
backgroundImage: NetworkImage(
'https://th.bing.com/th/id/OIP.cocZ4jgMxBCJLexP8JaKoAHaE7?w=246&h=180&c=7&r=0&o=5&dpr=2&pid=1.7'),
),
//最右边添加图片或者其他控件都行
trailing: const Icon(Icons.navigate_next_outlined),
//上面的文本内容
title: Text('这是Title$index'),
//下面的文本内容
subtitle: Text('这是SubTitle$index'),
dense: true,
//文本颜色
textColor: Colors.lightBlue[100 * (index + 1)],
//背景色
tileColor: Colors.white54,
style: ListTileStyle.drawer,
//设置内边距默认是16
contentPadding: const EdgeInsets.all(14),
//选中状态
selected: index % 7 == 0,
//选中的文本颜色
selectedColor: Colors.deepOrange,
//选中的背景色
selectedTileColor: Colors.deepPurple,
//点击事件
onTap: () {},
//长安点击
onLongPress: () {},
//是否禁用,禁用后就不能点击了
enabled: index % 3 != 0,
);
}),
),
//使用separated创建的可以创建分割组件
Scaffold(
appBar: AppBar(
title: const Text('这是build函数创建的'),
centerTitle: true,
),
body: ListView.separated(
//翻转从下往上滚动
reverse: true,
//item总条数,如果不设置就是无限多条
itemCount: 20,
//item之间的分割自定义组件,也可使用ListTile.divideTiles包裹
separatorBuilder: (BuildContext context, int index) {
return Container(
child: const Text('我是分割线'),
color: Colors.amber,
alignment: Alignment.center,
);
},
itemBuilder: (BuildContext context, int index) {
return ListTile(
//文本内容上面添加个图标
leading: const CircleAvatar(
backgroundImage: NetworkImage(
'https://th.bing.com/th/id/OIP.cocZ4jgMxBCJLexP8JaKoAHaE7?w=246&h=180&c=7&r=0&o=5&dpr=2&pid=1.7'),
),
//最右边添加图片或者其他控件都行
trailing: const Icon(Icons.navigate_next_outlined),
//上面的文本内容
title: Text('这是Title$index'),
//下面的文本内容
subtitle: Text('这是SubTitle$index'),
dense: true,
//文本颜色
textColor: Colors.lightBlue[100 * (index + 1)],
//背景色
tileColor: Colors.white54,
style: ListTileStyle.drawer,
//设置内边距默认是16
contentPadding: const EdgeInsets.all(14),
//选中状态
selected: index % 7 == 0,
//选中的文本颜色
selectedColor: Colors.deepOrange,
//选中的背景色
selectedTileColor: Colors.deepPurple,
//点击事件
onTap: () {},
//长安点击
onLongPress: () {},
//是否禁用,禁用后就不能点击了
enabled: index % 3 != 0,
);
}),
)
],
),
);
}
///
/// ListView 线性列表
void main(){
runApp(const ListViewApp())
}
class ListViewApp extends StatelessWidget {
const ListViewApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => _ListViewPage();
}
class _ListViewPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ListViewMoreState();
}
///
/// 分页加载数据
///
class _ListViewMoreState extends State<_ListViewPage> {
static const tagLastPage = "加载更多...";
final _data = <String>[tagLastPage];
///
/// 模拟加载数据
Future<void> _loadingMoreDate(bool ifRefresh) {
return Future.delayed(const Duration(milliseconds: 3000), () {
setState(() {
if (ifRefresh) {
_data.clear();
_data.add(tagLastPage);
}
for (int i = 0; i < 20; i++) {
_data.insert(_data.length - 1, "item${_data.length}");
}
});
return null;
});
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
//下拉刷新
body: RefreshIndicator(
onRefresh: () {
return _loadingMoreDate(true);
},
child: ListView.separated(
itemCount: _data.length,
separatorBuilder: (context, index) {
return const Divider(
height: 1,
color: Colors.grey,
);
},
itemBuilder: (context, index) {
if (_data[index] == tagLastPage) {
if (_data.length > 100) {
return const ListTile(
title: Center(
child: Text('没有更多数据'),
),
textColor: Colors.grey,
);
} else {
_loadingMoreDate(false); //加载下一页数据
return ListTile(
title: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const CircularProgressIndicator(),
const SizedBox(
width: 14,
),
Text(_data[index])
],
),
),
textColor: Colors.grey,
);
}
} else {
return ListTile(
//点击删除当前item
onTap: () {
_data.removeAt(index);
setState(() {});
},
leading: const CircleAvatar(
backgroundImage: NetworkImage(
'https://tse1.mm.bing.net/th/id/OET.2762872920ea4e6294085775af35b05f?w=272&h=272&c=7&rs=1&o=5&dpr=2&pid=1.9'),
),
title: Text(_data[index]),
textColor: Colors.black,
);
}
}),
),
),
);
}
}