老孟导读:Flutter组件有一个很大的特色,那就是很多复杂的组件都是通过一个一个小组件拼装而成的,今天就来说说系统的ExpansionPanelList是如何实现的。
在了解ExpansionPanelList实现前,先来了解下MergeableMaterial,它展示多个MergeableMaterialItem组件,当子组件发生变化时,以动画的方式打开或者关闭子组件,MergeableMaterial的父控件需要在主轴方向是一个没有限制的控件,比如SingleChildScrollView、Row、Column等。
基本用法如下:
SingleChildScrollView(
child: MergeableMaterial(
children: [
MaterialSlice(
key: ValueKey(1),child: Container(
height: 45,color: Colors.primaries[1 % Colors.primaries.length],)),MaterialGap(key: ValueKey(2)),MaterialSlice(
key: ValueKey(3),MaterialGap(key: ValueKey(4)),MaterialSlice(
key: ValueKey(5),],),)
效果如下:
MergeableMaterial的子控件只能是MaterialSlice和MaterialGap,MaterialSlice是带子控件的控件,显示实际内容,MaterialGap用于分割,只能放在MaterialSlice中间。
List<MergeableMaterialItem> items = [];
List.generate(_count,(index) {
items.add(MaterialSlice(
key: ValueKey(index * 2),child: Container(
height: 45,color: Colors.primaries[index % Colors.primaries.length],)));
});
return SingleChildScrollView(
child: MergeableMaterial(
children: items,)
效果如下:
增加分割线和阴影:
MergeableMaterial(
hasDividers: true,elevation: 24,children: items,)
效果如下:
阴影值不能随便设置,只能设置如下值:1,2,3,4,6,8,9,12,16,24
实现代码:
bool _expand = false;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Container(
height: 45,color: Colors.green.withOpacity(.3),alignment: Alignment.centerRight,child: IconButton(
icon: Icon(Icons.arrow_drop_down),onPressed: () {
setState(() {
_expand = !_expand;
});
},_expand
? MergeableMaterial(
hasDividers: true,children: [
MaterialSlice(
key: ValueKey(1),child: Container(
height: 200,))
],)
: Container(),Container(
height: 45,color: Colors.red.withOpacity(.3),);
}
看到这个效果是否想到了ExpansionPanelList呢?系统控件ExpansionPanelList就是使用此控件实现的。
交流
老孟Flutter博客地址(近200个控件用法):http://laomengit.com
欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】: