ExpansionPanel、ExpansionPanelRadio 是一种常见的折叠框。
ExpansionPanelList 是承载折叠框的一个父类控件。
1. ExpansionPanel
ExpansionPanel 定义
ExpansionPanel({
required this.headerBuilder,
required this.body,
this.isExpanded = false,
this.canTapOnHeader = false,
this.backgroundColor,
})
ExpansionPanel 属性
ExpansionPanel 属性 | 介绍 |
---|---|
headerBuilder | @required,Header Widget 构造方法 |
body | @required,展开部分 Widget |
isExpanded | 是否展开,默认为 false |
canTapOnHeader | 点击 header 是否可以展开收起,false |
backgroundColor | 背景色 |
2. ExpansionPanelRadio
ExpansionPanelRadio 定义
ExpansionPanelRadio({
required this.value,
required ExpansionPanelHeaderBuilder headerBuilder,
required Widget body,
bool canTapOnHeader = false,
Color? backgroundColor,
})
ExpansionPanelRadio属性
ExpansionPanelRadio属性 | 介绍 |
---|---|
value | @required 唯一标识 |
headerBuilder | @required Header Widget 构造方法 |
body | @required,展开部分 Widget |
canTapOnHeader | 是否可以点击 header 用来展开收起,false |
backgroundColor | 背景色 |
3. ExpansionPanelList
3.1 ExpansionPanelList 默认构造函数
ExpansionPanelList 定义
const ExpansionPanelList({
Key? key,
this.children = const <ExpansionPanel>[],
this.expansionCallback,
this.animationDuration = kThemeAnimationDuration,
this.expandedHeaderPadding = _kPanelHeaderExpandedDefaultPadding,
this.dividerColor,
this.elevation = 2,
})
ExpansionPanelList属性
ExpansionPanelList属性 | 介绍 |
---|---|
children | 子控件数组,List<ExpansionPanel> |
expansionCallback | 展开收起回调函数,(index, isExpand){},返回当前下标以及是否折叠 |
animationDuration | 动画时间,默认为 kThemeAnimationDuration |
expandedHeaderPadding | 展开后 Header 的 padding,默认为 _kPanelHeaderExpandedDefaultPadding |
dividerColor | 分割线颜色 |
elevation | 阴影大小 不可以随意设置,具体看kElevationToShadow |
3.2 ExpansionPanelList.radio
ExpansionPanelList.radio 定义
const ExpansionPanelList.radio({
Key? key,
this.children = const <ExpansionPanelRadio>[],
this.expansionCallback,
this.animationDuration = kThemeAnimationDuration,
this.initialOpenPanelValue,
this.expandedHeaderPadding = _kPanelHeaderExpandedDefaultPadding,
this.dividerColor,
this.elevation = 2,
})
ExpansionPanelList.radio属性
ExpansionPanelList.radio属性 | 介绍 |
---|---|
children | 子控件数组,List< ExpansionPanelRadio > |
expansionCallback | 展开收起回调函数,(index, isExpand){},返回当前下标以及是否折叠 |
animationDuration | 动画时间,默认为 kThemeAnimationDuration |
initialOpenPanelValue | 默认打开的ExpansionPanelRadio的标识 |
expandedHeaderPadding | 展开后 Header 的 padding,默认为 _kPanelHeaderExpandedDefaultPadding |
dividerColor | 分割线颜色 |
elevation | 阴影大小 不可以随意设置,具体看kElevationToShadow |
ExpansionPanelList.radio 对比ExpansionPanelList 默认构造函数,只增加了一个initialOpenPanelValue 属性
4. ExpansionPanelList 实例
示例1 ExpansionPanelList
class MSExpansionPanelListDemo extends StatefulWidget {
const MSExpansionPanelListDemo({Key? key}) : super(key: key);
@override
State<MSExpansionPanelListDemo> createState() =>
_MSExpansionPanelListDemoState();
}
class _MSExpansionPanelListDemoState extends State<MSExpansionPanelListDemo> {
List<MSExpansionPanelModel> _models = [];
@override
void initState() {
_models.add(MSExpansionPanelModel("EP1", "Title EP1", false));
_models.add(MSExpansionPanelModel("EP2", "Title EP2", false));
_models.add(MSExpansionPanelModel("EP3", "Title EP3", false));
_models.add(MSExpansionPanelModel("EP4", "Title EP4", false));
_models.add(MSExpansionPanelModel("EP5", "Title EP5", false));
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("ExpansionPanelListDemo")),
body: SingleChildScrollView(
child: _expansionPanelList(),
),
);
}
List<ExpansionPanel> _initChildrenForExpansionPanel() {
List<ExpansionPanel> _childrenForExpansionPanel = [];
_models.forEach((element) {
_childrenForExpansionPanel.add(_expansionPanelForModel(element));
});
return _childrenForExpansionPanel;
}
// 创建 ExpansionPanel
ExpansionPanel _expansionPanelForModel(MSExpansionPanelModel model) {
return ExpansionPanel(
// header 构造函数
headerBuilder: (context, isExpanded) {
return Container(
height: 56,
alignment: Alignment.centerLeft,
child: Text(model.title),
);
},
// body 展开部分 Widget
body: Container(
height: 100,
color: Colors.red,
),
// 是否展开
isExpanded: model.isExpanded,
// 点击 header 是否可以展开收起,false
canTapOnHeader: true,
// 背景色
backgroundColor: Colors.cyan[100],
);
}
// 创建 ExpansionPanelList
ExpansionPanelList _expansionPanelList() {
return ExpansionPanelList(
// 子控件数组 List<ExpansionPanel>
children: _initChildrenForExpansionPanel(),
// 分割线
dividerColor: Colors.green,
//动画时间,默认为 kThemeAnimationDuration
animationDuration: Duration(milliseconds: 200),
// 展开后 Header 的 padding,默认为 _kPanelHeaderExpandedDefaultPadding
expandedHeaderPadding: EdgeInsets.all(8),
// 展开收起回调函数,(index, isExpand){},返回当前下标以及是否折叠
expansionCallback: (index, isExpand) {
_models[index].isExpanded = !isExpand;
setState(() {});
},
// 阴影大小
elevation: 6,
);
}
}
class MSExpansionPanelModel {
var value;
String title;
bool isExpanded;
MSExpansionPanelModel(this.value, this.title, this.isExpanded);
}
129.gif
示例2 ExpansionPanelList.radio
class MSExpansionPanelListDemo2 extends StatefulWidget {
const MSExpansionPanelListDemo2({Key? key}) : super(key: key);
@override
State<MSExpansionPanelListDemo2> createState() =>
_MSExpansionPanelListDemo2State();
}
class _MSExpansionPanelListDemo2State extends State<MSExpansionPanelListDemo2> {
List<MSExpansionPanelModel> _models = [];
@override
void initState() {
_models.add(MSExpansionPanelModel("EP1", "Title EP1", false));
_models.add(MSExpansionPanelModel("EP2", "Title EP2", false));
_models.add(MSExpansionPanelModel("EP3", "Title EP3", false));
_models.add(MSExpansionPanelModel("EP4", "Title EP4", false));
_models.add(MSExpansionPanelModel("EP5", "Title EP5", false));
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("ExpansionPanelListDemo2")),
body: SingleChildScrollView(
child: _expansionPanelListForRadio(),
),
);
}
List<ExpansionPanelRadio> _initChildrenForExpansionPanelRadio() {
List<ExpansionPanelRadio> _childrenForExpansionPanelRadio = [];
_models.forEach((element) {
_childrenForExpansionPanelRadio
.add(_expansionPanelRadioForModle(element));
});
return _childrenForExpansionPanelRadio;
}
ExpansionPanelRadio _expansionPanelRadioForModle(
MSExpansionPanelModel model) {
return ExpansionPanelRadio(
// 唯一标识
value: model.value,
// Header Widget 构造方法
headerBuilder: (context, isExpanded) {
return Container(
height: 56,
alignment: Alignment.centerLeft,
child: Text(model.title),
);
},
// 展开部分 Widget
body: Container(
height: 100,
color: Colors.red,
),
// 是否可以点击 header 用来展开收起,false
canTapOnHeader: true,
// 背景色
backgroundColor: Colors.blue[100],
);
}
ExpansionPanelList _expansionPanelListForRadio() {
return ExpansionPanelList.radio(
// 子控件数组,List< ExpansionPanelRadio >
children: _initChildrenForExpansionPanelRadio(),
// 展开后 Header 的 padding,默认为 _kPanelHeaderExpandedDefaultPadding
expandedHeaderPadding: EdgeInsets.all(8),
// 展开收起回调函数,(index, isExpand){},返回当前下标以及是否折叠
expansionCallback: (index, isExpand) {
print("expansionCallback index $index, isExpand $isExpand");
},
// 默认打开的ExpansionPanelRadio的标识
initialOpenPanelValue: "EP2",
// 动画时间,默认为 kThemeAnimationDuration
animationDuration: Duration(milliseconds: 200),
// 分割线颜色
dividerColor: Colors.purple,
// 阴影大小 不可以随意设置,具体看kElevationToShadow
elevation: 6,
);
}
}
class MSExpansionPanelModel {
var value;
String title;
bool isExpanded;
MSExpansionPanelModel(this.value, this.title, this.isExpanded);
}
130.gif
ExpansionPanelList.radio 仅可以展开一个 ExpansionPanel,ExpansionPanelList 默认构造函数可以展开多个
5. 总结
- 注意 ExpansionPanel 不可以直接作为子控件给到 body,否则会报错,这里用了 SingleChildScrollView 作为外层容器,使用 Column、ListView...等很多控件都可以。
- 注意使用 ExpansionPanelList() 与 ExpansionPanelList.radio() 创建出来的 Widget,他们的 children 分别对应 <ExpansionPanel>,<ExpansionPanelRadio>,此处容易报错。
- 注意 ExpansionPanelRadio.value 不可以相同,容易报错。
网友评论