Search code examples
flutterhero

There are multiple heroes that share the same tag within a subtree, I dont understand the issue


I want to use a hero widget. But Im getting this error and I dont really see where the mistake is:

The following assertion was thrown during a scheduler callback: There are multiple heroes that share the same tag within a subtree.

This is part of my Code where I use the Hero widget:

class _Scrapbook extends State<Scrapbook> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.symmetric(vertical:8.0, horizontal: 0.0),
        child: Stack(
          children:[
            Positioned(
              top: 80,
                bottom: 20,
                left: 100,
                child: Text("Scrapbook", style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold))
            ),
          Positioned(
            top: 120,
            bottom: 0,
            width: MediaQuery.of(context).size.width,
            child: Column(
              children: [
                Expanded(child: GridView.builder(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2,
                  childAspectRatio: 1.4,
                ),itemCount: 100,
                itemBuilder: (context, index) {
                  return InkWell(
                    child: Padding(
                      padding: const EdgeInsets.symmetric(vertical:4.0, horizontal: 6.0),
                      child: Hero(
                        tag: "dash",
                        child: Card(
                          color: Colors.amber,
                          semanticContainer: true,
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(10.0),
                          ),
                          child: Column(
                            children: [
                              Text("POI"),
                              Flexible(child: Image.asset("assets/images/Rathaus.jpg")),
                            ],
                          ),
                        ),
                      ),
                    ),
                    onTap: () {
                      Navigator.push(context, MaterialPageRoute(builder: (_) => ScrapbookDetails()));
                    },
                  );
                },
                ))
              ],
            ),
          ),
         ],
        ),
      )
    );
  }
}

And heres where I use it again:

class ScrapbookDetails extends StatefulWidget {
  const ScrapbookDetails({super.key});

  @override
  State<ScrapbookDetails> createState() => _ScrapbookDetails();
}

class _ScrapbookDetails extends State<ScrapbookDetails> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child:Hero(tag: "dash",
              child: Image.asset("assets/images/Rathaus.jpg")),
      ),
    );
  }
}

I would really appreciate if any of you could help. Thank you in advance!

I tried a solution from a different post, but it wasnt realy helpful.


Solution

  • Your itemBuilder retuning hero widget with same key,

     itemBuilder: (context, index) {
        return InkWell(
          child: Padding(
            padding: const EdgeInsets.symmetric(vertical:4.0, horizontal: 6.0),
              child: Hero(
                tag: "dash",
    

    You can pass the Hero key using constructor while it is inside the widget.

     itemBuilder: (context, index) {
        return InkWell(
          child: Padding(
            padding: const EdgeInsets.symmetric(vertical:4.0, horizontal: 6.0),
              child: Hero(
                tag: "dash $index",
    
             .........
             Navigator.push(context, MaterialPageRoute(builder: (_) => ScrapbookDetails(heroKey:"dash $index")));
    
    
    class ScrapbookDetails extends StatefulWidget {
      const ScrapbookDetails({super.key, required this.heroKey});
      final String heroKey;
    
      @override
      State<ScrapbookDetails> createState() => _ScrapbookDetails();
    }
    
    class _ScrapbookDetails extends State<ScrapbookDetails> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
              child:Hero(tag: widget.heroKey,
                  child: Image.asset("assets/images/Rathaus.jpg")),
          ),
        );
      }
    }