字节笔记本
2026年3月22日
Flutter Slidable - 滑动操作面板组件
本文介绍 flutter_slidable,一个为 Flutter 列表项添加滑动操作面板的强大组件库,支持通过代码控制动画的打开与关闭。在 iOS 和 Android 的原生应用中,滑动列表项显示操作菜单(如删除、归档、分享等)是一种极为常见的交互模式。flutter_slidable 将这种交互模式完美地移植到了 Flutter 平台,并且提供了丰富的动画效果和高度可定制的 API。值得注意的是,本项目是 letsar/flutter_slidable 的一个增强分支,新增了通过代码控制 Slidable 动画的功能。
项目简介
flutter_slidable 是一个获得 Flutter Favorite 认证的包,由 letsar 最初开发,EmadBeltaje 在此基础上进行了功能增强。该库实现了带方向性滑动操作的列表项组件,操作面板可以设置为可关闭(dismissible)。
与原版相比,EmadBeltaje 的分支版本增加了一个关键功能:通过代码获取 Slidable 控制器,从而程序化地控制滑动面板的打开和关闭。这一功能在实际开发中非常实用,比如在长按菜单中触发滑动操作、在表单验证后自动打开操作面板等场景。
核心特性
- 双方向操作面板:支持左侧/顶部(start)和右侧/底部(end)两个方向的操作面板
- 可关闭支持:操作面板可以设置为可关闭,用户滑动即可将列表项移除
- 4 种内置动画效果:Behind Motion、Drawer Motion、Scroll Motion、Stretch Motion,每种都提供独特的视觉体验
- 2 种内置操作组件:
SlidableAction和自定义 Builder,满足常见和高级需求 - 内置关闭动画:提供流畅的关闭过渡效果
- 代码控制动画:通过控制器可以在代码中打开或关闭滑动面板,支持自定义持续时间和位置
- 自动关闭行为:点击操作按钮后自动关闭面板(可覆盖),滚动父级 Scrollable 时自动关闭(可覆盖)
- 轻松禁用:可随时禁用滑动效果
- 自定义布局和动画:支持完全自定义操作面板的布局和动画效果
技术栈
- Flutter/Dart:基于 Flutter 框架开发,纯 Dart 实现
- 手势系统:基于 Flutter 的手势检测和动画系统
- 发布平台:通过 pub.dev 发布,是 Flutter Favorite 包
- 分支增强:基于 letsar/flutter_slidable 进行功能扩展
安装指南
由于本版本是原版 flutter_slidable 的增强分支,安装方式与标准包略有不同。
方式一:从 Git 仓库安装
在 pubspec.yaml 中添加以下依赖:
dependencies:
flutter_slidable:
git:
url: https://github.com/EmadBeltaje/flutter_slidable.git方式二:从 pub.dev 安装原版
如果你不需要代码控制动画的功能,可以直接使用原版:
dependencies:
flutter_slidable: <latest_version>在需要使用的 Dart 文件中导入:
import 'package:flutter_slidable/flutter_slidable.dart';快速开始
Slidable 组件的基本结构包含三个部分:
startActionPane:左侧或顶部的操作面板endActionPane:右侧或底部的操作面板child:未滑动时用户看到的实际内容
每个 ActionPane 包含:
motion:定义面板动画效果的组件children:操作按钮列表dismissible:可选的关闭配置
使用示例
基础用法
以下是一个完整的 Slidable 使用示例,展示左右两侧的操作面板:
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
class SlidableExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Slidable 示例')),
body: ListView(
children: [
Slidable(
// 为可关闭的 Slidable 指定 key
key: const ValueKey(0),
// 左侧操作面板
startActionPane: ActionPane(
motion: const ScrollMotion(),
dismissible: DismissiblePane(onDismissed: () {}),
children: const [
SlidableAction(
onPressed: doNothing,
backgroundColor: Color(0xFFFE4A49),
foregroundColor: Colors.white,
icon: Icons.delete,
label: '删除',
),
SlidableAction(
onPressed: doNothing,
backgroundColor: Color(0xFF21B7CA),
foregroundColor: Colors.white,
icon: Icons.share,
label: '分享',
),
],
),
// 右侧操作面板
endActionPane: const ActionPane(
motion: ScrollMotion(),
children: [
SlidableAction(
flex: 2,
onPressed: doNothing,
backgroundColor: Color(0xFF7BC043),
foregroundColor: Colors.white,
icon: Icons.archive,
label: '归档',
),
SlidableAction(
onPressed: doNothing,
backgroundColor: Color(0xFF0392CF),
foregroundColor: Colors.white,
icon: Icons.save,
label: '保存',
),
],
),
// 列表项内容
child: const ListTile(
leading: Icon(Icons.person),
title: Text('滑动我'),
subtitle: Text('向左或向右滑动查看操作'),
),
),
],
),
);
}
void doNothing(BuildContext context) {}
}通过代码控制动画
这是本分支版本的核心增强功能。通过 onSlidableControllerCreated 回调获取控制器,即可在代码中控制面板的打开和关闭:
SlidableController? _controller;
Slidable(
endActionPane: ActionPane(
motion: const BehindMotion(),
children: [
SlidableAction(
onPressed: (_) => print('编辑'),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
icon: Icons.edit,
label: '编辑',
),
SlidableAction(
onPressed: (_) => print('删除'),
backgroundColor: Colors.red,
foregroundColor: Colors.white,
icon: Icons.delete,
label: '删除',
),
],
),
// 获取控制器
onSlidableControllerCreated: (controller) {
_controller = controller;
},
child: ListTile(title: Text('代码控制示例')),
)
// 在代码中打开左侧操作面板
_controller?.openTo(-0.5, duration: const Duration(seconds: 1));
// 在代码中打开右侧操作面板
_controller?.openTo(0.5, duration: const Duration(milliseconds: 300));
// 关闭面板
_controller?.close();openTo 方法的参数说明:
- 负值(如 -0.5):显示左侧操作面板
- 正值(如 0.5):显示右侧操作面板
duration:动画持续时间,可选参数
在列表中使用
将 Slidable 嵌入到 ListView 中是最常见的使用场景:
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return Slidable(
key: ValueKey(item.id),
startActionPane: ActionPane(
motion: const BehindMotion(),
children: [
SlidableAction(
onPressed: (_) => _editItem(item),
backgroundColor: const Color(0xFF21B7CA),
foregroundColor: Colors.white,
icon: Icons.edit,
label: '编辑',
),
],
),
endActionPane: ActionPane(
motion: const StretchMotion(),
dismissible: DismissiblePane(
onDismissed: () => _deleteItem(item),
),
children: [
SlidableAction(
onPressed: (_) => _archiveItem(item),
backgroundColor: const Color(0xFF7BC043),
foregroundColor: Colors.white,
icon: Icons.archive,
label: '归档',
),
SlidableAction(
onPressed: (_) => _deleteItem(item),
backgroundColor: const Color(0xFFFE4A49),
foregroundColor: Colors.white,
icon: Icons.delete,
label: '删除',
),
],
),
child: ListTile(
leading: CircleAvatar(child: Text(item.name[0])),
title: Text(item.name),
subtitle: Text(item.description),
trailing: Text(item.date),
),
);
},
)使用不同的动画效果
flutter_slidable 提供了 4 种内置动画,通过 ActionPane 的 motion 参数配置:
// 1. Behind Motion - 操作按钮在内容后面出现
ActionPane(
motion: const BehindMotion(),
children: [/* actions */],
)
// 2. Drawer Motion - 操作按钮像抽屉一样展开
ActionPane(
motion: const DrawerMotion(),
children: [/* actions */],
)
// 3. Scroll Motion - 操作按钮跟随内容移动
ActionPane(
motion: const ScrollMotion(),
children: [/* actions */],
)
// 4. Stretch Motion - 操作按钮拉伸动画
ActionPane(
motion: const StretchMotion(),
children: [/* actions */],
)每种动画都有其独特的视觉风格,可以根据应用的整体设计语言选择最合适的动画效果。Behind Motion 效果简洁优雅,Drawer Motion 提供了层次感,Scroll Motion 类似于 iOS 原生的滑动效果,Stretch Motion 则增添了一丝动感。
迁移说明
如果你正在使用 0.6 版本的 flutter_slidable,可以参考官方迁移指南升级到 1.0 版本:
https://github.com/letsar/flutter_slidable/wiki/Migration-from-version-0.6.0-to-version-1.0.0
主要的变化包括 API 结构的调整、动画系统的重构以及新的配置方式。
项目链接
- GitHub 仓库(增强分支):https://github.com/EmadBeltaje/flutter_slidable
- GitHub 仓库(原版):https://github.com/letsar/flutter_slidable
- pub.dev 包:https://pub.dev/packages/flutter_slidable
- 常见问题:https://github.com/letsar/flutter_slidable/wiki/FAQ