Flutter - 隐藏其中一个 Column 子项时高度的动画变化
Flutter - Animate change on height when hide one of Column children
我在 Column
小部件中有两个子项,第一个是简单的 Container
,第二个是 Expanded
小部件。
用户可以 hide/show 第一个 Container
。在这种情况下,我需要在两个小部件上应用动画,因此第一个容器的高度应该自动降低,第二个小部件应该逐渐增加直到填满整个 space.
我测试使用AnimatedContainer
,但是需要指定前后高度,我不知道。
有什么建议吗?
class ViewerPage extends StatefulWidget {
@override
_ViewerPageState createState() => _ViewerPageState();
}
class _ViewerPageState extends State<ViewerPage> {
bool visible = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Example"),
),
bottomNavigationBar: BottomAppBar(
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
icon: Icon(Icons.show_chart),
onPressed: () {
setState(() {
visible = !visible;
});
},
),
],
),
),
body: Container(
child: Column(
children: <Widget>[
Visibility(
visible: visible,
child: Container(
child: Text("This Container can be visible or hidden"),
color: Colors.red),
),
Expanded(
child: ListView.builder(
itemBuilder: (context, index) => Text("Item ..."),
itemCount: 20,
),
),
],
),
),
);
}
}
简单,使用 AnimatedSize,并移除 Visibility。 AnimatedSize 自行计算高度。所以你不需要知道之前和之后的尺寸。
在这里,我稍微更改了您的代码。现在可以正常使用了。
import 'package:flutter/material.dart';
class Test extends StatefulWidget {
@override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> with SingleTickerProviderStateMixin{
bool visible = true;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Example"),
),
bottomNavigationBar: BottomAppBar(
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
icon: Icon(Icons.show_chart),
onPressed: () {
setState(() {
visible = !visible;
});
},
),
],
),
),
body: Container(
child: Column(
children: <Widget>[
AnimatedSize(
duration: Duration(seconds: 1),
child: Container(
height: visible? null : 0.0,
child: Text("This Container can be visible or hidden"),
color: Colors.red
),
vsync: this,
),
Expanded(
child: ListView.builder(
itemBuilder: (context, index) => Text("Item ..."),
itemCount: 20,
),
),
],
),
),
);
}
}
我在 Column
小部件中有两个子项,第一个是简单的 Container
,第二个是 Expanded
小部件。
用户可以 hide/show 第一个 Container
。在这种情况下,我需要在两个小部件上应用动画,因此第一个容器的高度应该自动降低,第二个小部件应该逐渐增加直到填满整个 space.
我测试使用AnimatedContainer
,但是需要指定前后高度,我不知道。
有什么建议吗?
class ViewerPage extends StatefulWidget {
@override
_ViewerPageState createState() => _ViewerPageState();
}
class _ViewerPageState extends State<ViewerPage> {
bool visible = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Example"),
),
bottomNavigationBar: BottomAppBar(
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
icon: Icon(Icons.show_chart),
onPressed: () {
setState(() {
visible = !visible;
});
},
),
],
),
),
body: Container(
child: Column(
children: <Widget>[
Visibility(
visible: visible,
child: Container(
child: Text("This Container can be visible or hidden"),
color: Colors.red),
),
Expanded(
child: ListView.builder(
itemBuilder: (context, index) => Text("Item ..."),
itemCount: 20,
),
),
],
),
),
);
}
}
简单,使用 AnimatedSize,并移除 Visibility。 AnimatedSize 自行计算高度。所以你不需要知道之前和之后的尺寸。
在这里,我稍微更改了您的代码。现在可以正常使用了。
import 'package:flutter/material.dart';
class Test extends StatefulWidget {
@override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> with SingleTickerProviderStateMixin{
bool visible = true;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Example"),
),
bottomNavigationBar: BottomAppBar(
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
icon: Icon(Icons.show_chart),
onPressed: () {
setState(() {
visible = !visible;
});
},
),
],
),
),
body: Container(
child: Column(
children: <Widget>[
AnimatedSize(
duration: Duration(seconds: 1),
child: Container(
height: visible? null : 0.0,
child: Text("This Container can be visible or hidden"),
color: Colors.red
),
vsync: this,
),
Expanded(
child: ListView.builder(
itemBuilder: (context, index) => Text("Item ..."),
itemCount: 20,
),
),
],
),
),
);
}
}