📅  最后修改于: 2023-12-03 15:00:48.529000             🧑  作者: Mango
在Flutter中,扩展面板(Expansion Panel)是一个常用的交互控件,它可以让用户在需要时展开或收起一组相关的内容。本文将介绍如何使用Flutter中的扩展面板控件,让你轻松实现这个交互效果。
在Flutter中,使用扩展面板控件需要引入ExpansionPanel
和ExpansionPanelList
两个控件。其中,ExpansionPanel
表示一个可展开/收起的面板,而ExpansionPanelList
则是所有扩展面板的容器。
以下是一个最简单的例子,它演示了如何使用ExpansionPanelList
包含若干个ExpansionPanel
,并在其中展示一些基本信息。详见代码片段:
class _MyHomePageState extends State<MyHomePage> {
List<Item> _items = generateItems(10);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Expansion Panel Demo"),
),
body: ExpansionPanelList(
expansionCallback: (int index, bool isExpanded) {
setState(() {
_items[index].isExpanded = !isExpanded;
});
},
children: _items.map<ExpansionPanel>((Item item) {
return ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded) {
return ListTile(
title: Text(item.headerValue),
);
},
body: ListTile(
title: Text(item.expandedValue),
subtitle: Text('弹出框'),
trailing: Icon(Icons.add),
),
isExpanded: item.isExpanded,
);
}).toList(),
),
);
}
}
class Item {
String expandedValue;
String headerValue;
bool isExpanded;
Item({this.expandedValue, this.headerValue, this.isExpanded = false});
}
List<Item> generateItems(int numberOfItems) {
return List.generate(numberOfItems, (int index) {
return Item(
headerValue: 'Panel $index',
expandedValue: 'This is item number $index',
);
});
}
代码解释:generateItems
函数生成若干个Item
对象,每个Item
对象包含了一个常规信息和一个扩展信息,在下面的扩展面板中展示。ExpansionPanelList
控件的expansionCallback
参数接收的回调函数会在点击扩展面板时被调用,要求开发者更新isExpanded
状态,从而触发UI的重绘。控件的children
参数则接收一个List<ExpansionPanel>
,表示所有面板的集合。每个ExpansionPanel
需要配置headerBuilder
、body
、isExpanded
这三个参数:
headerBuilder
是一个回调函数,用于配置面板的头部,一般包含一个标题;body
用于配置面板展开时的内容,一般是一些复杂的布局或交互控件;isExpanded
表示面板是否展开,一般从数据模型中取而得。在渲染完成后,我们得到一个可见的列表,展示了所有的扩展面板。现在,你可以尝试依次点击每个面板,打开会暴露出“弹出框”这个文本的对话框。
默认情况下,扩展面板在展开和收起时没有任何过渡效果,显得十分生硬。然而,我们可以通过使用ExpansionPanelRadio
和ExpansionPanelRadioBuilder
两个控件,来实现扩展面板的自定义展开/收起效果。
ExpansionPanelRadio
表示带有状态转换效果的扩展面板,而ExpansionPanelRadioBuilder
是它的一个高级版本,可以定制扩展面板的每个方面,包括展开状态、头部、展开内容等等。
下面是一个ExpansionPanelRadioBuilder
的例子,它自定义了扩展面板的各个部分,除了可定制的header
和body
外,还支持扩展面板和头部的渐变动画。你可以根据自己的需要,再次修改以下的代码片段:
List<Item> _data = generateItems(10);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Expansion Panel Demo"),
),
body: SingleChildScrollView(
child: Container(
margin: EdgeInsets.all(24),
child: ExpansionPanelList.radio(
children: _data.map<ExpansionPanelRadio>((Item item) {
return ExpansionPanelRadioBuilder(
headerBackgroundColor: Colors.grey[300],
headerRadius: BorderRadius.circular(12),
canTapOnHeader: true,
body: ListTile(
title: Text(item.expandedValue),
subtitle: Text('弹出框'),
trailing: Icon(Icons.add),
),
value: item,
headerBuilder: (BuildContext context, Item value, bool isExpanded) {
return Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
gradient: isExpanded ? LinearGradient(
colors: [Colors.grey[400], Colors.grey[200]],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
) : null,
borderRadius: BorderRadius.circular(12),
),
child: Text(
value.headerValue,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
);
},
);
}).toList(),
expansionCallback: (int index, bool isExpanded) {
setState(() {
_data[index].isExpanded = !isExpanded;
});
},
),
),
),
);
}
Flutter中的扩展面板控件非常强大和灵活,它支持许多定制选项以及高效的动画效果,可以帮助开发者实现许多复杂的交互模式。如果想深入了解该控件的详细细节,建议查看官方文档和相关教程。