The following minimally reproducible dummy code throws this error:
════════ Exception caught by widgets library ═══════════════════════════════════
Multiple widgets used the same GlobalKey.
════════════════════════════════════════════════════════════════════════════════
Restarted application in 987ms.
I/flutter (10106): Key: [LabeledGlobalKey<FormBuilderState>#070c0 GlobalFormKey #SignIn ]
════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown while finalizing the widget tree:
Multiple widgets used the same GlobalKey.
The key [LabeledGlobalKey<FormBuilderState>#070c0 GlobalFormKey #SignIn ] was used by multiple widgets. The parents of those widgets were:
- FormBuilderWrapper-[LabeledGlobalKey<FormBuilderState>#070c0 GlobalFormKey #SignIn ]
- _BodyBuilder
A GlobalKey can only be specified on one widget at a time in the widget tree.
Dummy Code:
class SignInScreen extends StatelessWidget {
final GlobalKey<FormBuilderState> key =
GlobalKey<FormBuilderState>(debugLabel: 'GlobalFormKey #SignIn ');
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Dummy")),
body: FormBuilderWrapper(
key: key,
childrenInColumn: [
FormBuilderEmail(),
FormBuilderPassword(identifierForField: "password")
],
),
);
}
}
class FormBuilderWrapper extends StatelessWidget {
final List<Widget> childrenInColumn;
final Key key;
const FormBuilderWrapper({
@required this.key,
@required this.childrenInColumn,
});
@override
Widget build(BuildContext context) {
print("Key: $key");
return FormBuilder(
key: key,
child: Column(
children: this.childrenInColumn,
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
class FormBuilderEmail extends StatelessWidget {
const FormBuilderEmail({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return FormBuilderTextField(
name: "email",
);
}
}
class FormBuilderPassword extends StatelessWidget {
final String hintText;
final String identifierForField;
const FormBuilderPassword({
@required this.identifierForField,
this.hintText = "Password",
});
@override
Widget build(BuildContext context) {
return FormBuilderTextField(
name: identifierForField,
);
}
}
What I don't understand is that only 1 widget uses the Key and that's the FormBuilder
widget(I didn't count 'FormBuilderWrapper' as it merely passes the key to FormBuilder
)
Can anyone point me in the right direction as to why this is happening? An explanation of which are the "multiple widgets" using the same GlobalKey
would be great
I got it why you were getting the error. It was because of this statement. It is recognizing variable name key as keyword key.
final GlobalKey<FormBuilderState> key =
GlobalKey<FormBuilderState>(debugLabel: 'GlobalFormKey #SignIn ');
Below is the modified version of the dummy code you uploaded. I didn't get any errors after execution but please check at your end.
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
class SignInScreen extends StatelessWidget {
final GlobalKey<FormBuilderState> _formkey =
GlobalKey<FormBuilderState>(debugLabel: 'GlobalFormKey #SignIn ');
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Dummy")),
body: FormBuilderWrapper(
fomrkey: _formkey,
childrenInColumn: [
FormBuilderEmail(),
FormBuilderPassword(identifierForField: "password")
],
),
);
}
}
class FormBuilderWrapper extends StatelessWidget {
final List<Widget> childrenInColumn;
final Key fomrkey;
const FormBuilderWrapper({
required this.fomrkey,
required this.childrenInColumn,
});
@override
Widget build(BuildContext context) {
print("Key: $fomrkey");
return FormBuilder(
key: fomrkey,
child: Column(
children: this.childrenInColumn,
),
);
}
}
class FormBuilderEmail extends StatelessWidget {
const FormBuilderEmail({
Key? fomrkey1,
}) : super(key: fomrkey1);
@override
Widget build(BuildContext context) {
return FormBuilderTextField(
name: "email",
);
}
}
class FormBuilderPassword extends StatelessWidget {
final String hintText;
final String identifierForField;
const FormBuilderPassword({
required this.identifierForField,
this.hintText = "Password",
});
@override
Widget build(BuildContext context) {
return FormBuilderTextField(
name: identifierForField,
);
}
}