【问题标题】:Flutter- Fetch data from the Firestore and use it in a FormBuilderDropdownFlutter- 从 Firestore 获取数据并在 FormBuilderDropdown 中使用它
【发布时间】:2020-10-01 22:57:23
【问题描述】:

我的 Web 应用程序要求我从 Firestore 中读取数据,并将这些字段作为值显示到下拉按钮中,并针对每个值设置一个复选框。此下拉菜单将在 Formbuilder 中使用。这是为了确保可以从下拉列表中选择多个值。它看起来像这样。我可以得到一些帮助吗?

Widget _buildFormBuilderForm() {
return Column(
children: <Widget>[
FormBuilder(
key: _fbKey,
child: Expanded(
   child: Padding(
     padding: const EdgeInsets.all(16.0),
     child: Column(
        children: <Widget>[
           Row(
             children: <Widget>[
               Expanded(
                 child: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: new StreamBuilder<QuerySnapshot>(
                        stream: 
                         Firestore.instance.collection("collection") 
                          .snapshots(),
                         builder: (context, snapshot) {
                         if (!snapshot.hasData)
                                return new Text("Please wait");
                                return new FormBuilderDropdown(
                                       initialValue: dropdownvalue,
                                       hint: new Text("Select 
                                                  dropdownvalue"),
                                       attribute: 'dropdownvalue',
                                       decoration: 
                              InputDecoration(labelText:"dropdown"),
                                       items: 
                       snapshot.data.documents.map((DocumentSnapshot 
                       document) {
                             for(int i = 0; i <document.data.length; i++){
                               print(document.data['Name']);
                               return new DropdownMenuItem(
                               value: document.data['Name'],
                               child: new 
                             Text(document.data['Name'].toString()),
                                );
                        }
                   }).toList(),

              onChanged: (value) {
                   print(value);
                   setState(() {
                     dropdownvalue = value;
                     });
                    },
                  );
                }),
               ),
              ),
             ],
            ),
           ]
         ),
      )))
     ],
   );
 }

【问题讨论】:

  • 您在创建 ui 或连接到 firebase 时需要帮助吗?你都尝试了些什么。您能否分享一些代码以便我们为您提供帮助。
  • 我已经编辑了这个问题。我需要帮助来创建 UI。下拉列表的每个值也应该有对应的复选框。我尝试添加一个复选框,但看起来 FormBuilder 不支持它。

标签: flutter flutter-layout flutter-web


【解决方案1】:

由于您的示例涉及我无法访问的 firebase 流,因此我提供了一个通用解决方案。 FormsBuilder 包中有一个名为FormBuilderCheckboxList 的小部件,它可能对您有所帮助。您可能仍然需要根据自己的需要锻炼布局部分。

解决方案 1:

  1. 定义一个List&lt;String&gt; 变量来保存用户在您的小部件中所做的选择。说
// hold the options user selects.
List<String> options = [];
  1. 使用 FormBuilder 包创建一个FormBuilderDropdown,并将一个DropdownmenuItem 和一个新的FormBuilderCheckboxList 小部件作为其子小部件,并将options 列表分配为initialValueDropdownmenuItemvalue .
FormBuilderDropdown(
    attribute: "My Language",
    decoration: InputDecoration(labelText: "Laguage"),
    // set it as initial value
    initialValue: options,
    hint: Text('Select Language'),
    validators: [FormBuilderValidators.required()],
    items: [
      DropdownMenuItem(
        // set it as the value of the drop down.
        value: options,
  1. 使用onChanged 属性捕获用户选择的选项并将其添加到options 列表中。
 onChanged: (values) {                            
   options.clear();
   values.forEach((e) => options.add(e as String));
   setState(() {});
 }

解决方案 2:

  1. 使用ExpansionTile 而不是下拉菜单来独立处理用户选择。但是,当使用下拉列表中可用的列表之外的点击时,您将失去关闭菜单的功能。

包含两个解决方案的示例。

class MyHomePage extends StatefulWidget {
  @override
  MyHomePageState createState() {
    return MyHomePageState();
  }
}

class MyHomePageState extends State<MyHomePage> {
  var data;
  bool autoValidate = true;
  bool readOnly = false;
  bool showSegmentedControl = true;
  List<String> options = [];
  final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('FormBuilder Example'),
      ),
      body: Padding(
        padding: EdgeInsets.all(10),
        child: ListView(
          children: <Widget>[
            FormBuilder(
              // context,
              key: _fbKey,
              // autovalidate: true,
              initialValue: {
                'movie_rating': 3,
              },
              readOnly: false,
              child: Column(
                children: <Widget>[
                  SizedBox(
                    height: 50,
                  ),
                  // Solution 1
                  FormBuilderDropdown(
                    attribute: "My Language",
                    decoration: InputDecoration(labelText: "Laguage"),
                    initialValue: options,
                    hint: Text('Select Language'),
                    validators: [FormBuilderValidators.required()],
                    items: [
                      DropdownMenuItem(
                        value: options,
                        child: FormBuilderCheckboxList(
                          decoration: InputDecoration(
                              labelText: "The language of my people"),
                          attribute: "languages",
                          initialValue: options,
                          options: [
                            FormBuilderFieldOption(value: "Dart"),
                            FormBuilderFieldOption(value: "Kotlin"),
                            FormBuilderFieldOption(value: "Java"),
                            FormBuilderFieldOption(value: "Swift"),
                            FormBuilderFieldOption(value: "Objective-C"),
                          ],
                          onChanged: (values) {
                            options.clear();
                            values.forEach((e) => options.add(e as String));
                            setState(() {});
                          },
                        ),
                      ),
                    ],
                  ),
                  SizedBox(
                    height: 50,
                  ),
                  // Solution 2
                  ExpansionTile(
                    title: Text('My Language'),
                    children: [
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: FormBuilderCheckboxList(
                          decoration: InputDecoration(
                              labelText: "The language of my people"),
                          attribute: "languages",
                          initialValue: options,
                          options: [
                            FormBuilderFieldOption(value: "Dart"),
                            FormBuilderFieldOption(value: "Kotlin"),
                            FormBuilderFieldOption(value: "Java"),
                            FormBuilderFieldOption(value: "Swift"),
                            FormBuilderFieldOption(value: "Objective-C"),
                          ],
                          onChanged: (values) {
                            options.clear();
                            values.forEach((e) => options.add(e as String));
                            setState(() {});
                          },
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

【讨论】:

  • 谢谢@abhliash。我尝试了你的建议。但是在 FormBuilderFieldOption 中,应该从 Firestore 中读取该值。这些值实际上是 Firestore 中特定集合的文档 ID。
  • 您可以随意更改逻辑。相反,硬编码的 formbuilderoption 您可以映射 firestore 响应并构建它们。
猜你喜欢
  • 2021-06-14
  • 2021-04-17
  • 1970-01-01
  • 2020-09-12
  • 2018-12-22
  • 2020-04-01
  • 2021-11-08
  • 2020-04-03
  • 2020-05-11
相关资源
最近更新 更多