0

我正在使用“Flutter Form Builder”包 4.0.2构建一个表单。

大多数表单问题都在屏幕上,但最后两个问题在使用RFlutter Alert 包 1.1.0创建的连续*弹出窗口中

*“成功”是指在主窗体屏幕底部有一个“发布”按钮(见下面的第一张图片)。按下时,会出现一个 RFlutter 警报弹出窗口(请参见下面的第二张屏幕截图),其中包含倒数第二个 FormBuilderRadioGroup 问题(“q11”)。当按下“下一步”按钮时,会出现另一个 RFlutter 警报弹出窗口,其中会出现最后一个 FormBuilderRadioGroup 问题(“q12”)。当此处的“Finish Posting”按钮被按下时,整个 Flutter Form Builder 表单提交。

主屏幕的屏幕截图,在出现任何警报弹出窗口之前

第一个警报弹出窗口的屏幕截图

第二个警报弹出的屏幕截图

用户界面运行良好,但问题与随表单提交的警报弹出窗口(Q11 和 Q12)中的问题无关(请参阅下面的控制台快照 - q1、q2 和 q3 也有问题,但这不是我的问题在这里询问)。

控制台截图

这是代码(跳过不相关的部分,因为长度):

// This is the stateful widget that the main application instantiates, per https://api.flutter.dev/flutter/widgets/Form-class.html
class SandboxWriteReviewScreen extends StatefulWidget {
  // BEGIN code from material_tag_editor
  final String title = 'Material Tag Editor Demo';
// END code from material_tag_editor

  @override
  _SandboxWriteReviewScreenState createState() =>
      _SandboxWriteReviewScreenState();
}

// This is the private State class that goes with WriteReviewScreen
class _SandboxWriteReviewScreenState extends State<SandboxWriteReviewScreen> {
  var data;
  AutovalidateMode autovalidateMode = AutovalidateMode.always;
  bool readOnly = false;
  bool showSegmentedControl = true;
  //final _newFormbuilderKey = GlobalKey<FormState>();
  final _newnewFormbuilderKey = GlobalKey<FormBuilderState>();

  // above "GlobalKey" lets us generate a unique, app-wide ID that we can associate with our form, per https://fluttercrashcourse.com/blog/realistic-forms-part1
  final ValueChanged _onChanged = (val) => print(val);

  // BEGIN  related to FormBuilderTextField in form below
  final _ageController = TextEditingController(text: '45');
  bool _ageHasError = false;
  // END related to FormBuilderTextField in form below

  String qEleven;
  String qTwelve;

  // BEGIN code from material_tag_editor
  List<String> qOne = [];
  final FocusNode _focusNode = FocusNode();

  onDelete(index) {
    setState(() {
      qOne.removeAt(index);
    });
  }

  // below = reiteration for cons

  List<String> qThree = [];
  //final FocusNode _focusNode = FocusNode();

  uponDelete(index) {
    // NOTE: "uponDelete" for cons vs. "onDelete" for pros
    setState(() {
      qThree.removeAt(index);
    });
  }

// END code from material_tag_editor

  //final _user = User();

  List<bool> isSelected;

  int starIconColor =
      0xffFFB900; // was 0xffFFB900;  0xffD49428 is from this image: https://images.liveauctioneers.com/houses/logos/lg/bartonsauction550_large.jpg?auto=webp&format=pjpg&width=140

  @override
  void initState() {
    //isSelected = [true, false];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(

续(跳过 AppBar):

body: SingleChildScrollView(
        child: Container(
          child: Builder(
            builder: (context) => FormBuilder(
              // was "builder: (context) => Form("
              key: _newnewFormbuilderKey,
              initialValue: {
                'date': DateTime.now(),
              },
              child: Padding(
                padding: const EdgeInsets.all(14.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    SizedBox(
                      height: 12.0,
                    ),
                    RichText(
                      text: TextSpan(
                        style: TextStyle(
                          color: Colors.blue,
                        ),
                        children: <TextSpan>[
                          TextSpan(
                            text:
                                'Q1 via TagEditor', // was 'What are 3 good or positive things about the house, property or neighborhood?', //  [ 1 ​]
                            style: TextStyle(
                              fontWeight: FontWeight.bold,
                              fontSize: 16.0,
                            ),
                          ),
                          TextSpan(
                            text: '  (optional)',
                            style: TextStyle(
                              fontWeight: FontWeight.normal,
                              fontStyle: FontStyle.italic,
                              fontSize: 14.0,
                              color: Colors.black54,
                            ), // was 'misleading or inaccurate?',
                          ),
                        ],
                      ),
                    ),
                    // BEGIN code from material_tag_editor
                    Padding(
                      padding: const EdgeInsets.only(top: 16.0),
                      child: TagEditor(
                        length: qOne.length,
                        delimiters: [
                          ','
                        ], // was delimiters: [',', ' '],  Also tried "return" ('\u2386',) and '\u{2386}'
                        hasAddButton: true,
                        textInputAction: TextInputAction
                            .next, // moves user from one field to the next!!!!
                        autofocus: false,
                        maxLines: 1,

                        // focusedBorder: OutlineInputBorder(
                        //   borderSide: BorderSide(color: Colors.lightBlue),
                        //   borderRadius: BorderRadius.circular(20.0),
                        // ),
                        inputDecoration: const InputDecoration(
                          // below was "border: InputBorder.none,"
                          isDense: true,
                          border: OutlineInputBorder(
                            borderRadius: const BorderRadius.all(
                              const Radius.circular(20.0),
                            ),
                          ),
                          focusedBorder: OutlineInputBorder(
                            borderSide: BorderSide(color: Colors.lightBlue),
                            borderRadius: const BorderRadius.all(
                              const Radius.circular(20.0),
                            ),
                            // above is per https://github.com/flutter/flutter/issues/5191
                          ),
                          labelText: 'separate,  with,  commas',
                          labelStyle: TextStyle(
                            fontStyle: FontStyle.italic,
                            backgroundColor:
                                Color(0x65dffd02), // was Color(0xffDDFDFC),
                            color: Colors.black87, // was Color(0xffD82E6D),
                            fontSize: 14,
                          ),
                        ),
                        onTagChanged: (value) {
                          setState(() {
                            qOne.add(value);
                          });
                        },
                        tagBuilder: (context, index) => _Chip(
                          index: index,
                          label: qOne[index],
                          onDeleted: onDelete,
                        ),
                      ),
                    ),
                    // END code from material_tag_editor

                    SuperDivider(),

续(跳过 Q2 - Q9):

SuperDivider(),
                    RichText(
                      text: TextSpan(
                        style: TextStyle(
                          color: Colors.blue,
                        ),
                        children: <TextSpan>[
                          TextSpan(
                            text:
                                'Q10 - via FormBuilder\'s FormBuilderTextField', // [ 9 ​]
                            style: TextStyle(
                              fontWeight: FontWeight.bold,
                              fontSize: 16.0,
                            ),
                          ),
                          TextSpan(
                            text: '  (optional)',
                            style: TextStyle(
                              fontWeight: FontWeight.normal,
                              fontStyle: FontStyle.italic,
                              fontSize: 14.0,
                              color: Colors.black54,
                            ), // was 'misleading or inaccurate?',
                          ),
                        ],
                      ),
                    ),
                    GavTextField(
                      maxCharLength: 1200,
                      fieldAttribute: 'qTen',
                      fieldLabelText:
                          'Be honest & kind.', // was 'Be honest, but kind.',
                    ),
                    SuperDivider(),
                    Padding(
                      padding: const EdgeInsets.symmetric(vertical: 16.0),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          ElevatedButton(
                            style: ElevatedButton.styleFrom(
                                primary: Colors.purple,
                                padding: EdgeInsets.symmetric(
                                    horizontal: 50, vertical: 20),
                                textStyle: TextStyle(
                                    fontSize: 20, fontWeight: FontWeight.bold)),
                            onPressed: () {
                              Alert(
                                context: context,
                                style: alertStyle,
                                title: 'Two quick things...',
                                desc: ' ',
                                content: Column(
                                  children: <Widget>[
                                    RichText(
                                      text: TextSpan(
                                        style: TextStyle(
                                          color: Colors.blue,
                                        ),
                                        children: <TextSpan>[
                                          TextSpan(
                                            text:
                                                'Q11 - via FormBuilder\'s FormBuilderRadioGroup', // [ 10 ​]
                                            style: TextStyle(
                                              fontWeight: FontWeight.bold,
                                              fontSize: 16.0,
                                            ),
                                          ),
                                        ],
                                      ),
                                    ),
                                    FormBuilderRadioGroup(
                                      name: 'qEleven',
                                      decoration: const InputDecoration(
                                        border: InputBorder.none,
                                      ),
                                      orientation: OptionsOrientation.vertical,
                                      onChanged: _onChanged,
                                      options: [
                                        FormBuilderFieldOption(
                                          value: 'N',
                                          child: RichText(
                                            text: TextSpan(
                                              style: TextStyle(
                                                color: Colors.black,
                                              ),
                                              children: <TextSpan>[
                                                TextSpan(
                                                  text: 'No', // [ 10 ​]
                                                  style: TextStyle(
                                                    fontWeight: FontWeight.w500,
                                                    fontSize: 16.0,
                                                  ),
                                                ),
                                              ],
                                            ),
                                          ),
                                        ),
                                        FormBuilderFieldOption(
                                          value: 'YesSometimes',
                                          child: RichText(
                                            text: TextSpan(
                                              style: TextStyle(
                                                color: Colors.black,
                                              ),
                                              children: <TextSpan>[
                                                TextSpan(
                                                  text:
                                                      'Yes, sometimes', // [ 10 ​]
                                                  style: TextStyle(
                                                    fontWeight: FontWeight.w500,
                                                    fontSize: 16.0,
                                                  ),
                                                ),
                                              ],
                                            ),
                                          ),
                                        ),
                                        FormBuilderFieldOption(
                                          value: 'YesDaily',
                                          child: RichText(
                                            text: TextSpan(
                                              style: TextStyle(
                                                color: Colors.black,
                                              ),
                                              children: <TextSpan>[
                                                TextSpan(
                                                  text: 'Yes, daily', // [ 10 ​]
                                                  style: TextStyle(
                                                    fontWeight: FontWeight.w500,
                                                    fontSize: 16.0,
                                                  ),
                                                ),
                                              ],
                                            ),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ],
                                ),
                                buttons: [
                                  DialogButton(
                                    onPressed: () {
                                      Alert(
                                          context: context,
                                          style: alertStyle,
                                          title: 'And lastly:',
                                          desc: '',
                                          content: Column(
                                            children: <Widget>[
                                              Row(
                                                mainAxisAlignment:
                                                    MainAxisAlignment.start,
                                                children: [
                                                  RichText(
                                                    text: TextSpan(
                                                      style: TextStyle(
                                                        color: Colors.blue,
                                                      ),
                                                      children: <TextSpan>[
                                                        TextSpan(
                                                          text:
                                                              ' Q12 - via FormBuilder\'s', // [ 10 ​]

最后(跳过 Q12):

buttons: [
                                            DialogButton(
                                              // BEGIN submit form when button pressed per 4.0.2 Readme and video https://www.youtube.com/watch?v=7FBELQq808M
                                              onPressed: () {
                                                _newnewFormbuilderKey
                                                    .currentState
                                                    .save();
                                                if (_newnewFormbuilderKey
                                                    .currentState
                                                    .validate()) {
                                                  print(_newnewFormbuilderKey
                                                      .currentState.value);
                                                  print(
                                                    '  >>> Q1\'s value via separate print: {$qOne}',
                                                  );
                                                  print(
                                                    '  >>> Q3\'s value via separate print: {$qThree}',
                                                  );
                                                  print(
                                                    '   >>> Q11\'s value via separate print: {$qEleven}',
                                                  );
                                                  print(
                                                    '   >>> Q12\'s value via separate print: {$qTwelve}',
                                                  );
                                                  //print(_newFormbuilderKey.currentState.privacyChoice.value);
                                                } else {
                                                  print("validation failed");
                                                }
                                              },

                                              // END submit form when button pressed per 4.0.2 Readme and video https://www.youtube.com/watch?v=7FBELQq808M

                                              child: Text(
                                                "Finish Posting",
                                                style: TextStyle(
                                                  color: Colors.white,
                                                  fontSize: 20,
                                                ),
                                              ),
                                            )
                                          ]).show();
                                    },
                                    child: Text(
                                      "Next >",
                                      style: TextStyle(
                                        color: Colors.white,
                                        fontSize: 20,
                                      ),
                                    ),
                                  )
                                ],
                              ).show();
                            },
                            child: Text(
                              'Post',
                              style: TextStyle(
                                color: Colors.white,
                                fontSize: 20,
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),

谢谢!

4

1 回答 1

1

Flutter 表单构建器包会自动获取祖先表单以在他们的表单中添加字段值。但是由于您的表单字段现在在对话框中,因此不能保证它们在调用对话框的父布局内。

来自颤振文档的参考(链接

This function takes a builder which typically builds a Dialog widget. 
Content below the dialog is dimmed with a ModalBarrier. The widget returned by the
builder does not share a context with the location that showDialog is originally
called from. Use a StatefulBuilder or a custom StatefulWidget if the dialog needs
to update dynamically.

相反,您可以将这些字段的值保存在有状态小部件的状态中,然后它们会组合所有值以供将来操作。由于您已经将它们保存在变量中qElevenqTwelve以后可以使用它。

这是为 qEleven 执行此操作的代码片段(与上述问题中的这部分代码进行比较):

FormBuilderRadioGroup(
                                      name: 'qEleven',
                                      decoration: const InputDecoration(
                                        border: InputBorder.none,
                                      ),
                                      orientation: OptionsOrientation.vertical,
                                      onChanged: (val) {
                                        print(val);
                                        qEleven = val;
                                      },
                                      options: [
                                        FormBuilderFieldOption(
                                          value: 'N',
                                          child: RichText(
                                            text: TextSpan(
                                              style: TextStyle(
                                                color: Colors.black,
                                              ),
                                              children: <TextSpan>[
                                                TextSpan(
                                                  text: 'No', // [ 10 ​]
                                                  style: TextStyle(
                                                    fontWeight: FontWeight.w500,
                                                    fontSize: 16.0,
                                                  ),
                                                ),
                                              ],
                                            ),
                                          ),
                                        ),

这是一个屏幕截图,突出显示了问题中的代码(左)和基于答案的代码(右)之间的区别:

显示代码差异的屏幕截图

可以做的另一件事是修改表单构建器包以接受状态,但如果您访问未安装状态,它可能会中断。

于 2021-01-03T07:42:19.957 回答