ListView 常用属性讲解
ListView
是 Flutter 中用于展示滚动列表的一个非常常用的小部件。以下是一些常用的 ListView
属性及其说明:
1. children
-
类型:
List<Widget>
-
说明: 用于直接传入一个包含多个子小部件的列表。适合子项数量较少的情况。
ListView( children: <Widget>[ ListTile(title: Text('Item 1')), ListTile(title: Text('Item 2')), ListTile(title: Text('Item 3')), ], )
2. builder
- 类型: IndexedWidgetBuilder
- 说明: 用于懒加载子项,适合子项数量较多的情况。只有在需要时才会构建可见的子项。
ListView.builder(
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(title: Text('Item $index'));
},
)
3. separatorBuilder
说明: 用于在 ListView.separated 中指定分隔符的构建方式。可以用于添加分隔线或间距。
ListView.separated(
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(title: Text('Item $index'));
},
separatorBuilder: (context, index) => Divider(),
)
4. scrollDirection
- 类型: Axis
- 说明: 用于设置滚动方向,可以是 Axis.vertical(默认)或 Axis.horizontal。
5. physics
- 类型: ScrollPhysics
- 说明: 用于控制滚动行为,例如设置为 NeverScrollableScrollPhysics 来禁用滚动。
6. shrinkWrap
- 类型: bool
- 说明: 指示 ListView 是否应根据子项的大小来计算自身的高度。通常在嵌套滚动视图时使用。
7. padding
- 类型: EdgeInsets
- 说明: 用于设置 ListView 的内边距。
8. itemExtent
- 类型: double
- 说明: 用于设置每个列表项的高度,适合高度固定的列表以提高性能。
ListTile 使用
ListTile 是 Flutter 中用于构建列表项的一个小部件。它通常用于在 ListView 或其他列表结构中显示一个条目。ListTile 提供了一种标准化的方式来展示信息,包括标题、副标题、图标等。
主要属性
- leading:
用于显示在列表项前面的图标或小部件(如 Icon 或 CircleAvatar)。 - title:
列表项的主标题,通常是一个 Text 小部件。 - subtitle:
列表项的副标题,通常也是一个 Text 小部件,可以用于显示额外信息。 - trailing:
用于显示在列表项后面的图标或小部件,常用于操作按钮或状态指示器。 - onTap:
点击列表项时执行的回调函数,允许你在用户点击时执行特定操作。 - isThreeLine:
一个布尔值,指示列表项是否有三行文本(标题、副标题和额外的文本)。 - dense:
一个布尔值,指示列表项是否应更紧凑地显示。
使用示例
ListTile(
leading: Icon(Icons.album),
title: Text('音乐专辑'),
subtitle: Text('艺术家名称'),
trailing: Icon(Icons.more_vert),
onTap: () {
// 执行某个操作
},
)
效果:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar:
AppBar(title: const Text("App Title"), backgroundColor: Colors.red),
body: const MyList(),
),
),
);
}
class MyList extends StatelessWidget {
const MyList({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: ListView(
padding: const EdgeInsets.only(top: 5),
children: [
ListTile(
// 设置前图片
leading: Image.network(
"http://www.people.com.cn/NMediaFile/2024/1210/MAIN1733813355177423YPNX22U.jpg",
),
title: const Text("外交部:推动国际人权事业健康发展"),
subtitle: const Text("中方呼吁各方开展建设性对话与合作,共同推动国际人权事业健康发展"),
),
const Divider(),
ListTile(
leading: Image.network(
"http://www.people.com.cn/NMediaFile/2024/1210/MAIN1733839403962N0OCKJB5ST.jpg"),
title: const Text("日用家电零售11月同比增长74.4%"),
),
const Divider(),
ListTile(
leading: Image.network(
"http://www.people.com.cn/NMediaFile/2024/1210/MAIN1733793685988EYPIIFO3TV.jpg",
),
title: const Text("2024中华文化国际传播论坛举行"),
subtitle: const Text("中方呼吁各方开展建设性对话与合作,共同推动国际人权事业健康发展"),
),
const Divider(),
ListTile(
leading: Image.network(
"http://www.people.com.cn/NMediaFile/2024/1210/MAIN1733839403877Y0W2V4B91F.jpg",
),
title: const Text("外交部:推动国际人权事业健康发展"),
subtitle: const Text("中方呼吁各方开展建设性对话与合作,共同推动国际人权事业健康发展"),
),
const Divider(),
ListTile(
leading: Image.network(
"http://www.people.com.cn/NMediaFile/2024/1210/MAIN17337944922831E47YQPF4V.jpg",
),
title: const Text("外交部:推动国际人权事业健康发展"),
subtitle: const Text("中方呼吁各方开展建设性对话与合作,共同推动国际人权事业健康发展"),
),
const Divider(),
ListTile(
leading: Image.network(
"http://www.people.com.cn/NMediaFile/2024/1210/MAIN1733843461835Q6SZWKGIS9.jpg",
),
title: const Text("外交部:推动国际人权事业健康发展"),
subtitle: const Text("中方呼吁各方开展建设性对话与合作,共同推动国际人权事业健康发展"),
),
const Divider(),
ListTile(
leading: Image.network(
"http://www.people.com.cn/NMediaFile/2024/1210/MAIN1733839403914U9M3IAKRAR.jpg",
),
title: const Text("外交部:推动国际人权事业健康发展"),
subtitle: const Text("中方呼吁各方开展建设性对话与合作,共同推动国际人权事业健康发展"),
),
],
),
);
}
}
自定义垂直列表组件
children 中可以放任意组件:
- 垂直列表组件无法设置宽度。会根据屏幕自适应
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar:
AppBar(title: const Text("App Title"), backgroundColor: Colors.red),
body: const MyList(),
),
),
);
}
class MyList extends StatelessWidget {
const MyList({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: ListView(
padding: const EdgeInsets.only(top: 5),
// 可以放任意组件, 垂直列表中,宽度根据屏幕自适应,不能手动设置宽度
children: [
Image.network(
"https://developer.qcloudimg.com/operation/attachment/900005/20241205-9e91b6ad.png",
height: 400,
),
Container(
height: 60,
// 设置宽度无效
width: 100,
decoration: const BoxDecoration(color: Colors.red),
),
Container(
height: 60,
decoration: const BoxDecoration(color: Colors.blue),
),
Container(
height: 60,
decoration: const BoxDecoration(color: Colors.yellowAccent),
),
Container(
height: 60,
decoration: const BoxDecoration(color: Colors.blueGrey),
),
],
),
);
}
}
效果:
自定义水平列表
- 水平列表中,如果没有给列表的父容器设置高度,则列表的高度根据屏幕自适应,不能手动设置宽度
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar:
AppBar(title: const Text("App Title"), backgroundColor: Colors.red),
body: const MyList(),
),
),
);
}
class MyList extends StatelessWidget {
const MyList({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
// 父容器设置高度,控制列表整体的高度
height: 220,
child: ListView(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.only(top: 5),
// 水平列表中,如果没有给列表的父容器设置高度,则列表的高度根据屏幕自适应,不能手动设置宽度
children: [
Image.network(
"https://developer.qcloudimg.com/operation/attachment/900005/20241205-9e91b6ad.png",
),
Container(
decoration: const BoxDecoration(color: Colors.red),
width: 100,
// 水平列表设置高度无效
height: 420,
),
Container(
decoration: const BoxDecoration(color: Colors.blue),
width: 100,
),
Container(
decoration: const BoxDecoration(color: Colors.yellowAccent),
width: 100,
),
Container(
width: 100,
decoration: const BoxDecoration(color: Colors.blueGrey),
),
],
),
);
}
}
效果:
实现水平列表商品效果
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar:
AppBar(title: const Text("App Title"), backgroundColor: Colors.red),
body: const MyList(),
),
),
);
}
class MyList extends StatelessWidget {
const MyList({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
// 父容器设置高度,控制列表整体的高度
height: 120,
child: ListView(
scrollDirection: Axis.horizontal,
// padding: const EdgeInsets.only(top: 5),
// 水平列表中,如果没有给列表的父容器设置高度,则列表的高度根据屏幕自适应,不能手动设置宽度
children: [
MyShop(
"https://img14.360buyimg.com/n0/jfs/t1/226009/21/18660/59607/664f0109Fd05e02d9/6fb2028c374334c7.jpg",
"键盘",
),
const SizedBox(width: 5),
MyShop(
"https://img14.360buyimg.com/n0/jfs/t1/226009/21/18660/59607/664f0109Fd05e02d9/6fb2028c374334c7.jpg",
"键盘",
),
const SizedBox(width: 5),
MyShop(
"https://img14.360buyimg.com/n0/jfs/t1/226009/21/18660/59607/664f0109Fd05e02d9/6fb2028c374334c7.jpg",
"键盘",
),
const SizedBox(width: 5),
MyShop(
"https://img14.360buyimg.com/n0/jfs/t1/226009/21/18660/59607/664f0109Fd05e02d9/6fb2028c374334c7.jpg",
"键盘",
),
const SizedBox(width: 5),
MyShop(
"https://img14.360buyimg.com/n0/jfs/t1/226009/21/18660/59607/664f0109Fd05e02d9/6fb2028c374334c7.jpg",
"键盘",
),
const SizedBox(width: 5),
MyShop(
"https://img14.360buyimg.com/n0/jfs/t1/226009/21/18660/59607/664f0109Fd05e02d9/6fb2028c374334c7.jpg",
"键盘",
),
const SizedBox(width: 5),
MyShop(
"https://img14.360buyimg.com/n0/jfs/t1/226009/21/18660/59607/664f0109Fd05e02d9/6fb2028c374334c7.jpg",
"键盘",
),
],
),
);
}
}
class MyShop extends StatelessWidget {
String imgUrl;
String text;
MyShop(this.imgUrl, this.text, {super.key});
@override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
color: Colors.blueGrey,
),
width: 100,
child: Column(
children: [
SizedBox(
height: 100,
child: Image.network(
imgUrl,
),
),
Text(text),
],
),
);
}
}
效果
ListView.builder 使用
准备数据: data.dart
class Data {
static List<Map<String, String>> blogs = [
{
"title": "晨曦曙光",
"subtitle": "黎明的第一缕阳光",
},
{
"title": "森林漫步",
"subtitle": "绿叶间的宁静小径",
},
{
"title": "海洋之心",
"subtitle": "深蓝海面下的神秘世界",
},
{
"title": "雪山之巅",
"subtitle": "白色世界的壮丽景观",
},
{
"title": "城市夜景",
"subtitle": "夜晚灯光下的都市风情",
},
{
"title": "静谧湖泊",
"subtitle": "倒映天空的平静湖水",
},
{
"title": "星空奇观",
"subtitle": "繁星点点的浩瀚宇宙",
},
{
"title": "古老城堡",
"subtitle": "岁月沉淀的历史建筑",
},
{
"title": "瀑布轰鸣",
"subtitle": "水流奔腾而下的壮观景象",
},
{
"title": "沙漠绿洲",
"subtitle": "干旱中的生命奇迹",
},
{
"title": "热带雨林",
"subtitle": "丰富的生物多样性",
}
];
}
main.dart
import 'package:flutter/material.dart';
import './data.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar:
AppBar(title: const Text("App Title"), backgroundColor: Colors.red),
body: MyList(),
),
),
);
}
class MyList extends StatelessWidget {
MyList({super.key}) {
initData();
}
List<Widget> blogs = [];
initData() {
// Data.blogs 是 data.dart 中的数据 也可以来自网络
for (Map<String, String> value in Data.blogs) {
ListTile listTile = ListTile(
title: Text(value["title"]!),
subtitle: Text(value["subtitle"]!),
// leading: Image.network(value["image_url"]!),
);
blogs.add(listTile);
}
}
@override
Widget build(BuildContext context) {
return ListView.builder(
// 此字段必填, 否则数量不确定,会数组越界
itemCount: blogs.length,
// 构建列表元素
itemBuilder: (context, index) {
return blogs[index];
},
);
}
}
效果
联系方式: dccmmtop@foxmail.com