flutter 展開閉合案例 ExpansionTile 與 ExpansionPanelList

tabbin發表於2019-07-24

手機的螢幕本身就很小,所以要合理利用空間,把主要的元素展示出來,次要或者不重要的元素等使用者向看的時候再給使用者展示。這類操作最常見的互動就是展開和閉合了。

在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

相關文章