flutter 展开闭合案例 ExpansionTile 与 ExpansionPanelList

手机的屏幕本身就很小,所以要合理利用空间,把主要的元素展示出来,次要或者不重要的元素等用户向看的时候再给用户展示。这类操作最常见的交互就是展开和闭合了。

在flutter中,ExpansionTiles可用于生成两级或多级列表。

ExpansionTile组件

ExpansionTile Widget就是一个可以展开闭合的组件,常用的属性有如下几个。

  • title: 闭合时显示的标题,这个部分经常使用Text Widget
  • leading: 标题左侧图标,多是用来修饰,让界面显得美观。
  • backgroundColor: 展开时的背景颜色,当然也是有过度动画的,效果非常好。
  • children: 子元素,是一个数组,可以放入多个元素。
  • trailing: 右侧的箭头,可以自行替换
  • initiallyExpanded: 初始状态是否展开,为true时,是展开,默认为false,是不展开。
        ExpansionTile(
            title: Text('展开闭合demo'),
            leading: Icon(Icons.ac_unit, color: Colors.green),
            backgroundColor: Colors.white,
            initiallyExpanded: true, // 是否默认展开
            children: <Widget>[
              ListTile(
                  title:Text('北京优帆远扬'),
                  subtitle:Text('重庆优帆天成')
              ),
              ListTile(
                  title:Text('北京优帆远扬'),
                  subtitle:Text('重庆优帆天成')
              )
            ]
          )

flutter 展开闭合案例 ExpansionTile与ExpansionPanelList

ExpansionPanelList组件

ExpansionPanelList是一个item可以打开合并的list控件。

ExpansionPanelList 常用属性

  • expansionCallback:点击和交互的回掉事件,有两个参数,第一个是触发动作的索引,第二个是布尔类型的触发值。
  • children:列表的子元素,里边多是一个List数组。

ExpandStateBean 自定义类

为了方便管理制作了一个ExpandState类,里边就是两个状态,一个是是否展开isOpen,另一个索引值。代码如下:

class ExpandState{
  var isOpen;
  var index;
  ExpandStateBean(this.index,this.isOpen);
}

例子代码如下:

import 'package:flutter/material.dart';

class Expansion extends StatefulWidget {
  @override
  _ExpansionState createState() => _ExpansionState();
}

/// 用于管理状态
class ExpandState {
  bool isOpen;
  var index;
  ExpandState(this.index, this.isOpen);
}

class _ExpansionState extends State<Expansion> {
  var currentPanelIndex = -1; // 当前panel的index
  List<int> mList;   // 组成一个int类型数组,用来控制索引
  List<ExpandState> expandStateList;    //开展开的状态列表, ExpandStateBean是自定义的类

  /// 修改列表项展开与闭合的方法
  _setExpandOpenOrClose(int index, isExpand) {
    setState(() {
      /// 遍历可展开状态列表
      expandStateList.forEach((item){
        if(item.index==index){
          /// 取反
          item.isOpen = !isExpand;
        }
      });
    });
  }

  /// 构造方法,调用此类自动执行,这里的数组需要再实际情况自己定义,现在只是模拟数据
  _ExpansionState() {
    mList = new List();
    expandStateList = new List();
    // 遍历为两个List进行赋值
    for(int i = 0; i < 10; i++){
      mList.add(i);
      expandStateList.add(ExpandState(i,false));
    }
  }

  @override
  void initState () {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(title:Text('expansion tile demo')),
      body: SingleChildScrollView(
        child: ExpansionPanelList(
          /// 交互回调函数,包含点击项的index,和是否展开的bool值
          expansionCallback: (index, bool){
            _setExpandOpenOrClose(index, bool);
          },
          children: mList.map((index){
            return ExpansionPanel(
                headerBuilder: (context,isExpanded){
                  return ListTile(
                      title:Text('优帆远扬$index')
                  );
                },
                body: ListTile(
                    title:Text('北京优帆远扬$index')
                ),
                isExpanded: expandStateList[index].isOpen
            );
          }).toList(),
        )
      )
    );
  }
}

flutter 展开闭合案例 ExpansionTile与ExpansionPanelList

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 3

这嵌套层级估计是Flutter的梗了,看社区有没有推 第三方框架的,类似咸鱼出的之类的。

4年前 评论
Friday_ 4年前

@seebyyu 看起来写 Flutter 屏幕得竖起来才行 :smile:

4年前 评论

请问ExpansionTiles 怎么多级列表?

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!