Flutter进阶组件(5):ExpansionTile(折叠列表项)
ExpansionTile
是一个常用的折叠列表项,它允许用户点击标题来展开或折叠更多的内容。这个组件在实现可折叠列表、FAQ 部分或显示详情信息时非常有用。
一、基本使用
使用ExpansionTile
的基本方式如下:
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: ExpansionTileExample(),
)
));
}
class ExpansionTileExample extends StatelessWidget {
const ExpansionTileExample({super.key});
@override
Widget build(BuildContext context) {
return ListView(
children: const <Widget>[
ExpansionTile(
title: Text('Expansion Tile 1'),
children: <Widget>[
Text('Content for tile 1'),
// 可以添加更多内容
],
),
ExpansionTile(
title: Text('Expansion Tile 2'),
children: <Widget>[
Text('Content for tile 2'),
// 可以添加更多内容
],
),
],
);
}
}
在这个例子中,我们创建了一个ListView
,其中包含了两个ExpansionTile
,每个ExpansionTile
都有一个标题和一个内容列表。效果图如下所示:
二、属性
ExpansionTile
小部件的主要属性包括:
title
: 展开/折叠按钮的标题。children
: 展开时显示的内容列表。initiallyExpanded
: 是否在初始状态下展开。onExpansionChanged
: 展开/折叠状态改变时调用的回调函数。
三、自定义 ExpansionTile
ExpansionTile
可以用于各种自定义场景,例如:
ExpansionTile(
title: Text('Custom ExpansionTile'),
children: <Widget>[
Container(
color: Colors.amber,
child: Padding(
padding: EdgeInsets.all(16.0),
child: Text('Custom content'),
),
),
],
initiallyExpanded: true, // 默认展开
onExpansionChanged: (bool expanded) {
// 处理展开/折叠状态改变的逻辑
},
)
四、高级用法
- 动态内容:
children
可以是动态生成的内容,如根据数据库或其他数据源生成的列表项。 - 自定义折叠图标:通过自定义
title
属性中的leading
或trailing
widget,可以改变默认的折叠图标。 - 条件渲染:根据应用的状态或用户交互动态决定是否渲染
ExpansionTile
。
五、示例
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() {
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: ExpansionTilePage(),
)));
}
class ExpansionTilePage extends StatefulWidget {
const ExpansionTilePage({super.key});
@override
State<ExpansionTilePage> createState() => _ExpansionTileState();
}
class _ExpansionTileState extends State<ExpansionTilePage> {
bool isSwitched1 = false;
bool isSwitched2 = false;
@override
Widget build(BuildContext context) {
return Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: Color.fromRGBO(20, 45, 86, (1.0)),
borderRadius: BorderRadius.circular(4),
),
child: ListView(
children: <Widget>[
ExpansionTile(
maintainState: true,
backgroundColor: Color.fromARGB(48, 33, 149, 243),
tilePadding: EdgeInsets.only(left: 10, right: 20),
minTileHeight: 40,
shape: Border(
top: BorderSide(color: Colors.transparent),
bottom: BorderSide(color: Colors.transparent)),
dense: true,
title: Text(
"语言",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
leading: Image(
image: AssetImage("assets/images/icon_language.png"),
width: 14,
height: 14,
fit: BoxFit.fill,
),
// 下面添加折叠或展开的语言选项
children: <Widget>[
ListTile(
hoverColor: Color.fromARGB(128, 5, 70, 108),
dense: true,
contentPadding: EdgeInsets.only(left: 46, right: 20),
minTileHeight: 40,
title: Text(
"简体中文",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
trailing: Visibility(
visible: true,
child: Icon(
Icons.check,
color: Colors.lightBlue,
size: 20,
)),
onTap: () {
debugPrint('简体中文');
},
),
ListTile(
hoverColor: Color.fromARGB(128, 5, 70, 108),
dense: true,
contentPadding: EdgeInsets.only(left: 46, right: 20),
minTileHeight: 40,
title: Text(
"繁体中文",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
trailing: Visibility(
visible: false,
child: Icon(
Icons.check,
color: Colors.lightBlue,
size: 20,
)),
onTap: () {
debugPrint('繁体中文');
},
),
ListTile(
hoverColor: Color.fromARGB(128, 5, 70, 108),
dense: true,
contentPadding: EdgeInsets.only(left: 46, right: 20),
minTileHeight: 40,
title: Text(
"English",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
trailing: Visibility(
visible: false,
child: Icon(
Icons.check,
color: Colors.lightBlue,
size: 20,
)),
onTap: () {
debugPrint('English');
},
),
],
),
ListTile(
contentPadding: EdgeInsets.only(left: 10),
dense: true,
minTileHeight: 40,
title: Text(
"快捷键",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
leading: Image(
image: AssetImage("assets/images/icon_shortCut.png"),
width: 14,
height: 14,
fit: BoxFit.fill,
),
onTap: () {
debugPrint('快捷键');
},
),
ListTile(
contentPadding: EdgeInsets.only(left: 10, right: 5),
dense: true,
minTileHeight: 40,
title: Text(
"键盘显示",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
leading: Image(
image: AssetImage("assets/images/icon_keyboard.png"),
width: 14,
height: 14,
fit: BoxFit.fill,
),
trailing: Transform.scale(
scale: 0.6,
child: CupertinoSwitch(
value: isSwitched2,
onChanged: (value) {
setState(() {
isSwitched2 = value;
});
},
thumbColor: Color.fromARGB(255, 1, 29, 53),
activeColor: Colors.blue,
trackColor: Colors.grey,
)),
onTap: () {
debugPrint('键盘显示');
},
),
ListTile(
contentPadding: EdgeInsets.only(left: 10),
dense: true,
minTileHeight: 40,
title: Text(
"锁屏设置",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
leading: Image(
image: AssetImage("assets/images/icon_userRight.png"),
width: 14,
height: 14,
fit: BoxFit.fill,
),
onTap: () {
debugPrint('锁屏设置');
},
),
ExpansionTile(
backgroundColor: Color.fromARGB(48, 33, 149, 243),
tilePadding: EdgeInsets.only(left: 10, right: 20),
shape: Border(
top: BorderSide(color: Colors.transparent),
bottom: BorderSide(color: Colors.transparent)),
dense: true,
minTileHeight: 40,
title: Text(
"管理员",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
leading: Image(
image: AssetImage("assets/images/icon_managerSet.png"),
width: 14,
height: 14,
fit: BoxFit.fill,
),
children: <Widget>[
ListTile(
contentPadding: EdgeInsets.only(left: 10),
dense: true,
minTileHeight: 40,
title: Text(
"用户",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
leading: Image(
image: AssetImage("assets/images/icon_install.png"),
width: 14,
height: 14,
fit: BoxFit.fill,
),
onTap: () {
debugPrint('用户');
},
),
ListTile(
contentPadding: EdgeInsets.only(left: 10),
dense: true,
minTileHeight: 40,
title: Text(
"布局",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
leading: Image(
image: AssetImage("assets/images/icon_layout.png"),
width: 14,
height: 14,
fit: BoxFit.fill,
),
onTap: () {
debugPrint('布局');
},
),
],
),
],
));
}
}
效果图如下图所示:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
2019-12-26 Qt 使用 MPV 开源播放器