【问题标题】:How to pass a list of maps as inital value to the FormBuilderFilterChip in flutter_form_builder package?如何将地图列表作为初始值传递给flutter_form_builder包中的FormBuilder FilterChip?
【发布时间】:2020-07-29 19:28:49
【问题描述】:

我尝试将 FormBuilderFieldOption 的相同“值”字段的列表传递给 initialValue 参数。

编辑:通过列表满足“必需”验证器,但不会将筹码显示为“标记”

现在,如果我没记错的话,这应该返回一组全部标记的芯片,但它没有。

List<Map<String,dynamic>> _allValues = [
  {id: 1586762938154, name: 202, rate: 5000, type: 'ABYSS'},
  {id: 1586759232569, name: 101, rate: 1000, type: 'DELUXE'},
  {id: 1586849439323, name: 13, rate: 3434, type: 'DELUXE'},
  {id: 1586759258120, name: 102, rate: 2000, type: 'EXECUTIVE'},
  {id: 1586779416843, name: 103, rate: 2343, type: 'EXECUTIVE'},
]
FormBuilderFilterChip(
  initialValue: _allValues.map((value) => value).toList(),
  attribute: 'filter_chip',
  decoration: InputDecoration(
      labelText: 'Select many options',
    ),
  options: _allValues
               .map((val) => FormBuilderFieldOption(
                   value: val,
                   child: Text(val['name']),
                  ),
                ).toList(),
  onChanged: (value) {
    _selected = value;
     print(_selected);
   },
 )

【问题讨论】:

    标签: android ios flutter dart flutter-form-builder


    【解决方案1】:

    您可以在下面复制粘贴运行完整代码
    假设_allValuesList&lt;Map&lt;String, String&gt;&gt;

    代码sn-p

    List<Map<String, String>> _allValues = [
        {"name": "abc"},
        {"name": "def"},
        {"name": "123"}
      ];
    
    FormBuilderFilterChip(
                            initialValue:
                                _allValues.map((value) => value['name']).toList(),
                            attribute: 'filter_chip',
                            decoration: InputDecoration(
                              labelText: 'Select many options',
                            ),
                            options: _allValues
                                .map(
                                  (val) => FormBuilderFieldOption(
                                    value: val['name'],
                                    child: Text(val['name']),
                                  ),
                                )
                                .toList(),
    

    工作演示

    完整代码

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter_form_builder/flutter_form_builder.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter FormBuilder Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            inputDecorationTheme: InputDecorationTheme(
              labelStyle: TextStyle(color: Colors.purple),
            ),
          ),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      MyHomePageState createState() {
        return MyHomePageState();
      }
    }
    
    class Data {
      String name;
      Data(this.name);
    }
    
    class MyHomePageState extends State<MyHomePage> {
      var data;
      bool autoValidate = true;
      bool readOnly = false;
      bool showSegmentedControl = true;
      final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
      final GlobalKey<FormFieldState> _specifyTextFieldKey =
          GlobalKey<FormFieldState>();
    
      ValueChanged _onChanged = (val) => print(val);
      var genderOptions = ['Male', 'Female', 'Other'];
      List<Map<String, String>> _allValues = [
        {"name": "abc"},
        {"name": "def"},
        {"name": "123"}
      ];
      List<dynamic> _selected;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text("FormBuilder Example"),
            ),
            body: Padding(
                padding: EdgeInsets.all(10),
                child: SingleChildScrollView(
                  child: Column(children: <Widget>[
                    FormBuilder(
                      // context,
                      key: _fbKey,
                      autovalidate: true,
                      initialValue: {
                        'movie_rating': 5,
                      },
                      readOnly: false,
                      child: Column(
                        children: <Widget>[
                          FormBuilderFilterChip(
                            initialValue: ["Test 1", "Test 3"],
                            attribute: 'filter_chip',
                            decoration: InputDecoration(
                              labelText: 'Select many options',
                            ),
                            options: [
                              FormBuilderFieldOption(
                                  value: 'Test', child: Text('Test')),
                              FormBuilderFieldOption(
                                  value: 'Test 1', child: Text('Test 1')),
                              FormBuilderFieldOption(
                                  value: 'Test 2', child: Text('Test 2')),
                              FormBuilderFieldOption(
                                  value: 'Test 3', child: Text('Test 3')),
                              FormBuilderFieldOption(
                                  value: 'Test 4', child: Text('Test 4')),
                            ],
                          ),
                          FormBuilderFilterChip(
                            initialValue:
                                _allValues.map((value) => value['name']).toList(),
                            attribute: 'filter_chip',
                            decoration: InputDecoration(
                              labelText: 'Select many options',
                            ),
                            options: _allValues
                                .map(
                                  (val) => FormBuilderFieldOption(
                                    value: val['name'],
                                    child: Text(val['name']),
                                  ),
                                )
                                .toList(),
                            onChanged: (value) {
                              _selected = value;
                              print(_selected);
                            },
                          )
                        ],
                      ),
                    ),
                  ]),
                )));
      }
    }
    

    【讨论】:

    • 我试过这个方法,但它似乎不起作用,我已经用我试过的代码 sn-p 更新了这个问题。谢谢
    • 请贴出所有Value相关类和示例数据,需要转载。谢谢。
    • allValues 是从 initstate 上的数据库中获取的。我已经发布了示例数据。谢谢
    • 请检查更新的答案。如果 allValues 是 List 它将起作用
    • allValue的数据类型是什么?
    【解决方案2】:

    我深入了解了 FormBuilderFilterChip 如何使用 List.contains() 方法将芯片标记为选中。

    在此方法中,用于确定 [element] 是否等于 List 元素的相等性默认为元素的 [Object.==]。

    为了解决这个问题,我构建了自己的自定义 FilterChipField(从 FormBuilderFilterChip 中借用了大部分必要的代码)

    FormBuilderCustomField(
      attribute: "name",
      validators: [
        FormBuilderValidators.required(),
      ],
      formField: FormField(
        enabled: true,
        builder: (FormFieldState<dynamic> field) {
          return InputDecorator(
            decoration: InputDecoration(
              prefixIcon: Icon(Icons.vpn_key),
              labelText: "Assign Room(s)",
              contentPadding: EdgeInsets.only(top: 10.0, bottom: 0.0),
              errorText: field.errorText,
            ),
            child: Container(
              child: _buildChipSelectField(field),
            ),
          );
        },
      ),
    )
    

    下面的 _buildChipSelectField 包含两个自定义函数一个 (_selectedValuesContains) 来检查相等性 列表中的对象和第二个 (_selectedValuesRemove) 以在切换芯片时移除对象

    Widget _buildChipSelectField(FormFieldState<dynamic> field) {
      return Wrap(
        spacing: 3.0,
        children: _allValues.map((item) {
          return FilterChip(
            label: Text("${item['name']} - ${item['type']}"),
            selectedColor: Colors.black38,
            selected: _selectedValuesContains(item),
            onSelected: (value) {
              setState(() {
                if (_selectedValuesContains(item)) {
                  _selectedValuesRemove(item);
                } else {
                  _selectedValues.add(item);
                }
                field.didChange(_selectedValues);
              });
            },
          );
        }).toList(),
      );
    }
    

    (这些方法适用于我的示例数据(即 _allValues),但这个想法本质上是非常基本的。)

    _selectedValuesContains

    bool _selectedValuesContains(Map item) {
      int index = _selectedValues.indexWhere((val) => val['id'] == item['id']);
      return index >= 0 ? true : false;
    }
    

    _selectedValuesRemove

    void _selectedValuesRemove(Map item) {
      int index = _selectedValues.indexWhere((val) => val['id'] == item['id']);
      _selectedValues.removeAt(index);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-03
      • 2019-12-23
      • 2019-05-14
      • 1970-01-01
      • 2014-03-20
      • 2011-11-22
      相关资源
      最近更新 更多