Flutter AnimatedCrossFade портит форматирование виджетов
Я пытаюсь создать плавную анимацию с помощью виджета AnimatedCrossFade, но заметил две проблемы:
Размер кнопки изменяется и расширяется во время анимации.
Желаемый результат состоит в том, чтобы обе кнопки соответствовали ширине родительского элемента и чтобы цвет и текст менялись плавно, но вот что происходит.
- Без AnimatedCrossFade, кнопка 1 выглядит следующим образом :
- Если я заключу его в виджет AnimatedCrossFade, кнопка 1 будет выглядеть так:
- Пока происходит переход, он выглядит так:
TextField с обводкой InputDecoration становится тоньше
У меня есть несколько виджетов 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: () {},
),
),
],
),
);
}
}
1 ответ
Надеюсь, это то, что ты хочешь?
Я думаю, чтобы справиться с этим случаем, вам нужно использовать
AnimatedCrossFade
если вы нажмете на
layoutBuilder
вы можете найти подробности.
Чтобы использовать максимальную ширину, я использовал вот так
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
layoutBuilder:
(topChild, topChildKey, bottomChild, bottomChildKey) {
return topChild;
},