Search code examples
flutterflutter-animation

iOS search bar animation in flutter


I want to add a animation in a search bar when the user taps on it (just like the animation in whatsApp or telegram [only in iOS])

here is the animation

I used Hero widget to do so but the widget is not working, I don't know why. Here is my code for it

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
])

This is part of code for 1st page and the other page is just the search bar. This is the other page which is almost the same

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,
            ),
          ),
        ),
      ),
    ),
  );
}

Also is there any other way to do it?

EDIT: It's now working fine with Hero widget but it does not show that exact behaviour as in the above gif. How should I do that, if someone has any other method to achieve that, can also answer.


Solution

  • Hero is used when moving between different pages here(in the above animation) we are not navigating to any other page, so, remove the Hero widget

    This can be done with Transform.translate in combination with Opacity() widget in Flutter.

    Wrap the respective widget with Transform.translate create a Tween Animation and change its height with the help of Offset(dx, dy) (in this case dx will be 0 and dy will be the changing height), negative dy value will move the widget upwards. Also wrap it with Opacity() and change the value with the changing value of height.

    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
    ])