iOS flutter 中的搜索栏动画

iOS search bar animation in flutter

我想在用户点击时在搜索栏中添加动画(就像 whatsApp 或 telegram 中的动画 [仅 iOS])

here is the animation

我使用了 Hero 小部件来执行此操作,但该小部件无法正常工作,我不知道为什么。这是我的代码

Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
  //some widgets above the search bar
  Hero(
    tag: 'search',
    child: Container(
      height: 38,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(32),
      ),
      child: TextField(
        cursorColor: Colors.blue,

        decoration: InputDecoration(
          hintStyle: TextStyle(fontSize: 16),
          hintText: "Search here",
          prefixIcon: Icon(Icons.search),
          border: InputBorder.none,
        ),
      ),
    ),
  ),
  //some more widgets here inside the column
])

这是第一页的部分代码,另一页只是搜索栏。 这是几乎相同的另一页

Widget build(BuildContext context) {
  return Scaffold(
    body: SafeArea(
      child: Hero(
        tag: 'search',
        child: Container(
          height: 38,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(32),
          ),
          child: TextField(
            cursorColor: Colors.blue,
            decoration: InputDecoration(
              hintStyle: TextStyle(fontSize: 16),
              hintText: "Search here",
              prefixIcon: Icon(Icons.search),
              border: InputBorder.none,
            ),
          ),
        ),
      ),
    ),
  );
}

请问还有其他方法吗?

编辑:它现在可以与 Hero 小部件一起正常工作,但它并没有像上面的 gif 那样显示确切的行为。应该怎么做,如果有人有其他方法可以实现,也可以回答。

Hero 在不同页面之间移动时使用(在上面的动画中)我们没有导航到任何其他页面,因此,删除 Hero 小部件

这可以通过 Transform.translate 结合 Flutter 中的 Opacity() 小部件来完成。

Transform.translate包裹相应的小部件创建一个Tween Animation并在Offset(dx, dy)的帮助下改变它的高度(在这种情况下dx将为0而dy将为变化的高度),负数dy 值将使小部件向上移动。也用 Opacity() 包裹起来,随着高度的变化而变化。

Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
  Transform.translate(
    offset: Offset(0, animatedHeightFromTweenAnimation)
    child: Opacity(
      opacity: animatedHeightFromTweenAnimation/maxHeightValue;
      child: anyWidget()
    )
  )
  Container(
    height: 38,
    decoration: BoxDecoration(
      borderRadius: BorderRadius.circular(32),
    ),
    child: TextField(
      cursorColor: Colors.blue,

      decoration: InputDecoration(
        hintStyle: TextStyle(fontSize: 16),
        hintText: "Search here",
        prefixIcon: Icon(Icons.search),
        border: InputBorder.none,
      ),
    ),
  ),//container
  RaisedButton(
    onPressed: () => controller.forward(), //here controller is animation controller
          //the above line will start the animation
    child: Text("press it"),
  ),
  //some more widgets here inside the column
])