How to add Hero animations to my ListView in Flutter?

1,893

Hero Tags should be different, so in your SliverList change your tag to this:

tag: 'flutterLogo${index}',

and pass the tag to your second page, like this(in case its a StatefulWidget):

class SecondPage extends StatefulWidget {
  final String heroTag;
  SecondPage({Key key, this.heroTag}) : super(key: key);

  @override
  _SecondPageState createState() => _SecondPageState();
}

and then instead of using a simple tag in your second page use something like this:

tag: widget.heroTag,
Share:
1,893
Simran Aswani
Author by

Simran Aswani

Updated on December 22, 2022

Comments

  • Simran Aswani
    Simran Aswani over 1 year

    I have a ListView that has cards as shown below. I am trying to animate the card to open in a bigger size upon being pressed.

    I have already achieved this for a single card however I can not understand how to do this for a ListView. Upon adding the Hero tag on the ListView elements, I get the following error:

    There are multiple heroes that share the same tag within a subtree.
    

    This is the animation.

    This is the code for the animation:

    The first Page:

      Widget build(BuildContext context) {
        return new Scaffold(
          body: Hero(
              tag: 'flutterLogo',
              child: GestureDetector(
                onTap: () => Navigator.push(context,
                    MaterialPageRoute(builder: (context) => AnimatedPage())),
                child: Card(
                  elevation: 4.0,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(12.0),
                  ),
                  child: Container(
                    height: 180,
                    width: 300,
                    color: Colors.blue,
                  ),
                ),
              )),
        );
      }
    

    The Second Page:

      Widget build(BuildContext context) {
        return new Scaffold(
          body: Stack(
            children: <Widget>[
              Hero(
                tag: 'flutterLogo',
                child: Padding(
                  padding: const EdgeInsets.only(top: 20.0),
                  child: Card(
                    elevation: 4.0,
                    color: Colors.red,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(12.0),
                    ),
                    child: Container(
                      height: 200,
                      width: 300,
                      child: Center(child: Text('Hello')),
                    ),
                  ),
                ),
              ),
            ],
          ),
        );
      }
    

    And this is the code for my ListView:

     SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Hero(
                  tag: 'flutterLogo',
                  child: Padding(
                    padding: const EdgeInsets.only(top: 10.0, bottom: 10),
                    child: GestureDetector(
                      onTap: () {
                        Navigator.push(context,
                            MaterialPageRoute(builder: (context) => PaymentPage()));
                      },
                      child: Card(
                        elevation: 4.0,
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(12.0),
                        ),
                        child: Container(
                          height: 180,
                          width: 150,
                        ),
                      ),
                    ),
                  ),
                );
              },
              childCount: 4,
            ),
          ),
    

    And this is what the list looks like: enter image description here

    I am trying to open the same second page as shown in the Animation, after clicking on the card in the List.

    • AskNilesh
      AskNilesh almost 4 years
    • Simran Aswani
      Simran Aswani almost 4 years
      I saw this however i cant understand how to implement this in my case @NileshRathod
    • dev-aentgs
      dev-aentgs almost 4 years
      Referring to the link by @NileshRathod, You can do something like this, in SliverList use tag: 'flutterLogo$index' and modify the SecondPage to take tag as a parameter like PaymentPage('flutterLogo$index') and use in this in the Hero widget on SecondPage