多个小部件与 FormBuilder 使用相同的 GlobalKey

Multiple widgets used the same GlobalKey with FormBuilder

以下最低限度可重现的虚拟代码引发此错误:

════════ 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.

虚拟代码:

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,
    );
  }
}

我不明白的是,只有 1 个小部件使用了密钥,那就是 FormBuilder 小部件(我没有计算 'FormBuilderWrapper',因为它只是将密钥传递给 FormBuilder)

任何人都可以指出我为什么会这样的正确方向吗?解释一下使用相同 GlobalKey 的“多个小部件”会很棒

他们使用相同的密钥,因为当您创建 FormBuilderWrapper 时,您将密钥传递给它,然后在您内部 return 一个 formBuilder 传递您给 [=10= 的相同密钥].

据我了解,密钥只是“经过”并转到 FormBuilder 并不重要,因为 FormBuilderWrapper 仍在使用该密钥创建。

我明白你为什么会收到这个错误。正是因为这句话。它正在将变量名称键识别为关键字键。

 final GlobalKey<FormBuilderState> key =
      GlobalKey<FormBuilderState>(debugLabel: 'GlobalFormKey #SignIn ');

以下是您上传的虚拟代码的修改版本。执行后我没有收到任何错误,但请您检查一下。

    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,
        );
      }
    }