Flutter AnimatedContainer 调整大小溢出问题
Flutter AnimatedContainer resizing overflow issue
在 gif 上可以清楚地看到,当点击切换按钮时,AnimatedContainer 的高度会根据枚举类型从 X 变为 Y,但只要它必须先变大,它就会溢出新添加的小部件。有办法解决这个问题吗?或者另一个可以帮助我实现预期动画的小部件?谢谢!
enum Company { FOUR, TWO }
class CompanyDemo extends StatefulWidget {
@override
_CompanyDemoState createState() => _CompanyDemoState();
}
class _CompanyDemoState extends State<CompanyDemo> {
Company _comp = Company.FOUR;
double containerHeight = 170;
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Padding(
padding: EdgeInsets.all(15.0),
child: Form(
key: _formKey,
child: Column(
children: [
AnimatedContainer(
height: containerHeight,
duration: Duration(seconds: 1),
padding: EdgeInsets.all(15),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: [
_comp == Company.TWO
? TextFormField(
decoration: InputDecoration(
labelText: 'CEO',
border: InputBorder.none,
prefixIcon: Icon(Icons.person),
),
)
: SizedBox(),
_comp == Company.TWO
? Divider(color: Colors.grey)
: SizedBox(),
TextFormField(
decoration: InputDecoration(
labelText: 'Head Directive',
border: InputBorder.none,
prefixIcon: Icon(Icons.people),
),
),
Divider(color: Colors.grey),
TextFormField(
decoration: InputDecoration(
labelText: 'Human Resources',
border: InputBorder.none,
prefixIcon: Icon(Icons.nature_people),
),
),
_comp == Company.TWO
? Divider(color: Colors.grey)
: SizedBox(),
_comp == Company.TWO
? TextFormField(
decoration: InputDecoration(
labelText: 'Slave',
border: InputBorder.none,
prefixIcon: Icon(Icons.person_pin),
),
)
: SizedBox(),
],
),
),
RaisedButton(
child: Text('Switch'),
onPressed: () {
setState(() {
_comp = _comp == Company.TWO ? Company.FOUR : Company.TWO;
containerHeight = _comp == Company.TWO ? 320 : 170;
});
},
),
],
),
),
),
);
}
}
要在内容更改时为小部件大小设置动画,您可以使用 AnimatedSize
Container(
padding: ...,
decoration: ...,
child: AnimatedSize(
vsync: this,
alignment: Alignment.topCenter,
duration: Duration(seconds: 1),
child: Column(
children: [
TextField(),
TextField(),
_comp == Company.TWO ? TextField() : SizedBox(),
_comp == Company.TWO ? TextField() : SizedBox(),
_comp == Company.TWO ? TextField() : SizedBox(),
_comp == Company.TWO ? TextField() : SizedBox(),
],
),
),
)
它会自动根据子内容推断大小,因此您无需在任何地方指定 height
。
P.S。要使 vsync: this
工作,请将 mixin 添加到您的状态 class:
class _CompanyDemoState extends State<CompanyDemo> with SingleTickerProviderStateMixin {
在 gif 上可以清楚地看到,当点击切换按钮时,AnimatedContainer 的高度会根据枚举类型从 X 变为 Y,但只要它必须先变大,它就会溢出新添加的小部件。有办法解决这个问题吗?或者另一个可以帮助我实现预期动画的小部件?谢谢!
enum Company { FOUR, TWO }
class CompanyDemo extends StatefulWidget {
@override
_CompanyDemoState createState() => _CompanyDemoState();
}
class _CompanyDemoState extends State<CompanyDemo> {
Company _comp = Company.FOUR;
double containerHeight = 170;
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Padding(
padding: EdgeInsets.all(15.0),
child: Form(
key: _formKey,
child: Column(
children: [
AnimatedContainer(
height: containerHeight,
duration: Duration(seconds: 1),
padding: EdgeInsets.all(15),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: [
_comp == Company.TWO
? TextFormField(
decoration: InputDecoration(
labelText: 'CEO',
border: InputBorder.none,
prefixIcon: Icon(Icons.person),
),
)
: SizedBox(),
_comp == Company.TWO
? Divider(color: Colors.grey)
: SizedBox(),
TextFormField(
decoration: InputDecoration(
labelText: 'Head Directive',
border: InputBorder.none,
prefixIcon: Icon(Icons.people),
),
),
Divider(color: Colors.grey),
TextFormField(
decoration: InputDecoration(
labelText: 'Human Resources',
border: InputBorder.none,
prefixIcon: Icon(Icons.nature_people),
),
),
_comp == Company.TWO
? Divider(color: Colors.grey)
: SizedBox(),
_comp == Company.TWO
? TextFormField(
decoration: InputDecoration(
labelText: 'Slave',
border: InputBorder.none,
prefixIcon: Icon(Icons.person_pin),
),
)
: SizedBox(),
],
),
),
RaisedButton(
child: Text('Switch'),
onPressed: () {
setState(() {
_comp = _comp == Company.TWO ? Company.FOUR : Company.TWO;
containerHeight = _comp == Company.TWO ? 320 : 170;
});
},
),
],
),
),
),
);
}
}
要在内容更改时为小部件大小设置动画,您可以使用 AnimatedSize
Container(
padding: ...,
decoration: ...,
child: AnimatedSize(
vsync: this,
alignment: Alignment.topCenter,
duration: Duration(seconds: 1),
child: Column(
children: [
TextField(),
TextField(),
_comp == Company.TWO ? TextField() : SizedBox(),
_comp == Company.TWO ? TextField() : SizedBox(),
_comp == Company.TWO ? TextField() : SizedBox(),
_comp == Company.TWO ? TextField() : SizedBox(),
],
),
),
)
它会自动根据子内容推断大小,因此您无需在任何地方指定 height
。
P.S。要使 vsync: this
工作,请将 mixin 添加到您的状态 class:
class _CompanyDemoState extends State<CompanyDemo> with SingleTickerProviderStateMixin {