Flutter学习日记之ExpansionPanel/ExpansionTile实现分级列表(可开闭)

本文地址:https://blog.csdn.net/qq_40785165/article/details/120123938,转载需附上此链接

自己造的船,总有一天会扬帆远航!

大家好,我是小黑,一个还没秃头的程序员~~~

这次要给大家带来的是ExpansionPanelList组件,这是一个可以进行嵌套的列表,可以搭配ExpansionPanel,以及ListView搭配ExpansionTile的方案,适合实现分组效果的功能,而且还支持展开/关闭,多次嵌套可实现多级列表的功能,效果如下:
在这里插入图片描述

1.ExpansionPanelList搭配ExpansionPanel实现分级列表

ExpansionPanelList的常用属性如下:

参数说明
children一般是ExpansionPanel组件数组
expansionCallback展开/关闭的回调监听

ExpansionPanelList一般搭配ExpansionPanel使用,由ExpansionPanel实现头部以及展开内容的设置

ExpansionPanel的常用属性

参数说明
headerBuilder头部
body展开部分的内容
isExpanded是否展开
canTapOnHeader头部是否可以点击
backgroundColor背景颜色

(一) 创建一个类,用于生成列表数据

代码如下:

class Item {
  Item({
    required this.bodyValue,
    required this.headerValue,
    this.isExpanded = false,
  });

  Widget bodyValue;
  Widget headerValue;
  bool isExpanded;
}
  1. bodyValue 对应ExpansionPanel中的body内容
  2. headerValue 对应ExpansionPanel的头部内容
  3. isExpanded 对应是否展开

(二) 制造数据

我这里是嵌套了一个ListView,要记得设置shrinkWrap: true,不然ListView嵌套会报错

List<Item> generateItems(int numberOfItems) {
  return List.generate(numberOfItems, (int index) {
    return Item(
      headerValue: ListTile(
        trailing: Image.asset(
          "assets/images/icon_friend.png",
          width: 30,
          height: 30,
        ),
        title: Text("panel $index"),
      ),
      bodyValue: Padding(
        padding: EdgeInsets.all(20),
        child: ListView.builder(
          shrinkWrap: true,
          itemBuilder: (BuildContext context, int childIndex) {
            return ListTile(
              leading: Image.asset(
                "assets/images/icon_friend.png",
                width: 30,
                height: 30,
              ),
              title: Text("panel $index - $childIndex"),
            );
          },
          itemCount: 2,
        ),
      ),
    );
  });
}

(三) 生成ExpansionPanelList

代码如下:

 List<Item> _data = generateItems(8);
  Widget _buildPanelList() {
    return ExpansionPanelList(
      expansionCallback: (int index, bool isExpanded) {
        setState(() {
          _data[index].isExpanded = !isExpanded;
        });
      },
      children: _data.map<ExpansionPanel>((Item item) {
        return ExpansionPanel(
          headerBuilder: (BuildContext context, bool isExpanded) {
            return item.headerValue;
          },
          body: item.expandedValue,
          isExpanded: item.isExpanded,
        );
      }).toList(),
    );
  }

2.ListView搭配ExpansionTile实现分级列表

ExpansionTile使用和ListTile差不多,这里只列出不同的几个参数:

参数说明
onExpansionChanged展开/关闭的回调监听
initiallyExpanded默认开闭状态
collapsedBackgroundColor折叠时的背景颜色
collapsedTextColor折叠时头部文字的颜色
collapsedIconColor折叠时尾部图标的颜色
children展开时显示的内容

(一) 创建一个类,用于生成列表数据

代码按如下:

class Item {
  Item({
    required this.title,
    required this.body,
  });

  Widget title;
  Widget body;
}
  1. title 对应ExpansionTile的title
  2. body 对应ExpansionTile的children

(二) 制造数据

头部可以使用ListTile,方便设置左部图标,展开内容依然是ListView

List<Item> generateItems(int numberOfItems) {
  return List.generate(numberOfItems, (int index) {
    return Item(
      title: ListTile(
        title: Text(
          "分组$index",
          style: TextStyle(fontSize: 18),
        ),
      ),
      body: Padding(
        padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
        child: ListView.builder(
          shrinkWrap: true,
          itemBuilder: (BuildContext context, int childIndex) {
            return ListTile(
              leading: Image.asset(
                "assets/images/icon_friend.png",
                width: 30,
                height: 30,
              ),
              title: Text(
                "成员$index - $childIndex",
                style: TextStyle(fontSize: 18),
              ),
            );
          },
          itemCount: 2,
        ),
      ),
    );
  });
}

(三) 生成ListView

代码如下:

  List<Item> _data = generateItems(8);
  Widget _buildPanel() {
    return ListView(
      shrinkWrap: true,
      children: _data.map<ExpansionTile>((item) {
        return ExpansionTile(
          /* trailing: Icon(Icons.arrow_drop_up),*/
          onExpansionChanged: (isOpen) {
          
          },
          title: item.title,
          children: [item.body],
          initiallyExpanded: false,
        );
      }).toList(),
    );
  }

3.两种方案的对比

  1. ExpansionPanelList搭配ExpansionPanel只能点击尾部图标进行展开/关闭,且由于ExpansionPanel的原因,无法修改尾部的图标
  2. ListView搭配ExpansionTile,由于ExpansionTile有点击事件,所以可以点击整个头部进行展开/关闭,且可以使用ExpansionTile的trailing属性进行尾部按钮的设置

到此为止,两种实现分级列表的方案就介绍完毕了,更多关于Flutter的内容日后会持续更新,感兴趣的朋友可以点个关注,喜欢的话别忘了点个赞哈!大家晚安!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值