手機的螢幕本身就很小,所以要合理利用空間,把主要的元素展示出來,次要或者不重要的元素等使用者向看的時候再給使用者展示。這類操作最常見的互動就是展開和閉合了。
在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('重慶優帆天成')
)
]
)
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(),
)
)
);
}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結