package:expandable: ^5.0.1
pub 地址:https://pub.flutter-io.cn/packages/expandable
功能:
功能:
- 展开/关闭的控件
使用实例和代码:
import 'dart:math' as math;
import 'package:expandable/expandable.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'Expandable Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
State createState() {
return MyHomePageState();
}
}
class MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Expandable Demo"),
),
body:
//设置默认主题,child 里面的expand 都会使用这个默认的主题,除非自己在定义
ExpandableTheme(
data: const ExpandableThemeData(
iconColor: Colors.blue, //展开折叠图标的颜色
useInkWell: true, //点击是否有水波纹的效果
),
child: ListView(
physics: const BouncingScrollPhysics(),
children: <Widget>[
//下面总共有三种效果展示
Card1(),
Card2(),
Card3(),
],
),
),
);
}
}
const loremIpsum =
"张九龄:感遇四首之一孤鸿海上来,池潢不敢顾。 侧见双翠鸟,巢在三珠树。 矫矫珍木巅,得无金丸惧。 美服患人指,高明逼神恶。 今我游冥冥,弋者何所慕。张九龄:感遇四首之二兰叶春";
class Card1 extends StatelessWidget {
const Card1({super.key});
Widget build(BuildContext context) {
return ExpandableNotifier(
child: Padding(
padding: const EdgeInsets.all(10),
child: Card(
clipBehavior: Clip.antiAlias, //剪切
child: Column(
children: <Widget>[
//定义了一个高度150 颜色是橘色的圆角色块
SizedBox(
height: 150,
child: Container(
decoration: const BoxDecoration(
color: Colors.orange,
shape: BoxShape.rectangle,
),
),
),
// 自动化滚动,点击展开,会滚动到可以阅读位置
ScrollOnExpand(
scrollOnExpand: true,
scrollOnCollapse: false,
child: ExpandablePanel(
theme: const ExpandableThemeData(
headerAlignment: ExpandablePanelHeaderAlignment.center,
tapBodyToCollapse: true,
),
//头部widge
header: Padding(
padding: EdgeInsets.all(10),
child: Text(
"ExpandablePanel",
style: Theme.of(context).textTheme.bodyText2,
)),
//简洁性质的内容显示出全部的部分,或者是开头部分,这边是显示两行,超过的...
collapsed: const Text(
loremIpsum,
softWrap: true,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
//展开要显示的内容
expanded: const Text(
'张九龄:感遇四首之一孤鸿海上来,池潢不敢顾。 侧见双翠鸟,巢在三珠树。 矫矫珍木巅,得无金丸惧。 美服患人指,高明逼神恶。 今我游冥冥,弋者何所慕。张九龄:感遇四首之二兰叶春张九龄:感遇四首之一孤鸿海上来,池潢不敢顾。 侧见双翠鸟,巢在三珠树。 矫矫珍木巅,得无金丸惧。 美服患人指,高明逼神恶。 今我游冥冥,弋者何所慕。张九龄:感遇四首之二兰叶春张九龄:感遇四首之一孤鸿海上来,池潢不敢顾。 侧见双翠鸟,巢在三珠树。 矫矫珍木巅,得无金丸惧。 美服患人指,高明逼神恶。 今我游冥冥,弋者何所慕。张九龄:感遇四首之二兰叶春张九龄:感遇四首之一孤鸿海上来,池潢不敢顾。 侧见双翠鸟,巢在三珠树。 矫矫珍木巅,得无金丸惧。 美服患人指,高明逼神恶。 今我游冥冥,弋者何所慕。张九龄:感遇四首之二兰叶春'),
//创建展开后的内widget
builder: (_, collapsed, expanded) {
return Padding(
padding:
const EdgeInsets.only(left: 10, right: 10, bottom: 10),
child: Expandable(
collapsed: collapsed,
expanded: expanded,
//下面的不起作用
// theme: const ExpandableThemeData(
// crossFadePoint: 0, iconColor: Colors.pink),
),
);
},
),
),
],
),
),
));
}
}
class Card2 extends StatelessWidget {
Widget build(BuildContext context) {
buildImg(Color color, double height) {
return SizedBox(
height: height,
child: Container(
decoration: BoxDecoration(
color: color,
shape: BoxShape.rectangle,
),
));
}
buildCollapsed1() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Expandable",
style: Theme.of(context).textTheme.bodyText1,
),
],
),
),
]);
}
buildCollapsed2() {
return buildImg(Colors.lightGreenAccent, 150);
}
buildCollapsed3() {
return Container();
}
buildExpanded1() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Expandable",
style: Theme.of(context).textTheme.bodyText1,
),
Text(
"3 Expandable widgets",
style: Theme.of(context).textTheme.caption,
),
],
),
),
]);
}
buildExpanded2() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Expanded(child: buildImg(Colors.lightGreenAccent, 100)),
Expanded(child: buildImg(Colors.orange, 100)),
],
),
Row(
children: <Widget>[
Expanded(child: buildImg(Colors.lightBlue, 100)),
Expanded(child: buildImg(Colors.cyan, 100)),
],
),
],
);
}
buildExpanded3() {
return Padding(
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
loremIpsum,
softWrap: true,
),
],
),
);
}
return ExpandableNotifier(
child: Padding(
padding: const EdgeInsets.only(left: 10, right: 10, bottom: 10),
child: ScrollOnExpand(
child: Card(
clipBehavior: Clip.antiAlias,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
//Expandable 基础Expand widget
Expandable(
//ui 上面显示的是标题,展开之后显示标题和简介
collapsed: buildCollapsed1(),
expanded: buildExpanded1(),
),
Expandable(
collapsed: buildCollapsed2(),
expanded: buildExpanded2(),
),
Expandable(
collapsed: buildCollapsed3(),
expanded: buildExpanded3(),
),
Divider(
height: 1,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Builder(
builder: (context) {
//控制器可以控制展开和折叠
var controller =
ExpandableController.of(context, required: true)!;
return TextButton(
child: Text(
controller.expanded ? "折叠" : "展开",
style: Theme.of(context)
.textTheme
.button!
.copyWith(color: Colors.deepPurple),
),
onPressed: () {
controller.toggle();
},
);
},
),
],
),
],
),
),
),
));
}
}
class Card3 extends StatelessWidget {
Widget build(BuildContext context) {
buildItem(String label) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: Text(label),
);
}
buildList() {
return Column(
children: <Widget>[
for (var i in [1, 2, 3, 4]) buildItem("数据 ${i}"),
],
);
}
return ExpandableNotifier(
child: Padding(
padding: const EdgeInsets.all(10),
child: ScrollOnExpand(
child: Card(
clipBehavior: Clip.antiAlias,
child: ExpandablePanel(
theme: const ExpandableThemeData(
headerAlignment: ExpandablePanelHeaderAlignment.center,
tapBodyToExpand: true,
tapBodyToCollapse: true,
hasIcon: false,
),
header: Container(
color: Colors.indigoAccent,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
children: [
//展开和收起的widget
ExpandableIcon(
theme: const ExpandableThemeData(
expandIcon: Icons.arrow_right,
collapseIcon: Icons.arrow_drop_down,
iconColor: Colors.white,
iconSize: 28.0,
iconRotationAngle: math.pi / 2,
iconPadding: EdgeInsets.only(right: 5),
hasIcon: false,
),
),
Expanded(
child: Text(
"列表数据",
style: Theme.of(context)
.textTheme
.bodyText1!
.copyWith(color: Colors.white),
),
),
],
),
),
),
collapsed: Container(),
expanded: buildList(),
),
),
),
));
}
}