“滑动删除”模式在移动应用中很常见。例如,如果我们正在编写一个电子邮件应用程序,我们希望允许我们的用户在列表中滑动电子邮件。当他们这样做时,我们需要将该条目从收件箱移至垃圾箱。

Flutter通过提供Dismissable Widget 使这项任务变得简单。

步骤

  1. 创建item列表。
  2. 将每个item包装在一个Dismissable Widget中。
  3. 提供滑动背景提示。

1. 创建item列表

第一步是创建一个我们可以滑动的列表。有关如何创建列表的更多详细说明,请按照使用长列表进行操作。

创建数据源

在我们的例子中,我们需要20个条目。为了简单起见,我们将生成一个字符串列表。

  1. final items = new List<String>.generate(20, (i) => "Item ${i + 1}");

将数据源转换为List

首先,我们将简单地在屏幕上的列表中显示每个项目(先不支持滑动)。

  1. new ListView.builder(
  2. itemCount: items.length,
  3. itemBuilder: (context, index) {
  4. return new ListTile(title: new Text('${items[index]}'));
  5. },
  6. );

将每个item包装在Dismissible Widget中

现在我们希望让用户能够将条目从列表中移除,用户删除一个条目后,我们需要从列表中删除该条目并显示一个Snackbar。 在实际的场景中,您可能需要执行更复杂的逻辑,例如从Web服务或数据库中删除条目。

这是我们就可以使用Dismissable。在下面的例子中,我们将更新itemBuilder函数以返回一个DismissableWidget。

  1. new Dismissible(
  2. // Each Dismissible must contain a Key. Keys allow Flutter to
  3. // uniquely identify Widgets.
  4. key: new Key(item),
  5. // We also need to provide a function that will tell our app
  6. // what to do after an item has been swiped away.
  7. onDismissed: (direction) {
  8. // Remove the item from our data source
  9. items.removeAt(index);
  10. // Show a snackbar! This snackbar could also contain "Undo" actions.
  11. Scaffold.of(context).showSnackBar(
  12. new SnackBar(content: new Text("$item dismissed")));
  13. },
  14. child: new ListTile(title: new Text('$item')),
  15. );

3. 提供滑动背景提示

现在,我们的应用程序将允许用户从列表中滑动项目,但用户并不知道滑动后做了什么,所以,我们需要告诉用户滑动操作会移除条目。 为此,我们将在滑动条目时显示指示。在下面的例子中,我们通过将背景设置为红色表示为删除操作。

为此,我们为Dismissable提供一个background参数。

  1. new Dismissible(
  2. // Show a red background as the item is swiped away
  3. background: new Container(color: Colors.red),
  4. key: new Key(item),
  5. onDismissed: (direction) {
  6. items.removeAt(index);
  7. Scaffold.of(context).showSnackBar(
  8. new SnackBar(content: new Text("$item dismissed")));
  9. },
  10. child: new ListTile(title: new Text('$item')),
  11. );

完整的例子

  1. import 'package:flutter/foundation.dart';
  2. import 'package:flutter/material.dart';
  3. void main() {
  4. runApp(new MyApp(
  5. items: new List<String>.generate(20, (i) => "Item ${i + 1}"),
  6. ));
  7. }
  8. class MyApp extends StatelessWidget {
  9. final List<String> items;
  10. MyApp({Key key, @required this.items}) : super(key: key);
  11. @override
  12. Widget build(BuildContext context) {
  13. final title = 'Dismissing Items';
  14. return new MaterialApp(
  15. title: title,
  16. home: new Scaffold(
  17. appBar: new AppBar(
  18. title: new Text(title),
  19. ),
  20. body: new ListView.builder(
  21. itemCount: items.length,
  22. itemBuilder: (context, index) {
  23. final item = items[index];
  24. return new Dismissible(
  25. // Each Dismissible must contain a Key. Keys allow Flutter to
  26. // uniquely identify Widgets.
  27. key: new Key(item),
  28. // We also need to provide a function that will tell our app
  29. // what to do after an item has been swiped away.
  30. onDismissed: (direction) {
  31. items.removeAt(index);
  32. Scaffold.of(context).showSnackBar(
  33. new SnackBar(content: new Text("$item dismissed")));
  34. },
  35. // Show a red background as the item is swiped away
  36. background: new Container(color: Colors.red),
  37. child: new ListTile(title: new Text('$item')),
  38. );
  39. },
  40. ),
  41. ),
  42. );
  43. }
  44. }