Flutter AnimatedSwitcher 在孩子之间跳转

Mat*_*ier 6 dart flutter flutter-animation

我正在尝试在扩展面板列表中实现一些自定义设计。因此,我想创建某种动画,可以从一个视图(例如标题)平滑地动画到具有其他尺寸的另一个视图(例如图块的完整信息)(显然,完整信息将高于标题)。使用 AnimatedContainer 可以很容易地实现这一点。但是,我需要标题小部件和完整信息小部件的高度,以便在这两个高度之间进行动画处理。由于这些值在图块之间有所不同(其他信息 -> 可能是其他高度),并且通过全局键跟踪高度不是我的首选解决方案,因此我决定使用更简单的 AnimatedSwitcher 来代替。然而,我的 AnimatedSwitcher 的行为很奇怪。首先,ListView 中的其他图块(在我的示例中为按钮)立即向下移动,随后图块展开。有谁知道我如何实现一些代码,以实现与我从 AnimatedContainer 获得的相同动画(按钮/其他图块随着图块展开同时向下移动)?预先感谢您的任何建议。这是我的代码:

class MyPage extends State {
List _items;
int pos;

@override
void initState() {
pos = 0;
_items = [
  Container(
    color: Colors.white,
    width: 30,
    key: UniqueKey(),
    child: Column(
      children: <Widget>[Text('1'), Text('2')], //example that should visualise different heights
    ),
  ),
  Container(
    width: 30,
    color: Colors.white,
    key: UniqueKey(),
    child: Column(
      children: <Widget>[Text('1'), Text('2'), Text('44534'), Text('534534')],
    ),
  )
];
super.initState();
}

@override
Widget build(BuildContext context) {

return Scaffold(
  body: ListView(
    padding: EdgeInsets.only(top: 100),
    children: <Widget>[
      AnimatedSwitcher(
        duration: Duration(seconds: 1),
        transitionBuilder: (child, animation) => ScaleTransition(
          child: child,
          scale: animation,
        ),
        child: _items[pos],
      ),
      RaisedButton(
          child: Text('change'),
          onPressed: pos == 0
              ? () {
                  setState(() => pos = 1);
                }
              : () {
                  setState(() => pos = 0);
                })
    ],
  ),
);
}
}
Run Code Online (Sandbox Code Playgroud)

解决方案非常简单。刚刚发现有一个 AnimatedSize Widget 可以自动找出其子级的大小。

gba*_*tta 2

我偶然发现了这篇文章,因为我遇到了类似的问题,所以我决定在这里创建一个关于如何混合和解决这个问题的教程。动画不会同时发生,但优点是您可以完全控制提供给切换器的动画。AnimatedSwitcherAnimatedSize

我最终做到了这一点(请注意,我正在使用BlocBuilder,这AnimatedSizeWidget是一个基本实现AnimatedSize

    AnimatedSizeWidget(
              duration: const Duration(milliseconds: 250),
              child: BlocBuilder<SwapCubit, bool>(
                builder: (context, state) {
                  return AnimatedSwitcher(
                    duration: const Duration(milliseconds: 1000),
                    child: state
                        ? Icon(Icons.face, size: 80, key: Key("80"))
                        : Icon(Icons.face, size: 160, key: Key("160")),
                  );
                },
              ),
            ),
Run Code Online (Sandbox Code Playgroud)