Flutter:使用复选框进行下拉多选

简介: Flutter:使用复选框进行下拉多选本文向您展示了在 Flutter 中使用复选框实现下拉多选的两种不同方法。在第一种方法中,我们将从头开始构建多选。在第二种方法中,我们将使用第三方包快速完成工作。

Flutter:使用复选框进行下拉多选

本文向您展示了在 Flutter 中使用复选框实现下拉多选的两种不同方法。在第一种方法中,我们将从头开始构建多选。在第二种方法中,我们将使用第三方包快速完成工作。


从头开始使用复选框创建多选

应用预览

image.png


我们将要构建的应用程序有一个专业的、功能齐全的多选小部件,可显示选项列表。可以通过选中/取消选中与其关联的复选框来选择或取消选择一个选项。


当按下升高的按钮时,将显示多选对话框。它让用户在编程中选择他们最喜欢的主题。所选主题将作为筹码显示在屏幕上。


以下是我们的应用程序的运行方式:


构建自定义多选小部件

创建一个名为MultiSelect的可重用小部件,它可以获取选项列表(您可以对这些项目进行硬编码或从数据库/API 中获取它们):

// Multi Select widget
// This widget is reusable
class MultiSelect extends StatefulWidget {
  final List<String> items;
  const MultiSelect({Key? key, required this.items}) : super(key: key);
  @override
  State<StatefulWidget> createState() => _MultiSelectState();
}
class _MultiSelectState extends State<MultiSelect> {
  // this variable holds the selected items
  final List<String> _selectedItems = [];
// This function is triggered when a checkbox is checked or unchecked
  void _itemChange(String itemValue, bool isSelected) {
    setState(() {
      if (isSelected) {
        _selectedItems.add(itemValue);
      } else {
        _selectedItems.remove(itemValue);
      }
    });
  }
  // this function is called when the Cancel button is pressed
  void _cancel() {
    Navigator.pop(context);
  }
// this function is called when the Submit button is tapped
  void _submit() {
    Navigator.pop(context, _selectedItems);
  }
  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: const Text('Select Topics'),
      content: SingleChildScrollView(
        child: ListBody(
          children: widget.items
              .map((item) => CheckboxListTile(
                    value: _selectedItems.contains(item),
                    title: Text(item),
                    controlAffinity: ListTileControlAffinity.leading,
                    onChanged: (isChecked) => _itemChange(item, isChecked!),
                  ))
              .toList(),
        ),
      ),
      actions: [
        TextButton(
          child: const Text('Cancel'),
          onPressed: _cancel,
        ),
        ElevatedButton(
          child: const Text('Submit'),
          onPressed: _submit,
        ),
      ],
    );
  }
}

完整的代码

这是您在上面的演示中看到的应用程序的代码:

import 'package:flutter/material.dart';
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    const String title = "坚果";
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: title,
      theme: ThemeData(
        primarySwatch: Colors.indigo,
      ),
      home: const HomePage(),
    );
  }
}
// Multi Select widget
// This widget is reusable
class MultiSelect extends StatefulWidget {
  final List<String> items;
  const MultiSelect({Key? key, required this.items}) : super(key: key);
  @override
  State<StatefulWidget> createState() => _MultiSelectState();
}
class _MultiSelectState extends State<MultiSelect> {
  // this variable holds the selected items
  final List<String> _selectedItems = [];
// This function is triggered when a checkbox is checked or unchecked
  void _itemChange(String itemValue, bool isSelected) {
    setState(() {
      if (isSelected) {
        _selectedItems.add(itemValue);
      } else {
        _selectedItems.remove(itemValue);
      }
    });
  }
  // this function is called when the Cancel button is pressed
  void _cancel() {
    Navigator.pop(context);
  }
// this function is called when the Submit button is tapped
  void _submit() {
    Navigator.pop(context, _selectedItems);
  }
  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: const Text('Select Topics'),
      content: SingleChildScrollView(
        child: ListBody(
          children: widget.items
              .map((item) => CheckboxListTile(
                    value: _selectedItems.contains(item),
                    title: Text(item),
                    controlAffinity: ListTileControlAffinity.leading,
                    onChanged: (isChecked) => _itemChange(item, isChecked!),
                  ))
              .toList(),
        ),
      ),
      actions: [
        TextButton(
          child: const Text('取消'),
          onPressed: _cancel,
        ),
        ElevatedButton(
          child: const Text('确定'),
          onPressed: _submit,
        ),
      ],
    );
  }
}
// Implement a multi select on the Home screen
class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);
  @override
  _HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
  List<String> _selectedItems = [];
  String _title = "坚果";
  void _showMultiSelect() async {
    // a list of selectable items
    // these items can be hard-coded or dynamically fetched from a database/API
    final List<String> _items = [
      'Flutter',
      'Node.js',
      'React Native',
      'Java',
      'Docker',
      'MySQL'
    ];
    final List<String>? results = await showDialog(
      context: context,
      builder: (BuildContext context) {
        return MultiSelect(items: _items);
      },
    );
    // Update UI
    if (results != null) {
      setState(() {
        _selectedItems = results;
      });
    }
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_title),
      ),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // use this button to open the multi-select dialog
            ElevatedButton(
              child: const Text('选出你最喜欢的技术'),
              onPressed: _showMultiSelect,
            ),
            const Divider(
              height: 30,
            ),
            // display selected items
            Wrap(
              children: _selectedItems
                  .map((e) => Chip(
                        label: Text(e),
                      ))
                  .toList(),
            )
          ],
        ),
      ),
    );
  }
}

使用第三方插件

进行自定义多选既不复杂也不复杂。但是,如果您有紧急任务并且只想尽快进行多选,那么使用第三方插件是一个不错的选择。有几个不错的开源包供您使用:


flutter_multi_select

multiselect_formfield

flutter_multiselect

多选

结论

您已经学习了不止一种向应用程序添加多选的技术。如果你想探索更多关于现代 Flutter 开发的新鲜有趣的东西,


相关文章
|
4月前
|
监控 Dart 安全
创建一个Dart应用,监控局域网上网记录的软件:Flutter框架的应用
在当今数字时代,网络安全变得愈发重要。为了监控局域网上的上网记录,我们可以借助Flutter框架创建一个强大的Dart应用。在这篇文章中,我们将深入讨论如何使用Flutter框架开发这样一个监控局域网上网记录的软件,并提供一些实用的代码示例。
278 1
|
7月前
|
Dart Android开发 UED
带你读《深入浅出Dart》二十七、Flutter路由管理
带你读《深入浅出Dart》二十七、Flutter路由管理
|
7月前
|
Dart
带你读《深入浅出Dart》三十、Flutter实战之TODO应用(1)
带你读《深入浅出Dart》三十、Flutter实战之TODO应用(1)
|
1天前
|
Dart 前端开发 开发者
【Flutter前端技术开发专栏】Flutter Dart语言基础语法解析
【4月更文挑战第30天】Dart是Google为Flutter框架打造的高效编程语言,具有易学性、接口、混入、抽象类等特性。本文概述了Dart的基础语法,包括静态类型(如int、String)、控制流程(条件、循环)、函数、面向对象(类与对象)和异常处理。此外,还介绍了库导入与模块使用,帮助开发者快速入门Flutter开发。通过学习Dart,开发者能创建高性能的应用。
【Flutter前端技术开发专栏】Flutter Dart语言基础语法解析
|
1天前
|
Dart 测试技术 UED
Dart 和 Flutter 错误处理指南 | 最佳实践全解析
深入探索 Dart 和 Flutter 中的错误处理技术,从编译时错误到运行时异常,带你学习如何优雅地处理应用程序中的各种意外情况。了解最佳实践,让你的应用程序稳如磐石,用户体验持续优化!
Dart 和 Flutter 错误处理指南 | 最佳实践全解析
|
5天前
|
存储 缓存 开发框架
Flutter的网络请求:使用Dart进行HTTP请求的技术详解
【4月更文挑战第26天】了解Flutter网络请求,本文详述使用Dart进行HTTP请求
|
5天前
|
开发框架 Dart Java
Flutter的核心:Dart语言基础——语法与特性深度解析
【4月更文挑战第26天】Flutter框架背后的Dart语言,以其简洁的语法和独特特性深受开发者喜爱。本文深入解析Dart的语法与特性,如类型推导、动态静态类型系统、统一的类接口、访问权限控制以及并发编程支持。了解并掌握Dart,能助开发者更高效地利用Flutter构建高性能移动应用。
|
3月前
|
Dart JavaScript
Flutter - Dart 基础(数据类型)
【2月更文挑战第3天】
67 1
|
3月前
|
Dart JavaScript 安全
|
3月前
|
Dart Shell 开发工具
解决windows安装Flutter时出现Unknown operating system. Cannot install Dart SDK.问题
解决windows安装Flutter时出现Unknown operating system. Cannot install Dart SDK.问题