【问题标题】:Multiple widgets used the same GlobalKey with FormBuilder多个小部件使用与 FormBuilder 相同的 GlobalKey
【发布时间】:2021-08-26 17:17:53
【问题描述】:

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

════════ 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的'key'参数
  • 是的,我现在也意识到了!谢谢

标签: flutter dart flutter-dependencies flutter-form-builder


【解决方案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,
        );
      }
    }

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2018-09-26
      • 2019-06-07
      • 2020-10-01
      • 1970-01-01
      • 2023-03-04
      • 2019-06-01
      • 2020-10-21
      • 2021-07-01
      • 2019-05-27
      相关资源
      最近更新 更多