效果图
概念
Slidable 是一个 Flutter 包,用于创建类似 iOS 邮件应用中的滑动列表项,可以向左或向右滑动显示操作按钮。
安装
flutter_slidable: ^4.0.3主要参数
Slidable({ Key? key, Widget? child, // 滑动的内容 SlidableController? controller, // 控制器 Axis direction = Axis.horizontal, // 滑动方向 bool enabled = true, // 是否启用滑动 bool closeOnScroll = true, // 滚动时自动关闭 double? threshold, // 触发阈值 Duration? duration, // 动画时长 // 动作面板 ActionPane? startActionPane, // 左侧动作面板 ActionPane? endActionPane, // 右侧动作面板 // 分组 String? groupTag, // 分组标签 // 监听器 ValueChanged<SlideActionType>? onSlideAction, // 滑动动作回调 ValueChanged<double>? onSlideIsOpenChanged, // 打开状态变化 })ActionPane配置
ActionPane( motion: DrawerMotion(), // 动画类型 dismissible: DismissiblePane( // 可消失的面板 onDismissed: () {}, // 消失回调 ), extentRatio: 0.25, // 面板占宽度比例 dragDismissible: true, // 拖动可消失 children: [ // 动作按钮列表 SlidableAction(...), SlidableAction(...), ], )关键代码
return Slidable( // 右侧滑动面板 endActionPane: ActionPane( motion: ScrollMotion(), // 滑动动画效果 children: [ // 删除动作 SlidableAction( onPressed: (context) => _deleteItem(index), //点击删除 backgroundColor: Colors.red, //背景色 foregroundColor: Colors.white, //前景色 icon: Icons.delete, //图标 spacing: 0, // 按钮间距 borderRadius: BorderRadius.circular(0), // 圆角 autoClose: true, // 点击后自动关闭面板 label: '删除', ), // 编辑动作 SlidableAction( onPressed: (context) => _editItem(index), //点击编辑 backgroundColor: Colors.blue, foregroundColor: Colors.white, icon: Icons.edit, label: '编辑', ), ], ), // 左侧滑动面板 startActionPane: ActionPane( motion: ScrollMotion(), //滑动动画效果 children: [ SlidableAction( onPressed: (context) => _shareItem(index), //点击分享 backgroundColor: Colors.green, foregroundColor: Colors.white, icon: Icons.share, label: '分享', ), SlidableAction( onPressed: (context) => _archiveItem(index), //点击归档 backgroundColor: Colors.orange, foregroundColor: Colors.white, icon: Icons.archive, label: '归档', ), ], ), //列表项内容 child: ListTile( leading: CircleAvatar( //圆形头像组件 backgroundColor: Colors.blue[100], child: Text('${index + 1}'), ), title: Text(item['title']), trailing: Icon(Icons.chevron_right), ), );代码实例
import 'dart:async'; import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:my_flutter/ble_scanner.dart'; import 'package:my_flutter/path_manager.dart'; class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<StatefulWidget> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { //1.准备数据 final List<Map<String, dynamic>> _items = List.generate( 10, (i) => { 'id': i, 'title': '项目 ${i + 1}', }, ); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Flutter Slidable 示例')), body: ListView.builder( itemCount: _items.length, itemBuilder: (context, index) { final item = _items[index]; return Slidable( // 右侧滑动面板 endActionPane: ActionPane( motion: ScrollMotion(), // 滑动动画效果 children: [ // 删除动作 SlidableAction( onPressed: (context) => _deleteItem(index), //点击删除 backgroundColor: Colors.red, //背景色 foregroundColor: Colors.white, //前景色 icon: Icons.delete, //图标 spacing: 0, // 按钮间距 borderRadius: BorderRadius.circular(0), // 圆角 autoClose: true, // 点击后自动关闭面板 label: '删除', ), // 编辑动作 SlidableAction( onPressed: (context) => _editItem(index), //点击编辑 backgroundColor: Colors.blue, foregroundColor: Colors.white, icon: Icons.edit, label: '编辑', ), ], ), // 左侧滑动面板 startActionPane: ActionPane( motion: ScrollMotion(), //滑动动画效果 children: [ SlidableAction( onPressed: (context) => _shareItem(index), //点击分享 backgroundColor: Colors.green, foregroundColor: Colors.white, icon: Icons.share, label: '分享', ), SlidableAction( onPressed: (context) => _archiveItem(index), //点击归档 backgroundColor: Colors.orange, foregroundColor: Colors.white, icon: Icons.archive, label: '归档', ), ], ), //列表项内容 child: ListTile( leading: CircleAvatar( //圆形头像组件 backgroundColor: Colors.blue[100], child: Text('${index + 1}'), ), title: Text(item['title']), trailing: Icon(Icons.chevron_right), ), ); }, ), ); } void _deleteItem(int index) { showDialog( context: context, builder: (context) => AlertDialog( title: Text('确认删除'), content: Text('确定要删除 "${_items[index]['title']}" 吗?'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text('取消'), ), TextButton( onPressed: () { setState(() { _items.removeAt(index); }); Navigator.pop(context); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('已删除')), ); }, child: Text('删除'), ), ], ), ); } void _editItem(int index) { // 编辑逻辑 } void _shareItem(int index) { // 分享逻辑 } void _archiveItem(int index) { // 归档逻辑 } }