Flutter中的分组多选下拉

vcirk6k6  于 2022-12-05  发布在  Flutter
关注(0)|答案(1)|浏览(266)

在flutter中创建多选下拉列表的长时间搜索后,我找到了两个解决方案
第一个自定义类:
Is there an equivalent widget in flutter to the "select multiple" element in HTML
用包裹搜索一个:multi_select_flutter
但我想知道的是如何以这两种方式之一创建分组下拉列表因为在我的示例中,为每个选项组指定一个标题非常重要,例如:

vnjpjtjt

vnjpjtjt1#

在项目列表中,将类型设置为data to add checkbox或sep以添加标题。对话框的输出将是{2,3}形式的字典,其中value 2 = Cordoba。

完整代码

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomeScreen(),
    );
  }
}

class MultiSelectDialogItem<V> {
  V value;

  String name;
  String type;

  MultiSelectDialogItem(
      {required this.name, required this.type, required this.value});
}

class MultiSelectDialog<V> extends StatefulWidget {
  const MultiSelectDialog({
    Key? key,
    required this.items,
    required this.initialSelectedValues,
  }) : super(key: key);

  final List<MultiSelectDialogItem<V>> items;
  final Set<V> initialSelectedValues;

  @override
  State<StatefulWidget> createState() => _MultiSelectDialogState<V>();
}

class _MultiSelectDialogState<V> extends State<MultiSelectDialog<V>> {
  final _selectedValues = <V>{};

  @override
  void initState() {
    super.initState();
    _selectedValues.addAll(widget.initialSelectedValues);
  }

  void _onItemCheckedChange(V itemValue, bool checked) {
    setState(() {
      if (checked) {
        _selectedValues.add(itemValue);
      } else {
        _selectedValues.remove(itemValue);
      }
    });
  }

  void _onCancelTap() {
    Navigator.pop(context);
  }

  void _onSubmitTap() {
    Navigator.pop(context, _selectedValues);
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: const Text('Select place'),
      contentPadding: const EdgeInsets.all(20.0),
      content: SingleChildScrollView(
        child: ListTileTheme(
          contentPadding: const EdgeInsets.fromLTRB(14.0, 0.0, 24.0, 0.0),
          child: ListBody(
            children: widget.items.map(_buildItem).toList(),
          ),
        ),
      ),
      actions: <Widget>[
        ElevatedButton(
          onPressed: _onCancelTap,
          child: const Text('CANCEL'),
        ),
        ElevatedButton(
          onPressed: _onSubmitTap,
          child: const Text('OK'),
        )
      ],
    );
  }

  Widget _buildItem(MultiSelectDialogItem<V> item) {
    final checked = _selectedValues.contains(item.value);
    return item.type == "data"
        ? CheckboxListTile(
            value: checked,
            title: Text(item.name),
            controlAffinity: ListTileControlAffinity.leading,
            onChanged: (checked) => _onItemCheckedChange(item.value, checked!),
          )
        : Container(
            child: Padding(
              padding: const EdgeInsets.all(10.0),
              child: Text(
                item.name,
                style: TextStyle(color: Color.fromARGB(255, 91, 91, 91)),
              ),
            ),
          );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

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

class HomeScreenState extends State<HomeScreen> {
  void _showMultiSelect(BuildContext context) async {
    final items = <MultiSelectDialogItem<int>>[
      MultiSelectDialogItem(name: 'Argentina', type: 'sep', value: 1),
      MultiSelectDialogItem(name: 'Cordoba', type: 'data', value: 2),
      MultiSelectDialogItem(name: 'Chaco', type: 'data', value: 3),
      MultiSelectDialogItem(name: 'Buenos Aires', type: 'data', value: 4),
      MultiSelectDialogItem(name: 'USA', type: 'sep', value: 5),
      MultiSelectDialogItem(name: 'California', type: 'data', value: 6),
      MultiSelectDialogItem(name: 'Florida', type: 'data', value: 7),
    ];

    final selectedValues = await showDialog<Set>(
      context: context,
      builder: (BuildContext context) {
        return MultiSelectDialog(
          items: items,
          initialSelectedValues: [].toSet(),
        );
      },
    );

    print(selectedValues);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          child: Text("show dialog"),
          onPressed: () {
            _showMultiSelect(context);
          },
        ),
      ),
    );
  }
}

输出

希望这对你有帮助。快乐编码:)

相关问题