“滑动清除”在许多移动应用中都很常见。 比如,我们在写一个邮件应用,我们会想让用户能够滑动删除列表中的邮件消息。 用户操作时,我们可能需要把这封邮件从收件箱移动到垃圾箱。
Flutter 提供了
Dismissible
Widget 来轻松地实现这个需求。

步骤
1. 创建项目列表
2. 把每一项打包成一个 Dismissible Widget
3. 提供“滞留”提示
1. 创建项目列表
首先,我们创建一个列表,列表项是能够滑动清除的。 至于如何创建列表的更多细节,请参考 长列表的处理 文档。
文档链接:https://flutter-io.cn/docs/cookbook/lists/long-lists
1.1 创建一个数据源
在我们的例子中,我们需要 20 个样本项来实现列表。 为简单起见,我们会生成一个字符串列表。
final items = List<String>.generate(20, (i) => "Item ${i + 1}");
1.2 将数据源转换成一个 List
首先,我们简单地在屏幕上展示列表中的每一项。 用户现在还无法滑动清除它们。
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(title: Text('${items[index]}'));
},
);
2. 把每一项打包一个 Dismissible Widget
在这个步骤中,用户可以通过使用
Dismissible
来删除列表中的某项。
在用户将某一项滑出屏幕后,我们需要将那一项从列表中删除并显示一个 Snackbar。 在真实的应用中,你可能需要执行更复杂的逻辑,比如从网页服务或数据库中删除此项。
我们可以通过更新
itemBuilder()
函数来返回一个
Dismissible
Widget:
Dismissible(
// Each Dismissible must contain a Key. Keys allow Flutter to
// uniquely identify widgets.
// 每个Dismissible实例都必须包含一个Key。Key让Flutter能够对Widgets做唯一标识。
key: Key(item),
// Provide a function that tells the app
// what to do after an item has been swiped away.
// 我们还需要提供一个函数,告诉应用,在项目被移出后,要做什么。
onDismissed: (direction) {
// Remove the item from the data source.
// 从数据源中移除项目
setState(() {
items.removeAt(index);
});
// Show a snackbar. This snackbar could also contain "Undo" actions.
// 展示一个 snackbar!这个snackbar也可以包含“撤销”动作。
Scaffold
.of(context)
.showSnackBar(SnackBar(content: Text("$item dismissed")));
},
child: ListTile(title: Text('$item')),
);
3. 提供“滞留”提示
顾名思义,我们的应用允许用户将列表项滑出列表,但是应用可能没有向用户给出视觉提示,告诉他们操作时发生了什么。 要给出提示,表明我们正在删除列表项,就需要在他们将列表项滑出屏幕的时候,展示一个“滞留”提示。 这个例子中,我们使用了一个红色背景!
出于这个目的,我们为
Dismissible
设置了一个
background
参数。
Dismissible(
// Show a red background as the item is swiped away.
// 列表项被滑出时,显示一个红色背景
background: Container(color: Colors.red),
key: Key(item),
onDismissed: (direction) {
setState(() {
items.removeAt(index);
});
Scaffold
.of(context)
.showSnackBar(SnackBar(content: Text("$item dismissed")));
},
child: ListTile(title: Text('$item')),
);
完整样例
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
// MyApp is a StatefulWidget. This allows updating the state of the
// widget when an item is removed.
// MyApp是一个StatefulWidget。这样,我们就能够在列表项被移除的时候,更新Widget的状态。
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
@override
MyAppState createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
final items = List<String>.generate(3, (i) => "Item ${i + 1}");
@override
Widget build(BuildContext context) {
final title = 'Dismissing Items';
return MaterialApp(
title: title,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return Dismissible(
// Each Dismissible must contain a Key. Keys allow Flutter to
// uniquely identify widgets.
// 每个Dismissible实例都必须包含一个Key。Key让Flutter能够对Widgets做唯一标识。
key: Key(item),
// Provide a function that tells the app
// what to do after an item has been swiped away.
// 我们还需要提供一个函数,告诉应用,在项目被移出后,要做什么。
onDismissed: (direction) {
// Remove the item from the data source.
// 从数据源中移除项目
setState(() {
items.removeAt(index);
});
// Then show a snackbar.
// 展示一个 snackbar!
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text("$item dismissed")));
},
// Show a red background as the item is swiped away.
// 列表项被滑出时,显示一个红色背景(Show a red background as the item is swiped away)
background: Container(color: Colors.red),
child: ListTile(title: Text('$item')),
);
},
),
),
);
}
}
















