如何将列表列表作为初始值传递给flutter_form_builder包中的FormBuilderFilterChip?

时间:2020-04-16 14:06:03

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

我尝试将 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);
   },
 )

2 个答案:

答案 0 :(得分:1)

您可以在下面复制粘贴运行完整代码
假设_allValuesList<Map<String, String>>

代码段

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(),

工作演示

enter image description here

完整代码

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);
                        },
                      )
                    ],
                  ),
                ),
              ]),
            )));
  }
}

答案 1 :(得分:0)

我了解了一下, FormBuilderFilterChip 如何通过使用 List.contains()方法将所选芯片标记为选定的。

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

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

 kubectl exec -t other pod -- curl -I 10.244.0.142:4000/

下面的 _buildChipSelectField 包含两个自定义函数,其中一个( _selectedValuesContains )用于检查是否相等 列表中对象的第二个( _selectedValuesRemove ),以在切换筹码时删除对象

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),
        ),
      );
    },
  ),
)

(这些方法用于我的示例数据(即_allValues),但实际上该想法非常基础。)

_selectedValues包含

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(),
  );
}

_selectedValues删除

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