There are multiple heroes that share the same tag within a subtree
FlutterFlutter Problem Overview
I am trying to navigate from one screen to another with route. When I hit the button for the page to move to the route provided I get the error
I/flutter ( 8790): Another exception was thrown: There are multiple heroes that share the same tag within a subtree.
Here's the code:
Routes:
<String, WidgetBuilder>{
'/first':(BuildContext context) =>NavigatorOne() ,
'/second':(BuildContext context) =>NavigatorTwo(),
'/third':(BuildContext context) =>NavigatorThree(),
},
Navigator.of(context).pushNamed('/first');
Navigator.of(context).pushNamed('/second');
Navigator.of(context).pushNamed('/third');
class NavigatorOne extends StatefulWidget {
@override
_NavigatorOneState createState() => _NavigatorOneState();
}
class _NavigatorOneState extends State<NavigatorOne> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
color: Colors.green,
child: RaisedButton(child: Text(' one 1'),onPressed: (){
Navigator.of(context).pushNamed('/second');
},),
),
);
}
}
And The Error:
══╡ EXCEPTION CAUGHT BY SCHEDULER LIBRARY ╞═════════════════════════════════════════════════════════ I/flutter (21786): The following assertion was thrown during a scheduler callback: I/flutter (21786): There are multiple heroes that share the same tag within a subtree. I/flutter (21786): Within each subtree for which heroes are to be animated (typically a PageRoute subtree), each Hero I/flutter (21786): must have a unique non-null tag. I/flutter (21786): In this case, multiple heroes had the following tag: <default FloatingActionButton tag>
How do I solve this?
Flutter Solutions
Solution 1 - Flutter
I have encountered this before, and it was because I had two FloatingAction
buttons on one screen, I had to add a heroTag property + value per FloatingActionButton
in order for the error to go away.
Example:
FloatingActionButton(
heroTag: "btn1",
...
)
FloatingActionButton(
heroTag: "btn2",
...
)
From the example code you provided it doesn't appear that you have a FloatingActionButton
, but from the error it does seem to reference it:
I/flutter (21786): In this case, multiple heroes had the following tag: default FloatingActionButton tag
Perhaps you used it on the page you were navigating to which then triggered the error. Note that if you're using a programmatic way of creating tagged heroes, you will need to find a way of giving them different tags. For example, if you have a ListView.builder()
creating FloatingActionButtons
, try passing tags with string formatting so each button has a different tag, e.g.: heroTag: "btn$index"
.
In any event, hope that helps someone.
Solution 2 - Flutter
You can set a unique id or only set null
:
FloatingActionButton(
heroTag: null,
...
)
Solution 3 - Flutter
Just for Readers in the future:
in appreciate to @m.vincent comment, what cause this error for me is that i was using Hero inside SliverChildBuilderDelegate
which (obviously) has an index, so i used the index with the tag like 'tag$index'
like this
SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Hero(
tag: 'tagImage$index',
child: Image.asset(
'image source here',
),
),
NOTE : this may happen with any widget with index created children like ListView.Builder
Solution 4 - Flutter
For me, just adding a unique heroTag
to my FloatingActionButtons
didn't work. I ended up wrapping the heroTag
in a Text
widget and that solved the problem for me.
new FloatingActionButton(
heroTag: Text("btn1"),
...
)
new FloatingActionButton(
heroTag: Text("btn2"),
...
)
Solution 5 - Flutter
Add as many widgets as you like with hero tags as Strings
Widget floatingButt(Function function, IconData icon, String heroTag) {
return FloatingActionButton(
onPressed: function,
heroTag: heroTag,
materialTapTargetSize: MaterialTapTargetSize.padded,
backgroundColor: Constants.primaryColor, // from your values file
child: Icon(
icon,
size: 36.0,
),
);
}
Solution 6 - Flutter
I went through same Error. It is because of use of buttons like floating action button multiple times in single screen.
Previously I used a floating action button instead I changed it to a gesture detector to use ontap so it worked
GestureDetector(
//backgroundColor: Colors.amber[100],
onTap: add,
child: Icon(
FontAwesomeIcons.plus,
size: 30,
),
),
SizedBox(
width: 20,
),
GestureDetector(
// heroTag: "btn2",
// backgroundColor: Colors.amber[100],
onTap: sub,
child: Icon(FontAwesomeIcons.minus, size: 30),
),
Solution 7 - Flutter
This is correct because according to flutter documentations, it should be one Floating Action Button per route (Screen) unless you explicit set the hero tag.
> if this is not explicitly set, then there can only be one > FloatingActionButton per route (that is, per screen), since otherwise > there would be a tag conflict (multiple heroes on one route can't have > the same tag). The material design specification recommends only using > one floating action button per screen.
Solution 8 - Flutter
Simply set tag: Uuid()
if having multiple items with the same tag.
Solution 9 - Flutter
Simple solution of this heroTag issue is to provide this property as unique value. Either it can be a String value. In my case i provided it a String casted index value. And following is my solution which is working perfectly
FloatingActionButton(
onPressed: (){
print(index);
Navigator.push( context,
MaterialPageRoute( builder: (context)=> AddLead()
),
);
},
heroTag: '$index',
child: Image.asset('assets/pencil.png',height: 30, width: 30,), backgroundColor: Constants.myColor,
),
for more information follow this link https://wise4rmgodadmob.medium.com/how-to-solve-there-are-multiple-heroes-that-share-the-same-tag-within-a-subtree-a5146fdec2b8