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都有一个标题和一个内容列表。效果图如下所示:

Flutter_ExpansionTileExample_A.gif


二、属性

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属性中的leadingtrailing 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('布局');
                  },
                ),
              ],
            ),
          ],
        ));
  }
}

效果图如下图所示:

Flutter_ExpansionTileExample_B.gif


posted @   fengMisaka  阅读(222)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
历史上的今天:
2019-12-26 Qt 使用 MPV 开源播放器
点击右上角即可分享
微信分享提示