You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中实现类似Google Keep的ListTile长按多选与批量删除

我来帮你搞定类似Google Keep的长按多选功能,核心就是把多选状态管理、AppBar动态切换和ListTile的交互逻辑串起来,下面是具体的实现思路和完整代码示例:

核心实现思路
  • 用布尔变量isSelectMode标记当前是否处于多选状态
  • 用Set集合跟踪选中的条目(推荐存条目的唯一ID,避免对象引用问题)
  • 长按ListTile时激活多选模式,并自动选中当前长按的条目
  • 根据isSelectMode动态切换AppBar的操作按钮(正常模式/删除模式)
  • 选中状态下的ListTile要显示视觉反馈(比如背景高亮、勾选图标)
完整代码示例

假设你的条目模型是NoteItem,下面是完整的StatefulWidget实现:

import 'package:flutter/material.dart';

// 自定义条目模型
class NoteItem {
  final String id;
  final String name;
  final String description;
  final DateTime dateTime;

  NoteItem({
    required this.id,
    required this.name,
    required this.description,
    required this.dateTime,
  });
}

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

  @override
  State<KeepStyleList> createState() => _KeepStyleListState();
}

class _KeepStyleListState extends State<KeepStyleList> {
  bool _isSelectMode = false;
  // 用Set存选中条目的ID,确保唯一性
  Set<String> _selectedItemIds = {};
  // 示例数据
  List<NoteItem> _notes = [
    NoteItem(
      id: '1',
      name: '购物清单',
      description: '买牛奶、全麦面包、鸡蛋',
      dateTime: DateTime.now(),
    ),
    NoteItem(
      id: '2',
      name: '会议记录',
      description: '下午3点讨论Q3项目进度',
      dateTime: DateTime.now(),
    ),
    NoteItem(
      id: '3',
      name: '健身计划',
      description: '周一、周三、周五练上肢',
      dateTime: DateTime.now(),
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: _isSelectMode 
            ? Text('已选中 ${_selectedItemIds.length} 项')
            : const Text('我的笔记'),
        actions: _isSelectMode
            ? [
                // 多选模式显示删除按钮
                IconButton(
                  icon: const Icon(Icons.delete_outline),
                  onPressed: () {
                    setState(() {
                      // 删除选中的条目
                      _notes.removeWhere((item) => _selectedItemIds.contains(item.id));
                      // 重置多选状态
                      _selectedItemIds.clear();
                      _isSelectMode = false;
                    });
                  },
                )
              ]
            : [
                // 正常模式的操作按钮(比如添加按钮)
                IconButton(
                  icon: const Icon(Icons.add),
                  onPressed: () {},
                ),
              ],
      ),
      body: ListView.builder(
        itemCount: _notes.length,
        itemBuilder: (context, index) {
          final item = _notes[index];
          final isSelected = _selectedItemIds.contains(item.id);
          
          return Card(
            child: ListTile(
              // 多选模式下替换leading为复选框
              leading: _isSelectMode
                  ? Checkbox(
                      value: isSelected,
                      onChanged: (value) {
                        setState(() {
                          value == true
                              ? _selectedItemIds.add(item.id)
                              : _selectedItemIds.remove(item.id);
                          // 选中为空时自动退出多选模式
                          if (_selectedItemIds.isEmpty) {
                            _isSelectMode = false;
                          }
                        });
                      },
                    )
                  : const Icon(Icons.info_outline),
              title: Text(item.name),
              subtitle: Text(item.description),
              trailing: Text('${item.dateTime.month}/${item.dateTime.day}'),
              // 长按激活多选模式并选中当前条目
              onLongPress: () {
                setState(() {
                  _isSelectMode = true;
                  _selectedItemIds.add(item.id);
                });
              },
              // 点击逻辑:多选模式下切换选中状态,正常模式下打开详情
              onTap: () {
                if (_isSelectMode) {
                  setState(() {
                    isSelected
                        ? _selectedItemIds.remove(item.id)
                        : _selectedItemIds.add(item.id);
                    if (_selectedItemIds.isEmpty) {
                      _isSelectMode = false;
                    }
                  });
                } else {
                  // 正常点击逻辑:比如跳转到详情页
                  // Navigator.push(context, MaterialPageRoute(builder: (context) => NoteDetail(item: item)));
                }
              },
              // 选中条目添加背景高亮
              tileColor: isSelected ? Colors.grey[200] : null,
            ),
          );
        },
      ),
    );
  }
}
关键细节说明
  • 多选模式激活后,自动把ListTile的leading换成复选框,方便快速切换选中状态
  • 长按条目时自动选中当前条目,完全贴合Google Keep的用户操作习惯
  • 当选中集合为空时,自动退出多选模式,无需手动取消
  • 选中的条目用tileColor设置浅灰色背景,给用户清晰的视觉反馈
  • 删除操作完成后自动重置所有状态,回到正常浏览模式

内容的提问来源于stack exchange,提问作者Mrye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:00:57