Flutter AnimatedCrossFade 搞乱了小部件格式
Flutter AnimatedCrossFade messes up widget formatting
我正在尝试使用 AnimatedCrossFade 小部件创建流畅的动画,但我发现了 2 个问题:
按钮尺寸在动画期间发生变化和扩展。
期望的结果是两个按钮都与父按钮的宽度相匹配,并且颜色和文本的变化过渡平滑,但实际情况是这样的。
- 没有 AnimatedCrossFade,按钮 1 看起来像这样:
- 如果我将它包裹在 AnimatedCrossFade 小部件中,Button 1 看起来像这样:
- 在转换过程中,它看起来像这样:
带有 InputDecoration 笔触的 TextField 变得更细
我有多个要在页面中使用的 TextField 小部件,但有些需要在其中设置动画。问题是当我放置 TextField 在 AnimatedCrossFade 小部件中,底线变得更细,使布局看起来很糟糕。这是 TextField 在 AnimatedCrossFade 内部(顶部)和外部(底部)的对比。
- 这是动画后布局的样子。
- 但它应该是这样的。
此代码示例应该足以重现我要解释的内容。
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _isExpanded = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView(
padding: EdgeInsets.symmetric(horizontal: 60, vertical: 60),
children: [
ElevatedButton(
child: Text(_isExpanded ? "Collapse" : "Expand"),
onPressed: () {
setState(() {
_isExpanded = !_isExpanded;
});
},
),
AnimatedCrossFade(
crossFadeState: _isExpanded
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: const Duration(seconds: 1),
firstChild: TextField(
decoration: InputDecoration(
hintText: "Text",
),
),
secondChild: SizedBox.shrink(),
),
TextField(
decoration: InputDecoration(
hintText: "Text",
),
),
AnimatedCrossFade(
crossFadeState: !_isExpanded
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: Duration(seconds: 1),
firstChild: ElevatedButton(
child: Text("Button 1"),
onPressed: () {},
),
secondChild: ElevatedButton(
child: Text("Button 2"),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.red),
),
onPressed: () {},
),
),
],
),
);
}
}
希望这就是你想要的?
我认为要处理这种情况,您需要使用 layoutBuilder
of AnimatedCrossFade
如果你点击 layoutBuilder
你可以找到详细信息。
已更新
wrap with padding to solve TextFiledFormat
,更多可以使用decoration
。
要使用最大宽度我是这样使用的
AnimatedCrossFade(
crossFadeState: _isExpanded
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: const Duration(seconds: 1),
firstChild: Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: TextField(
key: ValueKey("text1"),
decoration: InputDecoration(
hintText: "Text1",
),
),
),
secondChild: SizedBox.shrink(),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: TextField(
key: ValueKey("text2"),
decoration: InputDecoration(
hintText: "Text",
),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: AnimatedCrossFade(
crossFadeState: !_isExpanded
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: Duration(seconds: 1),
alignment: Alignment.center,
layoutBuilder:
(topChild, topChildKey, bottomChild, bottomChildKey) {
return topChild;
},
secondChild: ElevatedButton(
child: Text("Button 2"),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.red),
),
onPressed: () {},
),
firstChild: ElevatedButton(
child: Text("Button 1"),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.red),
),
onPressed: () {},
),
),
),
在 layoutBuilder 中获取用 Center 包裹的按钮的默认大小
layoutBuilder:
(topChild, topChildKey, bottomChild, bottomChildKey) {
return topChild;
},
我正在尝试使用 AnimatedCrossFade 小部件创建流畅的动画,但我发现了 2 个问题:
按钮尺寸在动画期间发生变化和扩展。
期望的结果是两个按钮都与父按钮的宽度相匹配,并且颜色和文本的变化过渡平滑,但实际情况是这样的。
- 没有 AnimatedCrossFade,按钮 1 看起来像这样:
- 如果我将它包裹在 AnimatedCrossFade 小部件中,Button 1 看起来像这样:
- 在转换过程中,它看起来像这样:
带有 InputDecoration 笔触的 TextField 变得更细
我有多个要在页面中使用的 TextField 小部件,但有些需要在其中设置动画。问题是当我放置 TextField 在 AnimatedCrossFade 小部件中,底线变得更细,使布局看起来很糟糕。这是 TextField 在 AnimatedCrossFade 内部(顶部)和外部(底部)的对比。
- 这是动画后布局的样子。
- 但它应该是这样的。
此代码示例应该足以重现我要解释的内容。
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _isExpanded = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView(
padding: EdgeInsets.symmetric(horizontal: 60, vertical: 60),
children: [
ElevatedButton(
child: Text(_isExpanded ? "Collapse" : "Expand"),
onPressed: () {
setState(() {
_isExpanded = !_isExpanded;
});
},
),
AnimatedCrossFade(
crossFadeState: _isExpanded
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: const Duration(seconds: 1),
firstChild: TextField(
decoration: InputDecoration(
hintText: "Text",
),
),
secondChild: SizedBox.shrink(),
),
TextField(
decoration: InputDecoration(
hintText: "Text",
),
),
AnimatedCrossFade(
crossFadeState: !_isExpanded
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: Duration(seconds: 1),
firstChild: ElevatedButton(
child: Text("Button 1"),
onPressed: () {},
),
secondChild: ElevatedButton(
child: Text("Button 2"),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.red),
),
onPressed: () {},
),
),
],
),
);
}
}
希望这就是你想要的?
我认为要处理这种情况,您需要使用 layoutBuilder
of AnimatedCrossFade
如果你点击 layoutBuilder
你可以找到详细信息。
已更新
wrap with padding to solve TextFiledFormat
,更多可以使用decoration
。
要使用最大宽度我是这样使用的
AnimatedCrossFade(
crossFadeState: _isExpanded
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: const Duration(seconds: 1),
firstChild: Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: TextField(
key: ValueKey("text1"),
decoration: InputDecoration(
hintText: "Text1",
),
),
),
secondChild: SizedBox.shrink(),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: TextField(
key: ValueKey("text2"),
decoration: InputDecoration(
hintText: "Text",
),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: AnimatedCrossFade(
crossFadeState: !_isExpanded
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: Duration(seconds: 1),
alignment: Alignment.center,
layoutBuilder:
(topChild, topChildKey, bottomChild, bottomChildKey) {
return topChild;
},
secondChild: ElevatedButton(
child: Text("Button 2"),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.red),
),
onPressed: () {},
),
firstChild: ElevatedButton(
child: Text("Button 1"),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.red),
),
onPressed: () {},
),
),
),
在 layoutBuilder 中获取用 Center 包裹的按钮的默认大小
layoutBuilder:
(topChild, topChildKey, bottomChild, bottomChildKey) {
return topChild;
},