跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Dart大前端

Flutter 使用复选框实现下拉多选

Flutter 使用复选框实现下拉多选功能主要包含两种方案。一是自定义 MultiSelect 组件,通过 AlertDialog 展示列表,利用 CheckboxListTile 处理选中状态,提交后返回结果并在首页以 Chip 形式展示。二是使用第三方插件如 flutter_multi_select 快速集成。文章提供了完整的自定义代码示例,涵盖 StatefulWidget 状态管理及 Navigator 交互逻辑,帮助开发者在 Flutter 应用中实现灵活的多选交互效果。

霸天发布于 2025/2/7更新于 2026/8/2253 浏览
Flutter 使用复选框实现下拉多选

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

本文介绍在 Flutter 中使用复选框实现下拉多选的两种方法。第一种是从头构建自定义多选组件,第二种是使用第三方包。

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

我们将构建一个应用程序,包含一个专业的多选小部件,显示选项列表。用户可以通过选中/取消选中关联的复选框来选择或取消选择选项。当按下按钮时,显示多选对话框,让用户选择主题。所选主题将作为筹码(Chip)显示在屏幕上。

构建自定义多选小部件

创建一个名为 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('取消'),
          onPressed: _cancel,
        ),
        ElevatedButton(
          child: const Text('确定'),
          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
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> {
  final List<String> _selectedItems = [];

  void _itemChange(String itemValue, bool isSelected) {
    setState(() {
      if (isSelected) {
        _selectedItems.add(itemValue);
      } else {
        _selectedItems.remove(itemValue);
      }
    });
  }

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

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

    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: [
            ElevatedButton(
              child: const Text('选出你最喜欢的技术'),
              onPressed: _showMultiSelect,
            ),
            const Divider(height: 30),
            Wrap(
              children: _selectedItems
                  .map((e) => Chip(label: Text(e)))
                  .toList(),
            )
          ],
        ),
      ),
    );
  }
}
使用第三方插件

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

  • flutter_multi_select
  • multiselect_formfield
  • flutter_multiselect
  • multiselect

目录

  1. Flutter:使用复选框进行下拉多选
  2. 从头开始使用复选框创建多选
  3. 构建自定义多选小部件
  4. 完整代码示例
  5. 使用第三方插件
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • RocketMQ 服务启动与关闭指南
  • C++ 语言基础与进阶教程
  • Google Antigravity AI 编程工具下载与安装指南
  • 使用 TRAE CN 结合 MasterGo MCP 实现设计稿转前端代码
  • AI 在数据库操作中的应用场景与实战优化
  • 将 Zed 编辑器集成到 Bright Data Web MCP
  • 数据结构:八种经典排序算法实现与解析
  • BaseCTF Week3 Web & Misc 解题复盘
  • YOLOv8 算法架构、核心创新与部署详解
  • 大模型开发基本功:推荐几个练手程序与优化实践
  • 哈希算法原理、特点及应用场景详解
  • 消息队列理论基础与 Kafka 架构价值解析
  • FPGA 实现 UART 串口通信
  • Python Web 开发:Flask 框架入门与实战
  • Python 兼职与副业方向及技术实现指南
  • DeepSeek-R1-Distill-Qwen-1.5B 本地部署:vLLM 与 Open WebUI 实战
  • Cookie 与 Session:Web 用户状态管理机制解析
  • C++ 红黑树核心原理与插入实现详解
  • 黑词分析前端组件设计:双面板交互与进度监控
  • 扩散模型原理与图像生成实战

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online