1

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

════════ 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会很棒

4

2 回答 2

1

我明白了为什么你会收到错误。就是因为这个说法。它将变量名键识别为关键字键。

 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,
        );
      }
    }
于 2021-06-09T17:25:49.223 回答
0

他们使用相同的密钥,因为当您创建时,FormBuilderWrapper您将密钥传递给它,然后在内部返回一个 formBuilder,传递您提供的相同密钥FormBuilderWrapper

据我了解,密钥只是“经过”并进入FormBuilder,因为FormBuilderWrapper仍然是用该密钥创建的,这并不重要。

于 2021-06-09T17:06:09.170 回答