FlutterError : The key [LabeledGlobalKey<FormState>] was used by multiple widgets

145

My mistake was including the form inside the ListView.builder().

So , I solved the error by changing the code to this :

Form(
  key: menuformKey,
  child: ListView.builder(
     shrinkWrap: true,
     itemCount: widget.menu.categories.length,
     itemBuilder: (context, i) {
     Category categoryItem = widget.menu.categories[i];
     return ListView(
         primary: false,
         shrinkWrap: true,
         children: [
             Column(
                children: [
                   Padding(
                      padding: EdgeInsets.symmetric(
                      horizontal: screenWidth * .1),
                      child: TextFormField(
                      initialValue: categoryItem.title,
                      onSaved: (value) {
                      categoryItem.setTitle = value!;
                      },
                      ),
                   ),
                   ListView.builder(
                      primary: true,
                      shrinkWrap: true,
                      itemCount: categoryItem.items.length,
                      itemBuilder: (context, j) {
                      Meal mealItem = categoryItem.items[j];
                          return Container(
                             margin: EdgeInsets.only(
                                top: 20, left: 20, right: 20),
                             width: double.infinity,
                             height: screenHeight * .15,
                             color: widget.dark
                             ? primaryDarkColor
                             : primaryLightColor,
                               child: ListTile(
                                  leading: Container(
                                    height: screenHeight * .5,
                                    width: screenWidth * .2,
                                    child: Stack(
                                      children: [
                                        FittedBox(
                                          child:  Image.asset(mealItem.imgPath,)
                                        ),
                                        IconButton(
                                          onPressed: () async {
                                            final XFile? pickedImage =
                                                await _picker.pickImage(
                                                    source:
                                                        ImageSource.gallery);
                                            if (pickedImage != null) {
                                              setState(
                                                () {
                                                  mealItem.setImgPath =
                                                      pickedImage.path;
                                                  _images[j] =
                                                      File(pickedImage.path);
                                                  print(pickedImage.path);
                                                },
                                              );
                                            }
                                          },
                                          icon: Icon(
                                            Icons.edit,
                                            color: Colors.white,
                                            size: 20,
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                  title: TextFormField(
                                    initialValue: mealItem.name,
                                    onSaved: (value) {
                                      mealItem.setName = value!;
                                    },
                                  ),
                                  subtitle: TextFormField(
                                    initialValue: "${mealItem.price}",
                                    onSaved: (value) {
                                      mealItem.setPrice = double.parse(value!);
                                    },
                                  ),
                                  trailing: IconButton(
                                    onPressed: () {
                                      categoryItem.items.remove(mealItem);
                                    },
                                    icon: Icon(
                                      Icons.delete,
                                      color: Colors.red,
                                    ),
                                  ),
                                ),
                              );
                            },
                          ),
                        ],
                      );
                    },
                  ),
                );
Share:
145
Admin
Author by

Admin

Updated on January 04, 2023

Comments

  • Admin
    Admin over 1 year

    I'm getting an error while trying to navigate to the menu_screen widget. I'm pretty sure that the GlobalKey menuFormKey is not used inside another widget but I don't understand why I'm getting this problem.

    There is the code of menu_screen :

    import 'dart:async';
    
    import 'package:flutter/material.dart';
    
    class MenuScreen extends StatefulWidget {
      bool dark;
      Menu menu;
      MenuScreen({Key? key, required this.dark, required this.menu})
          : super(key: RIKeys.riKey3);
    
      @override
      State<MenuScreen> createState() => _MenuScreenState();
      static String id = "MenuScreen";
    }
    
    class _MenuScreenState extends State<MenuScreen> {
      final StreamController<Menu> _currentMenuStreamCtrl =
          StreamController<Menu>.broadcast();
      Stream<Menu> get onCurrentMenuChanged => _currentMenuStreamCtrl.stream;
      void updateCurrentMenuUI() => _currentMenuStreamCtrl.add(widget.menu);
      GlobalKey<FormState> menuformKey =
          GlobalKey<FormState>(debugLabel: "menu form Key");
      @override
      Widget build(BuildContext context) {
        Size deviceSize = MediaQuery.of(context).size;
        Orientation deviceOrientation = MediaQuery.of(context).orientation;
        bool isPortrait = deviceOrientation == Orientation.portrait;
        double screenWidth = isPortrait ? deviceSize.width : deviceSize.height;
        double screenHeight = isPortrait ? deviceSize.height : deviceSize.width;
        return MaterialApp(
          home: SafeArea(
            child: Scaffold(
              appBar: AppBar(
                leading: IconButton(
                  icon: Icon(Icons.arrow_back),
                  onPressed: () {
                    Navigator.pop(context);
                  },
                ),
                title: Text(
                  "Modify Menu",
                  style: TextStyle(
                    color: widget.dark ? Colors.black : Colors.white,
                  ),
                ),
                actions: [
                  IconButton(
                    onPressed: () {
                      if (menuformKey.currentState!.validate()) {
                        menuformKey.currentState!.save();
                        Navigator.pop(context);
                      }
                    },
                    icon: Icon(
                      Icons.done_outline,
                      color: widget.dark ? Colors.black : Colors.white,
                    ),
                  ),
                ],
                backgroundColor:
                    !widget.dark ? backgroundDarkColor : backgroundLightColor,
              ),
              body: StreamBuilder(
                initialData: widget.menu,
                stream: onCurrentMenuChanged,
                builder: (context, AsyncSnapshot<Menu> snapshot) {
                  late Widget builtWidget;
                  if (snapshot.hasData) {
                    builtWidget = ListView.builder(
                      itemCount: widget.menu.categories.length,
                      itemBuilder: (context, i) {
                        Category categoryItem = widget.menu.categories[i];
                        return Form(
                          key: menuformKey,
                          child: ListView(
                            shrinkWrap: true,
                            children: [
                              Padding(
                                padding: EdgeInsets.symmetric(
                                    horizontal: screenWidth * .1),
                                child: TextFormField(
                                  initialValue: categoryItem.title,
                                  onSaved: (value) {
                                    categoryItem.setTitle = value!;
                                  },
                                ),
                              ),
                              Expanded(
                                child: ListView.builder(
                                  shrinkWrap: true,
                                  itemCount: categoryItem.items.length,
                                  itemBuilder: (context, j) {
                                    Meal mealItem = categoryItem.items[j];
                                    return Container(
                                      width: double.infinity,
                                      height: screenHeight * .1,
                                      color: widget.dark
                                          ? primaryDarkColor
                                          : primaryLightColor,
                                      child: ListTile(
                                        leading: Stack(
                                          alignment: Alignment.topLeft,
                                          children: [
                                            Container(
                                              width: screenWidth * .1,
                                              height: screenWidth * .2,
                                              decoration: BoxDecoration(
                                                image: DecorationImage(
                                                    image: AssetImage(
                                                        mealItem.imgPath),
                                                    fit: BoxFit.fill),
                                              ),
                                            ),
                                            IconButton(
                                              onPressed: () {
                                                /*Change Image Function*/
                                              },
                                              icon: Icon(
                                                Icons.edit,
                                                color: Colors.white,
                                              ),
                                            ),
                                          ],
                                        ),
                                        title: TextFormField(
                                          initialValue: mealItem.name,
                                          onSaved: (value) {
                                            mealItem.setName = value!;
                                          },
                                        ),
                                        subtitle: TextFormField(
                                          initialValue: "${mealItem.price}",
                                          onSaved: (value) {
                                            mealItem.setPrice =
                                                double.parse(value!);
                                          },
                                        ),
                                        trailing: IconButton(
                                          onPressed: () {
                                            categoryItem.items.remove(mealItem);
                                          },
                                          icon: Icon(
                                            Icons.delete,
                                            color: Colors.red,
                                          ),
                                        ),
                                      ),
                                    );
                                  },
                                ),
                              ),
                            ],
                          ),
                        );
                      },
                    );
                  } else if (snapshot.error != null) {
                    builtWidget = Text("error : ${snapshot.error}");
                  } else if (!snapshot.hasData) {
                    builtWidget = Text("No data");
                  } else if (snapshot.connectionState == ConnectionState.waiting) {
                    builtWidget = Text("Waiting for Connection");
                  }
                  return builtWidget;
                },
              ),
            ),
          ),
        );
      }
    }
    

    And this is the full error description :

    FlutterError (Multiple widgets used the same GlobalKey. The key [LabeledGlobalKey#f9b7f menu form Key] was used by multiple widgets. The parents of those widgets were:

    • RepaintBoundary(renderObject: RenderRepaintBoundary#522fa relayoutBoundary=up4 NEEDS-LAYOUT NEEDS-PAINT)
    • RepaintBoundary(renderObject: RenderRepaintBoundary#ef78c relayoutBoundary=up4) A GlobalKey can only be specified on one widget at a time in the widget tree.)
    • intraector
      intraector about 2 years
      Once I had a similar issue, the problem was the screen was pushing twice
    • Admin
      Admin about 2 years
      How do I know if the screen is pushing twice? thanks in advance.
    • intraector
      intraector about 2 years
      In my case it was because of BlocListener was triggered twice because of bloc changes, which led to Navigator.push() calling twice. Take a closer look to how you're opening the MenuScreen()