ExpansionTile是什么?
ExpansionTile其实就是一个类似于有一个标题可以展开的控件而已,就好比我们选择一个Title他就可以展开一些属于他的东西。例如我们点击一个服务,它会在下面展开一些服务的子项目。
我们看ExpansionTile的签名函数即构造函数
ExpansionTile({
Key key,
this.leading,//和ListTitle类似,在文字前面的Widget
@required this.title,//和ListTitle类似,文字
this.backgroundColor,//背景
this.onExpansionChanged,//展开或者关闭的监听
this.children = const <Widget>[],//内部孩子
this.trailing,//和ListTitle类似,右侧图标
this.initiallyExpanded = false,//默认是否展开
})
以上就是ExpansionTile的构造函数,我们可以看出他的某些参数的用处。(其实跟ListTitle的点击事件也是有点相通的,有兴趣的可以去源码看一下)。
刚开始
点击之后
不放gif了,至于过程脑洞自补。
代码如下:
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({Key key, this.title}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title:Text("ExpansionTileDemo"),
),
body: ListView(
children: <Widget>[
ExpansionTile(
title: Text("服务"),
children: <Widget>[
ListTile(title: Text("子服务1"),),
ListTile(title: Text("子服务2"),),
ListTile(title: Text("子服务3"),),
ListTile(title: Text("子服务4"),),
],
),
],
),
);
}
}
还有别的参数,有兴趣的可以自己去试试,不过常用的就是backgroundColor:(背景颜色) Colors.blueAccent.withOpacity(0.1),
和 initiallyExpanded: true,(自动展开)
还有leading和trailing属性,应该很熟了,他是左边和右边可以设置Widget。
但是有点细心的朋友会发现,点开之后的按钮从朝下,变成了朝上,这样我们就要使用动画的知识去改变了(后面补)。发现是旋转,那么就会用到相关的旋转函数RotationTransition
,至于图片我就不放了,因为就是右边按钮的样式换了。
代码如下:
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({Key key, this.title}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin{
Animation animation;
AnimationController animationController;
@override
void initState() {
super.initState();
animationController = new AnimationController(
vsync: this, //用这个方法必须实现接口TickerProviderStateMixin --别问为什么就是这样写....想知道的去看底层源码
duration: Duration(milliseconds: 200) //延迟、延时
);
animation = new Tween(begin: 0.0,end: 0.25).animate(animationController); //这里最大是1 而0.25是为了 0.25*360=90,刚好旋转90°
}
_changeOpacity(bool expand){
setState(() {
if(expand){
animationController.forward(); //正向
}else{
animationController.reverse(); //反向
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('ExpansionTile')
),
body: ListView(
children: <Widget>[
ExpansionTile(
title: Text('服务'),
backgroundColor: Colors.blueAccent.withOpacity(0.5),
initiallyExpanded: true,
leading: Icon(
Icons.person,
color: Colors.redAccent,
),
trailing: RotationTransition(
turns: animation,
child: const Icon(Icons.chevron_right),
),
onExpansionChanged: (bool) {
_changeOpacity(bool);
},
children: <Widget>[
ListTile(title: Text('子服务1'),),
ListTile(title: Text('子服务2'),),
ListTile(title: Text('子服务3'),),
ListTile(title: Text('子服务4'),),
]
)
]
)
);
}
}
这就是转变之后的了。
我写的应该是有问题的,因为最好还是要加一下释放!
@override
void dispose() {
// TODO: implement dispose
super.dispose();
animationController.dispose();
}
- 虽说你加不加看不出什么结果,但是如果你的项目大了,它会变得慢!
版权声明:本文为mubowen666原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。