How to have same page destination between multiple buttons using hero

1

I am trying to make a flutter app. Recently, I have learned how to use hero with two different buttons which all have the same destination. So, I tried to use hero with infinitely creatable containers. This is what I came up with:

import 'package:flutter/material.dart';

void main() => runApp(MainPage());

class MainPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
            backgroundColor: Colors.white,
            body: Column(children: <Widget>[
              Body(),
            ])));
  }
}

class Body extends StatefulWidget {
  @override
  _BodyState createState() => _BodyState();
}

class _BodyState extends State<Body> {
  final String open1 = 'open';

  int count = 1;

  @override
  Widget build(BuildContext context) {
    print(count);
    List cards = List.generate(count, (int i) => RCard(count));

    return Expanded(
        child: Container(
            child: NotificationListener<OverscrollIndicatorNotification>(
                onNotification: (OverscrollIndicatorNotification overscroll) {
                  overscroll.disallowGlow();
                },
                child: PageView.builder(
                    reverse: true,
                    pageSnapping: false,
                    controller: PageController(viewportFraction: 0.85),
                    itemCount: count,
                    itemBuilder: (context, i) {
                      if (i == 0) {
                        return GestureDetector(
                            onTap: () {
                              Navigator.push(
                                context,
                                MaterialPageRoute(
                                    builder: (context) => Page(
                                          open: open1,
                                        )),
                              );
                              count++;
                            },
                            child: Hero(
                                tag: open1,
                                child: Padding(
                                    padding: EdgeInsets.only(
                                        left:
                                            MediaQuery.of(context).size.height *
                                                0.015,
                                        right:
                                            MediaQuery.of(context).size.height *
                                                0.015,
                                        top: MediaQuery.of(context).size.width *
                                            0.08,
                                        bottom:
                                            MediaQuery.of(context).size.width *
                                                0.15),
                                    child: Material(
                                        borderRadius:
                                            BorderRadius.circular(40.0),
                                        color: Colors.white,
                                        elevation: 8.0,
                                        child: InkWell(
                                          child: Column(
                                              mainAxisAlignment:
                                                  MainAxisAlignment.center,
                                              children: <Widget>[
                                                Icon(
                                                  Icons.add,
                                                  size: 30.0,
                                                  color: Colors.black,
                                                )
                                              ]),
                                        )))));
                      } else {
                        return cards[i];
                      }
                    }))));
  }
}

class RCard extends StatefulWidget {
  final int count;

  RCard(this.count);

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

class RCardState extends State<RCard> {
  int count;
  String open2;
  @override
  void initState() {
    super.initState();
    count = widget.count;
    open2 = 'open$count';
  }

  @override
  Widget build(BuildContext context) {
    return Hero(
      tag: open2,
      child: GestureDetector(
          onTap: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                  builder: (context) => Page(
                        open: open2,
                      )),
            );
          },
          child: Padding(
            padding: EdgeInsets.only(
                left: MediaQuery.of(context).size.height * 0.015,
                right: MediaQuery.of(context).size.height * 0.015,
                top: MediaQuery.of(context).size.width * 0.08,
                bottom: MediaQuery.of(context).size.width * 0.15),
            child: Material(
                borderRadius: BorderRadius.circular(40.0),
                color: Colors.white,
                elevation: 8.0,
                child: Padding(
                  padding:
                      EdgeInsets.all(MediaQuery.of(context).size.width * 0.15),
                )),
          )),
    );
  }
}

class Page extends StatelessWidget {
  final String open;

  Page({this.open});

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      child: Hero(
          tag: open,
          child: Material(
            child: Center(child: Text('New page')),
          )),
      onTap: () {
        Navigator.pop(context);
      },
    );
  }
}

But, when I create a second container and press on it, It will give a black screen and get an error message in my debug console saying:

flutter: ══╡ EXCEPTION CAUGHT BY SCHEDULER LIBRARY ╞═════════════════════════════════════════════════════════
flutter: The following assertion was thrown during a scheduler callback:
flutter: There are multiple heroes that share the same tag within a subtree.
flutter: Within each subtree for which heroes are to be animated (typically a PageRoute subtree), each Hero
flutter: must have a unique non-null tag.
flutter: In this case, multiple heroes had the following tag: opennull
flutter: Here is the subtree for one of the offending heroes:
flutter: # Hero(tag: opennull, state: _HeroState#f299c)
flutter: # └KeyedSubtree-[GlobalKey#45266]
flutter: #  └GestureDetector
flutter: #   └RawGestureDetector(state: RawGestureDetectorState#98814(gestures: [tap]))
flutter: #    └_GestureSemantics(renderObject: RenderSemanticsGestureHandler#59110)
flutter: #     └Listener(listeners: [down], behavior: deferToChild, renderObject: RenderPointerListener#5cfa6)
flutter: #      └Padding(padding: EdgeInsets(13.4, 33.1, 13.4, 62.1), renderObject: RenderPadding#ab11d)
flutter: #       └Material(type: canvas, elevation: 8.0, color: Color(0xffffffff), borderRadius: circular(40.0), state: _MaterialState#a511a)
flutter: #        └_MaterialInterior(duration: 200ms, shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(40.0)), elevation: 8.0, color: Color(0xffffffff), shadowColor: Color(0xff000000), state: _MaterialInteriorState#6412f(ticker inactive))
flutter: #         └PhysicalShape(clipper: ShapeBorderClipper, elevation: 8.0, color: Color(0xffffffff), shadowColor: Color(0xff000000), renderObject: RenderPhysicalShape#1b504)
flutter: #          └_ShapeBorderPaint
flutter: #           └CustomPaint(renderObject: RenderCustomPaint#94831)
flutter: #            └NotificationListener<LayoutChangedNotification>
flutter: #             └_InkFeatures-[GlobalKey#8ef37 ink renderer](renderObject: _RenderInkFeatures#670e3)
flutter: #              └AnimatedDefaultTextStyle(duration: 200ms, debugLabel: (englishLike body1 2014).merge(blackCupertino body1), inherit: false, color: Color(0xdd000000), family: .SF UI Text, size: 14.0, weight: 400, baseline: alphabetic, decoration: TextDecoration.none, softWrap: wrapping at box width, overflow: clip, state: _AnimatedDefaultTextStyleState#9cb8b(ticker inactive))
flutter: #               └DefaultTextStyle(debugLabel: (englishLike body1 2014).merge(blackCupertino body1), inherit: false, color: Color(0xdd000000), family: .SF UI Text, size: 14.0, weight: 400, baseline: alphabetic, decoration: TextDecoration.none, softWrap: wrapping at box width, overflow: clip)
flutter: #                └Padding(padding: EdgeInsets.all(62.1), renderObject: RenderPadding#0a02b)
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0      Hero._allHeroesFor.visitor.<anonymous closure> 
package:flutter/…/widgets/heroes.dart:210
flutter: #1      Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:220
flutter: #2      ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #3      Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #4      SingleChildRenderObjectElement.visitChildren 
package:flutter/…/widgets/framework.dart:4848
flutter: #5      Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #6      SingleChildRenderObjectElement.visitChildren 
package:flutter/…/widgets/framework.dart:4848
flutter: #7      Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #8      ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #9      Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #10     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #11     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #12     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #13     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #14     List.forEach (dart:core/runtime/libgrowable_array.dart:278:8)
flutter: #15     SliverMultiBoxAdaptorElement.visitChildren 
package:flutter/…/widgets/sliver.dart:1175
flutter: #16     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #17     MultiChildRenderObjectElement.visitChildren 
package:flutter/…/widgets/framework.dart:4948
flutter: #18     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #19     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #20     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #21     SingleChildRenderObjectElement.visitChildren 
package:flutter/…/widgets/framework.dart:4848
flutter: #22     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #23     SingleChildRenderObjectElement.visitChildren 
package:flutter/…/widgets/framework.dart:4848
flutter: #24     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #25     SingleChildRenderObjectElement.visitChildren 
package:flutter/…/widgets/framework.dart:4848
flutter: #26     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #27     SingleChildRenderObjectElement.visitChildren 
package:flutter/…/widgets/framework.dart:4848
flutter: #28     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #29     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #30     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #31     SingleChildRenderObjectElement.visitChildren 
package:flutter/…/widgets/framework.dart:4848
flutter: #32     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #33     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #34     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #35     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #36     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #37     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #38     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #39     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #40     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #41     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #42     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #43     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #44     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #45     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #46     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #47     MultiChildRenderObjectElement.visitChildren 
package:flutter/…/widgets/framework.dart:4948
flutter: #48     Hero._allHeroesFor.visitor 
flutter: #49     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #50     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #51     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #52     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #53     MultiChildRenderObjectElement.visitChildren 
package:flutter/…/widgets/framework.dart:4948
flutter: #54     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #55     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #56     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #57     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #58     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #59     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #60     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #61     SingleChildRenderObjectElement.visitChildren 
package:flutter/…/widgets/framework.dart:4848
flutter: #62     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #63     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #64     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #65     SingleChildRenderObjectElement.visitChildren 
package:flutter/…/widgets/framework.dart:4848
flutter: #66     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #67     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #68     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #69     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #70     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #71     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #72     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #73     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #74     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #75     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #76     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #77     SingleChildRenderObjectElement.visitChildren 
package:flutter/…/widgets/framework.dart:4848
flutter: #78     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #79     ComponentElement.visitChildren 
package:flutter/…/widgets/framework.dart:3755
flutter: #80     Hero._allHeroesFor.visitor 
package:flutter/…/widgets/heroes.dart:225
flutter: #81     SingleChildRenderObjectElement.visitChildren 
package:flutter/…/widgets/framework.dart:4848
flutter: #82     Element.visitChildElements 
package:flutter/…/widgets/framework.dart:2686
flutter: #83     Hero._allHeroesFor 
package:flutter/…/widgets/heroes.dart:227
flutter: #84     HeroController._startHeroTransition 
package:flutter/…/widgets/heroes.dart:655
flutter: #85     HeroController._maybeStartHeroTransition.<anonymous closure> 
package:flutter/…/widgets/heroes.dart:630
flutter: #86     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback 
package:flutter/…/scheduler/binding.dart:990
flutter: #87     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame 
package:flutter/…/scheduler/binding.dart:938
flutter: #88     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame 
package:flutter/…/scheduler/binding.dart:842
flutter: #89     _invoke (dart:ui/hooks.dart:154:13)
flutter: #90     _drawFrame (dart:ui/hooks.dart:143:3)
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════

How anyone please help???

dart
flutter
asked on Stack Overflow Feb 15, 2019 by Extra • edited Feb 25, 2019 by Extra

1 Answer

1

Instead of doing - List.generate in build. Simply Pass RCard directly in PageView.builder

working Code:

 import 'package:flutter/material.dart';

    void main() => runApp(MainPage());

    class MainPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            debugShowCheckedModeBanner: false,
            home: Scaffold(
                backgroundColor: Colors.white,
                body: Column(children: <Widget>[
                  Body(),
                ])));
      }
    }

    class Body extends StatefulWidget {
      @override
      _BodyState createState() => _BodyState();
    }

    class _BodyState extends State<Body> {
      final String open1 = 'open';

      int count = 1;

      @override
      Widget build(BuildContext context) {
        print(count);
        return Expanded(
            child: Container(
                child: NotificationListener<OverscrollIndicatorNotification>(
                    onNotification: (OverscrollIndicatorNotification overscroll) {
                      overscroll.disallowGlow();
                    },
                    child: PageView.builder(
                        reverse: true,
                        pageSnapping: false,
                        controller: PageController(viewportFraction: 0.85),
                        itemCount: count,
                        itemBuilder: (context, i) {
                          if (i == 0) {
                            return GestureDetector(
                                onTap: () {
                                  Navigator.push(
                                    context,
                                    MaterialPageRoute(
                                        builder: (context) => Page(
                                          open: open1,
                                        )),
                                  );
                                  count++;
                                },
                                child: Hero(
                                    tag: open1,
                                    child: Padding(
                                        padding: EdgeInsets.only(
                                            left:
                                            MediaQuery.of(context).size.height *
                                                0.015,
                                            right:
                                            MediaQuery.of(context).size.height *
                                                0.015,
                                            top: MediaQuery.of(context).size.width *
                                                0.08,
                                            bottom:
                                            MediaQuery.of(context).size.width *
                                                0.15),
                                        child: Material(
                                            borderRadius:
                                            BorderRadius.circular(40.0),
                                            color: Colors.white,
                                            elevation: 8.0,
                                            child: InkWell(
                                              child: Column(
                                                  mainAxisAlignment:
                                                  MainAxisAlignment.center,
                                                  children: <Widget>[
                                                    Icon(
                                                      Icons.add,
                                                      size: 30.0,
                                                      color: Colors.black,
                                                    )
                                                  ]),
                                            )))));
                          } else {
                            return RCard(i);
                          }
                        }))));
      }
    }

    class RCard extends StatefulWidget {
      final int count;

      RCard(this.count);

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

    class RCardState extends State<RCard> {
      int count;
      String open2;
      @override
      void initState() {
        super.initState();
        count = widget.count;
        open2 = 'open$count';
      }

      @override
      Widget build(BuildContext context) {
        return Hero(
          tag: open2,
          child: GestureDetector(
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (context) => Page(
                        open: open2,
                      )),
                );
              },
              child: Padding(
                padding: EdgeInsets.only(
                    left: MediaQuery.of(context).size.height * 0.015,
                    right: MediaQuery.of(context).size.height * 0.015,
                    top: MediaQuery.of(context).size.width * 0.08,
                    bottom: MediaQuery.of(context).size.width * 0.15),
                child: Material(
                    borderRadius: BorderRadius.circular(40.0),
                    color: Colors.white,
                    elevation: 8.0,
                    child: Padding(
                      padding:
                      EdgeInsets.all(MediaQuery.of(context).size.width * 0.15),
                    )),
              )),
        );
      }
    }

    class Page extends StatelessWidget {
      final String open;

      Page({this.open});

      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          child: Hero(
              tag: open,
              child: Material(
                child: Center(child: Text('New page')),
              )),
          onTap: () {
            Navigator.pop(context);
          },
        );
      }
    }
answered on Stack Overflow Feb 25, 2019 by anmol.majhail

User contributions licensed under CC BY-SA 3.0