Search code examples
flutterflutter-dependenciesflutter-animationfloating-action-button

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


Hello everyone,

hoping you are ok, i need your help, i get this error There are multiple heroes that share the same tag within a subtree every time i navigate to another page

being on MyIdemDetailsScreen I call my appbar,

class _MyItemDetailsScreenState extends State<MyItemDetailsScreen> {
  // ignore: prefer_typing_uninitialized_variables
  final GlobalKey<FormState> _forKey = GlobalKey<FormState>();
  TextEditingController counterTextEditingController = TextEditingController();
  forValidation() {
    if (counterTextEditingController.text.isNotEmpty) {
      int itemCounter = int.parse(counterTextEditingController.text);

      List<String> separateItemIDsList = separateItemIDs();

      //1.check if item exist already in cart
      separateItemIDsList.contains(widget.model!.itemID)
          ? Fluttertoast.showToast(msg: "Item is already in Cart.")
          :
          //2.add to cart
          addItemToCart(widget.model!.itemID, context, itemCounter);
    } else {
      showDialog(
          context: context,
          builder: (c) {
            return ErrorDialog(
              message: "Metter une valeur",
            );
          });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: const MyAppBar(),// i call  my appbar here
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Card(
              shape: const RoundedRectangleBorder(
                  borderRadius: BorderRadius.all(Radius.circular(8.0))),
              child: InkWell(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: <Widget>[
                    ClipRRect(
                      borderRadius: const BorderRadius.only(
                        topLeft: Radius.circular(8.0),
                        topRight: Radius.circular(8.0),
                      ),
                      child: Image.network(
                          widget.model!.thumbnailUrl.toString(),
                          height: 290,
                          fit: BoxFit.fill),
                    ),
                    ListTile(
                        title: Text(
                          textAlign: TextAlign.left,
                          widget.model!.title.toString().toUpperCase(),
                          style: const TextStyle(
                              fontWeight: FontWeight.bold, fontSize: 20),
                        ),
                        subtitle: Text(
                            textAlign: TextAlign.left,
                            widget.model!.shortInfo.toString(),
                            style: const TextStyle(
                                fontWeight: FontWeight.bold, fontSize: 20)))
                  ],
                ),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(18.0),
            child: Form(
                key: _forKey,
                child: Column(
                  children: [
                    TextFormField(
                      decoration:
                          const InputDecoration(labelText: "Enter your number"),
                      keyboardType: TextInputType.number,
                      controller: counterTextEditingController,
                      inputFormatters: [
                        FilteringTextInputFormatter.allow(
                          RegExp("[0-9]"),
                        ),
                      ],
                    ),
                  ],
                )),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Text(
              widget.model!.longDescription.toString(),
              textAlign: TextAlign.justify,
              style:
                  const TextStyle(fontWeight: FontWeight.normal, fontSize: 14),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Text(
              "${widget.model!.price} CDF",
              style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
            ),
          ),
          const SizedBox(
            height: 10,
          ),
          Center(
            child: InkWell(
              onTap: () {
                forValidation();
              },
              child: Container(
                decoration: const BoxDecoration(
                    gradient: LinearGradient(
                  colors: [
                    Colors.cyan,
                    Colors.amber,
                  ],
                  begin: FractionalOffset(0.0, 0.0),
                  end: FractionalOffset(1.0, 0.0),
                  stops: [0.0, 1.0],
                  tileMode: TileMode.clamp,
                )),
                width: MediaQuery.of(context).size.width - 13,
                height: 50,
                child: const Center(
                  child: Text(
                    "Add to Cart",
                    style: TextStyle(color: Colors.white, fontSize: 15),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

here is the code of my appbar

class _MyAppBarState extends State<MyAppBar> {
  @override
  Widget build(BuildContext context) {
    return AppBar(
      flexibleSpace: Container(
        decoration: const BoxDecoration(
            gradient: LinearGradient(
          colors: [
            Colors.cyan,
            Colors.amber,
          ],
          begin: FractionalOffset(0.0, 0.0),
          end: FractionalOffset(1.0, 0.0),
          stops: [0.0, 1.0],
          tileMode: TileMode.clamp,
        )),
      ),
      leading: IconButton(
          onPressed: () {
            Navigator.pop(context);
          },
          icon: const Icon(Icons.keyboard_backspace_outlined)),
      title: const Text(
        "iFood",
        style: TextStyle(
            fontSize: 45, fontFamily: "Signatra", color: Colors.white),
      ),
      centerTitle: true,
      automaticallyImplyLeading: true,
      actions: [
        Stack(
          children: [
            IconButton(
              icon: const Icon(
                Icons.shopping_cart,
                color: Colors.cyan,
              ),
              onPressed: () {
                //send user to cart screen
                Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (c) => CartItem(ifoodUID: widget.ifoodUID)));
              },
            ),
            Positioned(
              child: Stack(
                children: [
                  const Icon(
                    Icons.brightness_1,
                    size: 20.0,
                    color: Colors.green,
                  ),
                  Positioned(
                    top: 3,
                    right: 4,
                    child: Center(
                      child: Consumer<CartItemCounter>(
                        builder: (context, counter, c) {
                          return Text(
                            counter.count.toString(),
                            style: const TextStyle(
                                color: Colors.white, fontSize: 12),
                          );
                        },
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ],
    );
  }
}

and I call CartItem page

 @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          flexibleSpace: Container(
            decoration: const BoxDecoration(
                gradient: LinearGradient(
              colors: [
                Colors.cyan,
                Colors.amber,
              ],
              begin: FractionalOffset(0.0, 0.0),
              end: FractionalOffset(1.0, 0.0),
              stops: [0.0, 1.0],
              tileMode: TileMode.clamp,
            )),
          ),
          leading: IconButton(
            icon: const Icon(Icons.clear_all),
            onPressed: () {
              clearCartNow(context);
            },
          ),
          title: const Text(
            "iFood",
            style: TextStyle(fontSize: 45, fontFamily: "Signatra"),
          ),
          centerTitle: true,
          automaticallyImplyLeading: true,
          actions: [
            Stack(
              children: [
                IconButton(
                  icon: const Icon(
                    Icons.shopping_cart,
                    color: Colors.cyan,
                  ),
                  onPressed: () {
                    print("clicked");
                  },
                ),
                Positioned(
                  child: Stack(
                    children: [
                      const Icon(
                        Icons.brightness_1,
                        size: 20.0,
                        color: Colors.green,
                      ),
                      Positioned(
                        top: 3,
                        right: 4,
                        child: Center(
                            // child: Consumer<CartItemCounter>(
                            //   builder: (context, counter, c)
                            //   {
                            //     return Text(
                            //       counter.count.toString(),
                            //       style: const TextStyle(color: Colors.white, fontSize: 12),
                            //     );
                            //   },
                            // ),
                            ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ],
        ),
        floatingActionButton: Center(
            child: Stack(
          children: [
            RadialMenu(
              centerButtonAlignment: Alignment
                  .bottomCenter, // by default alignment is set to Alignment.center
              centerButtonSize: 0.5, // size ranging from 0.0 to 1.0
              children: [
                RadialButton(
                    icon: const Icon(Icons.navigate_next),
                    buttonColor: Colors.teal,
                    onPress: () {
                      clearCartNow(context);
                      //   Navigator.push(context, MaterialPageRoute(builder: (c)=> const MySplashScreen()));
                      Fluttertoast.showToast(msg: "Cart has been cleared.");
                    }),
                RadialButton(
                    icon: const Icon(Icons.clear_all),
                    buttonColor: Colors.green,
                    onPress: () {}),
                /* you can add any number of buttons, although it's 
                  not recommended to insert beyond 8-9 buttons. */
              ],
            ),
          ],
        )),
        body: const Center());
  }

and I always get this exception, please can you help me,

I've been thinking about this expression for days, and I can't fix it,

enter image description here


Solution

  • Generally, the usual cause of that error are Floating Action Buttons (FAB)s.

    traverse your application screens again searching for any FAB and provide a unique hero tag for each FAB.

    Column(
      children:[
           FloatinActionButton(
            heroTag: 'anyTag1',
            ...
           ),
           FloatinActionButton(
            heroTag: 'anyTag2',
            ...
           ),   
       ]
      )
    

    if you have many FABs in your app, the above code will be error-prone because it may lead to unintended duplicate of the same heroTag.

    So i recommend the following :

       FloatinActionButton(
        heroTag: UniqueKey().toString(),
        ...
       ),