颤振错误:子树中有多个英雄共享同一标签

时间:2020-03-29 05:49:51

标签: flutter dart

我在使用Hero小部件时遇到错误。在对MaterialPageRoute进行一些更改之前,该小部件工作正常,但现在不起作用。我已经在SO上看到了几个关于同一问题的问题,但它们似乎都针对浮动操作按钮。我没有使用FAB,因此解决方案似乎不适用于我的问题。我认为此问题是由于我在TripPackage网格视图中使用索引这一事实引起的。它应该为每个图像分配一个新的索引和标签,但是似乎没有这样做。我收到以下消息:

错误消息:

Within each subtree for which heroes are to be animated (i.e. a PageRoute subtree), 
each Hero must have a unique non-null tag.
In this case, multiple heroes had the following tag: tag0

Here is the subtree for one of the offending heroes: Hero
  tag: tag0
  state: _HeroState#2a251
When the exception was thrown, this was the stack: 
#0 Hero._allHeroesFor.inviteHero.<anonymous closure> (package:flutter/src/widgets/heroes.dart:265:11)
#1 Hero._allHeroesFor.inviteHero (package:flutter/src/widgets/heroes.dart:276:8)
#2 Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:295:21)
#3 MultiChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:5534:16)
#4 Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:308:15)

TripPackages英雄

Container(
   margin: EdgeInsets.only(top: 1.0),
   child: SingleChildScrollView(
     child: StreamBuilder<QuerySnapshot>(
       stream: Firestore.instance.collection('trip_package').snapshots(),
       builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
         if (snapshot.hasError)
           return Text('Error: ${snapshot.error}');
         if (!snapshot.hasData)
           return Container(child: Center(child: CircularProgressIndicator()));
         final int docCount = snapshot.data.documents.length;
         return Column(
           children: snapshot.data.documents.map((doc) {
             return GridView.builder(
               shrinkWrap: true,
               primary: false,
               scrollDirection: Axis.vertical,
               itemCount: docCount,
               itemBuilder: (_, int index) {
                 DocumentSnapshot document = snapshot.data.documents[index];
                 return GestureDetector(
                   onTap: () {
                     var docId = doc.documentID;
                     var indexID = document;
                             Navigator.push(context,
                                 MaterialPageRoute(builder: (context) => IndividualTripPackage(docId, indexID)));},
                           child: Container(margin: EdgeInsets.all(3.0),
                             child: Column(mainAxisAlignment: MainAxisAlignment.center,
                               children: <Widget>[
                                 Row(mainAxisAlignment: MainAxisAlignment.center,
                                   crossAxisAlignment: CrossAxisAlignment.center,
                                   children: <Widget>[
                                     Stack(
                                       alignment: Alignment.topCenter,
                                       children: <Widget>[
                                         Container(...),
                                           child: Stack(
                                             children: <Widget>[
                                               Hero(
                                                 tag: 'tag$index',
                                                 child: ClipRRect(
                                                   borderRadius: BorderRadius.circular(20.0),
                                                   child: Image.network(
                                                     document.data['image'], height: 160.0, width: 180.0, fit: BoxFit.cover,
                                                   ),
                                                 ),
                                               ),

个人旅行包英雄:

class IndividualTripPackage extends StatefulWidget {
  final docId;
  final indexID;
  IndividualTripPackage(this.docId, this.indexID);

  @override
  State<StatefulWidget> createState() =>
      _IndividualTripPackageState(docId, indexID);
}

class _IndividualTripPackageState extends State<IndividualTripPackage> {
  final docId;
  final indexID;
  _IndividualTripPackageState(this.docId, this.indexID);

  @override
  Widget build(BuildContext context) {
    return Material(
      child: SafeArea(
        child: LayoutBuilder(
          builder: (BuildContext context, BoxConstraints viewportConstraints) {
            return SingleChildScrollView(
              child: ConstrainedBox(
                constraints: BoxConstraints(minHeight: viewportConstraints.maxHeight),
                child: StreamBuilder<DocumentSnapshot>(
                    stream: Firestore.instance.collection('trip_package').document(docId).snapshots(),
                    builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
                      if (snapshot.hasError)
                        return Text('Error: ${snapshot.error}');
                      if (!snapshot.hasData)
                        return Container(
                          child: Center(child: CircularProgressIndicator()));
                      final int itemCount = snapshot.data['itineraryItems'].length;
                      return Column(
                        children: <Widget>[
                          Stack(children: <Widget>[
                              Container(
                                padding: EdgeInsets.only(left: 10.0, top: 5.0, right: 10.0),
                                width: MediaQuery.of(context).size.width,
                                height: MediaQuery.of(context).size.height / 3,
                                decoration: BoxDecoration(borderRadius: BorderRadius.circular(30.0),
                                  boxShadow: [BoxShadow(color: Colors.black26, offset: Offset(0.0, 2.0), blurRadius: 6.0)]),
                                child: Hero(
                                  tag: 'tag$indexID',
                                  child: ClipRRect(
                                    borderRadius: BorderRadius.circular(30.0),
                                    child:
                                        Image.network(snapshot.data['image']),
                                  ),
                                ),
                              ),
//Some more code.....

2 个答案:

答案 0 :(得分:2)

您必须为每个英雄提供单独的密钥:

我认为以下代码可以解决您的问题。

 Hero(
     tag: index.toString(),
     child: ClipRRect(
     borderRadius: BorderRadius.circular(20.0),
     child: Image.network(

您在这里重复了很多次:

return Column(
           children: snapshot.data.documents.map((doc) {
             return GridView.builder(

我认为只需删除快照映射并返回网格视图即可解决您的问题,如下所示。

return Column(
           children: GridView.builder(

答案 1 :(得分:1)

我遇到了同样的问题,也没有使用浮动操作按钮。最终解决了我的问题的是我将导航从命名路线更改为匿名路线。

所以我有这个:

Navigator.pushNamed(context, DestinationScreen.routeName);

改为:

Navigator.push(context, MaterialPageRoute(builder: (_) {
       return ProductDetailsScreen();  }));

然后错误消失了。希望能帮助其他人,因为我花了几个小时才弄明白。