1、ListView
列表分类:垂直列表、垂直图文列表、水平列表、动态列表。
1、列表常用参数
ListView({
Key key,
//Axis类型可选命名参数,设置沿横轴还是纵轴滚动
Axis scrollDirection = Axis.vertical,
//bool类型可选命名参数,用于设置视图的滚动方向是否为读取方向
bool reverse = false,
//ScrollController类型可选命名参数,控制滚动视图滚动位置的控制器
ScrollController controller,
//bool类型可选命名参数,是否是与父PrimaryScrollController相关联的主滚动视图
bool primary,
//ScrollPhysics类型可选命名参数,滚动视图应如何响应用户输入
ScrollPhysics physics,
//boo类型可选命名参数,crollDirection中滚动视图的范围是否应由正在查看的内容确定
bool shrinkWrap = false,
//EdgeInsetsGeometry类型可选命名参数,内边距,使用EdgeInsets
EdgeInsetsGeometry padding,
//double类型可选命名参数,不为空则强制子级在滚动方向上具有给定范围
this.itemExtent,
//bool类型可选命名参数,是否将每个子Widget都包装在AutomaticKeepAlive组件中
bool addAutomaticKeepAlives = true,
//bool类型可选命名参数,是否将每个子Widget都包装在RepaintBoundary组件中
bool addRepaintBoundaries = true,
//bool类型可选命名参数,是否将每个子Widget都包装在IndexedSemantics组件中
bool addSemanticIndexes = true,
//double类型可选命名参数,用于设置不可见的缓存区域的大小
double cacheExtent,
//List<Widget>类型可选命名参数,用于设置滚动列表的每一项Widget
List<Widget> children = const <Widget>[],
//int类型可选命名参数,为ListView中的子列表中Widget提供语义信息的数量
int semanticChildCount,
//DragStartBehavior类型可选命名参数,确定处理拖动开始行为的方式
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
})
//此构造方法采用 IndexedWidgetBuilder,可以根据需要创建子 Widget。适用于有大量或无限个子Widget的ListView。其只对可见的子 Widget 进行构建
ListView.builder({
Key key,
//IndexedWidgetBuilder类型必传参数,为给定索引创建Widget
@required IndexedWidgetBuilder itemBuilder,
//int类型可选命名参数,创建Widget的个数
int itemCount,
//...省略与ListView相同部分
})
//此构造方法采用 IndexedWidgetBuilder,一个是 itemBuilder,可以根据需要创建子 Widget,另一个是 separatorBuilder,同样构建出现在子项目之间的分隔子项目。此构造函数适用于具有固定数目的子元素的列表视图
ListView.separated({
Key key,
//IndexedWidgetBuilder类型必传参数,为给定索引创建Widget
@required IndexedWidgetBuilder itemBuilder,
//IndexedWidgetBuilder类型必传参数,为给定索引创建Widget分割Widget
@required IndexedWidgetBuilder separatorBuilder,
//int类型必传参数,创建Widget的个数
@required int itemCount,
//...省略与ListView相同部分
})
//此构造方法采用 SliverChildDelegate,它提供了自定义模型的其他方面的功能。例如,SliverChildDelegate 可以控制用于估计实际不可见的子代大小的算法
const ListView.custom({
Key key,
//SliverChildDelegate类型必传参数,为ListView提供子Widget的委托
@required this.childrenDelegate,
//...省略与ListView相同部分
})
2、示例
垂直列表
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ListView(
children: const [
ListTile(
title: Text("第一行"),
subtitle: Text("第一行副标题"),
titleTextStyle: TextStyle(
color: Colors.red,
backgroundColor: Colors.blue,
fontSize: 30,
),
subtitleTextStyle: TextStyle(
color: Colors.green,
backgroundColor: Colors.orange,
fontSize: 10,
),
),
ListTile(
title: Text("第二行"),
subtitle: Text("第二行副标题"),
titleTextStyle: TextStyle(
color: Colors.red,
backgroundColor: Colors.blue,
fontSize: 30,
),
subtitleTextStyle: TextStyle(
color: Colors.green,
backgroundColor: Colors.orange,
fontSize: 10,
),
),
],
);
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ListView(
children: const [
ListTile(
leading: Icon(
Icons.assignment,
color: Colors.red,
// size: 40,
),
title: Text("全部订单"),
),
Divider(),
ListTile(
leading: Icon(
Icons.payment,
color: Colors.green,
// size: 40,
),
title: Text("待付款"),
),
Divider(),
ListTile(
leading: Icon(
Icons.local_car_wash,
color: Colors.orange,
// size: 40,
),
title: Text("待收货"),
),
Divider(),
ListTile(
leading: Icon(
Icons.favorite,
color: Colors.lightGreen,
// size: 40,
),
title: Text("我的收藏"),
),
Divider(),
ListTile(
leading: Icon(
Icons.people,
color: Colors.black54,
// size: 40,
),
title: Text("在线客服"),
),
Divider(),
],
);
}
}
垂直图文列表
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ListView(
children: [
ListTile(
leading: Image.network("https://www.itying.com/images/flutter/1.png"),
title: const Text("华北黄淮高温雨今起强势登场"),
subtitle: const Text("中国天气网讯 21日开始,华北黄淮高温雨今起强势登场"),
),
const Divider(),
ListTile(
trailing: Image.network("https://www.itying.com/images/flutter/1.png"),
title: const Text("华北黄淮高温雨今起强势登场"),
subtitle: const Text("中国天气网讯 21日开始,华北黄淮高温雨今起强势登场"),
),
const Divider(),
ListTile(
leading: Image.network("https://www.itying.com/images/flutter/1.png"),
title: const Text("华北黄淮高温雨今起强势登场"),
// subtitle: const Text("中国天气网讯 21日开始,华北黄淮高温雨今起强势登场"),
),
const Divider(),
],
);
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.all(10),
children: [
Image.network("https://www.itying.com/images/flutter/1.png"),
Container(
height: 44,
padding: const EdgeInsets.fromLTRB(0, 10, 0, 10),
child: const Text(
"第一行",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18),
),
),
const Divider(),
Image.network("https://www.itying.com/images/flutter/2.png"),
Container(
height: 44,
padding: const EdgeInsets.fromLTRB(0, 10, 0, 10),
child: const Text(
"第二行",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18),
),
),
const Divider(),
],
);
}
}
水平列表
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
height: 180,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
ClipOval(
//圆角
child: Container(
width: 180,
color: Colors.red,
),
),
Container(
width: 180,
color: Colors.green,
child: ClipRRect(
borderRadius: BorderRadius.circular(50),
child: Column(
children: [
Image.network(
"https://www.itying.com/images/flutter/1.png"),
const Text("第一个文本"),
],
),
)),
Container(
color: Colors.orange,
width: 180,
),
],
),
);
}
}
动态列表
class MyApp extends StatelessWidget {
const MyApp({super.key});
List<Widget> _initListView() {
List<Widget> list = [];
for (var i = 0; i < 10; i++) {
list.add(const ListTile(
title: Text("列表"),
));
}
return list;
}
@override
Widget build(BuildContext context) {
return ListView(
children: _initListView(),
);
}
}
builder 实现动态列表
class MyApp extends StatelessWidget {
List<String> list = [];
MyApp({super.key}) {
for (var i = 0; i < 10; i++) {
list.add("列表 -- $i");
}
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: list.length,//数量
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(list[index]),
);
},
);
}
}
builder 实现动态列表 -- 获取 json 数据
// listData 中测试数据,使用时需要导入头文件
List listData=[
{
"title": 'Candy Shop',
"author": 'Mohamed Chahin',
"imageUrl": 'https://www.itying.com/images/flutter/1.png',
},
{
"title": 'Childhood in a picture',
"author": 'Google',
"imageUrl": 'https://www.itying.com/images/flutter/2.png',
},
{
"title": 'Alibaba Shop',
"author": 'Alibaba',
"imageUrl": 'https://www.itying.com/images/flutter/3.png',
},
{
"title": 'Candy Shop',
"author": 'Mohamed Chahin',
"imageUrl": 'https://www.itying.com/images/flutter/4.png',
},
{
"title": 'Tornado',
"author": 'Mohamed Chahin',
"imageUrl": 'https://www.itying.com/images/flutter/5.png',
},
{
"title": 'Undo',
"author": 'Mohamed Chahin',
"imageUrl": 'https://www.itying.com/images/flutter/6.png',
},
{
"title": 'white-dragon',
"author": 'Mohamed Chahin',
"imageUrl": 'https://www.itying.com/images/flutter/7.png',
}
];
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: listData.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: Image.network(listData[index]["imageUrl"]),
title: Text(listData[index]["title"]),
subtitle: Text(listData[index]["author"]),
);
},
);
}
}
2、GridView
GridView 网格布局,让可以滚动的元素使用矩阵方式排列(类似 OC 的 UICollectionView)。
1、GridView 创建网格方式
1、GridView.count 方式
2、GridView.extent 方式
3、GridView.builder 方式
2、GridView 常见属性
GridView GridView({
Key? key,
Axis scrollDirection = Axis.vertical, //滚动方向
//bool类型可选命名参数,用于设置视图的滚动方向是否为读取方向
bool reverse = false,
//ScrollController类型可选命名参数,控制滚动视图滚动位置的控制器
ScrollController? controller,
//bool类型可选命名参数,是否是与父PrimaryScrollController相关联的主滚动视图
bool? primary,
//ScrollPhysics类型可选命名参数,滚动视图应如何响应用户输入
ScrollPhysics? physics,
//boo类型可选命名参数,crollDirection中滚动视图的范围是否应由正在查看的内容确定
bool shrinkWrap = false,
EdgeInsetsGeometry? padding, //内边距
//控制布局,主要用在 GridView.builder 里面
required SliverGridDelegate gridDelegate,
//bool类型可选命名参数,是否将每个子Widget都包装在AutomaticKeepAlive组件中
bool addAutomaticKeepAlives = true,
//bool类型可选命名参数,是否将每个子Widget都包装在RepaintBoundary组件中
bool addRepaintBoundaries = true,
//bool类型可选命名参数,是否将每个子Widget都包装在IndexedSemantics组件中
bool addSemanticIndexes = true,
//double类型可选命名参数,用于设置不可见的缓存区域的大小
double? cacheExtent,
//List<Widget>类型可选命名参数,用于设置滚动列表的每一项Widget
List<Widget> children = const <Widget>[],
//int类型可选命名参数,为ListView中的子列表中Widget提供语义信息的数量
int? semanticChildCount,
//DragStartBehavior类型可选命名参数,确定处理拖动开始行为的方式
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
//Clip类型可选命名参数,内容将被裁剪(或不裁剪)
Clip clipBehavior = Clip.hardEdge,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
//保持滑动的偏移量
String? restorationId,
})
3、网格布局
GridView.count 实现网格布局
GridView.count 构造函数内部使用了 SliverGridDelegateWithFixedCrossAxisCount,我们通过它可以快速的创建横轴固定数量子元素的 GridView。
//示例一
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return GridView.count(
crossAxisSpacing: 3, //widget 左右间的距离
mainAxisSpacing: 2, //widget 上下间的距离
crossAxisCount: 4, //每行列数
children: const <Widget>[
Icon(Icons.home),
Icon(Icons.ac_unit),
Icon(Icons.search),
Icon(Icons.settings),
Icon(Icons.airport_shuttle),
Icon(Icons.all_inclusive),
Icon(Icons.beach_access),
Icon(Icons.cake),
Icon(Icons.circle),
],
);
}
}
示例二
///GridView.count 实现网格布局
class MyApp1 extends StatelessWidget {
const MyApp1({super.key});
List<Widget> _customList() {
List<Widget> list = [];
for (var i = 0; i < 50; i++) {
list.add(
Container(
color: Colors.red,
alignment: Alignment.center,
child: Text(
"第 $i 个元素",
style: const TextStyle(color: Colors.white, fontSize: 15),
),
),
);
}
return list;
}
@override
Widget build(BuildContext context) {
return GridView.count(
padding: const EdgeInsets.all(10),
crossAxisSpacing: 3, //水平子 Widget 之间间距
mainAxisSpacing: 2, //垂直子 Widget 之间间距
crossAxisCount: 4, //每行列数
childAspectRatio: 0.8, //宽高比
children: _customList(),
);
}
}
GridView.count 实现动态列表
///GridView.count 实现动态列表
class MyApp extends StatelessWidget {
const MyApp({super.key});
List<Widget> _customList() {
var list = listData.map((value) {
return Container(
decoration: BoxDecoration(
border: Border.all(
color: const Color.fromRGBO(233, 233, 233, 0.9),
width: 1,
)),
child: Column(
children: [
Image.network(value["imageUrl"]),
const SizedBox(
height: 12,
),
Text(
value["title"],
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 10),
),
],
),
);
});
return list.toList();
}
@override
Widget build(BuildContext context) {
return GridView.count(
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 2,
padding: const EdgeInsets.all(10),
children: _customList(),
);
}
}
GridView.extent 实现网格布局
GridView.extent 构造函数内部使用了 SliverGridDelegateWithMaxCrossAxisExtent,我们通过它可以快速的创建横轴子元素为固定最大长度的的 GridView。
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return GridView.extent(
maxCrossAxisExtent: 100, //横轴子元素的最大长度
children: const <Widget>[
Icon(Icons.home),
Icon(Icons.ac_unit),
Icon(Icons.search),
Icon(Icons.settings),
Icon(Icons.airport_shuttle),
Icon(Icons.all_inclusive),
Icon(Icons.beach_access),
Icon(Icons.cake),
Icon(Icons.circle),
],
);
}
}
GridView.builder 实现动态列表
///GridView.builder 实现动态列表
class MyApp extends StatelessWidget {
const MyApp({super.key});
//初始化数据
Widget _customWidget(BuildContext context, int index) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: const Color.fromRGBO(233, 233, 233, 0.9)),
),
child: Column(
children: [
Image.network(listData[index]["imageUrl"]),
const SizedBox(
height: 12,
),
Text(
listData[index]["title"],
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 15),
)
],
),
);
}
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(//注意此行
crossAxisCount: 2, //每行 widget 数量
crossAxisSpacing: 10, //widget 水平之间的距离
mainAxisSpacing: 10, //widget 垂直之间的距离
),
itemCount: listData.length,
itemBuilder: _customWidget,
);
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget _customWidget(BuildContext context, int index) {
return Container(
decoration: BoxDecoration(
border: Border.all(
color: const Color.fromRGBO(233, 233, 233, 0.9),
width: 1,
)),
child: Column(
children: [
Image.network(listData[index]["imageUrl"]),
const SizedBox(
height: 12,
),
Text(
listData[index]["title"],
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 15,
),
)
],
),
);
}
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(//注意此行
maxCrossAxisExtent: 300, //横轴元素的最大长度
crossAxisSpacing: 10, //widget 水平之间的距离
mainAxisSpacing: 10, //widget 垂直之间的距离
),
itemCount: listData.length,
itemBuilder: _customWidget,
);
}
}
网友评论