实现滑动关闭
如何实现滑动以删除或移除内容。
“滑动删除”模式在许多移动应用中都很常见。例如,在编写电子邮件应用时,你可能希望允许用户滑动邮件以将其从列表中删除。
Flutter 通过提供 Dismissible 组件让这一任务变得简单。按照以下步骤了解如何实现滑动删除:
- 创建列表项。
- 使用
Dismissible组件包裹每个列表项。 - 提供“滑走后”的背景指示器。
1. 创建列表项
#首先,创建列表项。关于如何创建列表的详细说明,请参考处理长列表方案。
创建一个数据源
#在这个示例中,你需要 20 个示例项来操作。为简单起见,生成一个字符串列表。
dart
final items = List<String>.generate(20, (i) => 'Item ${i + 1}');
将数据源转换为列表
#在屏幕上显示列表中的每一项。此时,用户还无法滑动这些列表项。
dart
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(title: Text(items[index]));
},
)
2. 使用 Dismissible 组件包裹每个列表项
#在此步骤中,使用 Dismissible 组件让用户能够从列表中滑动移除某一项。
当用户滑走列表项后,从列表中删除该项并显示一个 snackbar。在真实的应用中,你可能需要执行更复杂的逻辑,例如从 Web 服务或数据库中删除该项。
更新 itemBuilder() 函数以返回 Dismissible 组件。
dart
itemBuilder: (context, index) {
final item = items[index];
return Dismissible(
// Each Dismissible must contain a Key. Keys allow Flutter to
// uniquely identify 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.
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('$item dismissed')));
},
child: ListTile(title: Text(item)),
);
},
3. 提供“滑走后”的背景指示器
#目前,应用允许用户通过滑动将列表项移除,但没有给出操作后的视觉反馈。为了提示用户列表项已被删除,可以在滑动移除列表项时显示一个“滑走后”的背景指示器。在本例中,该指示器为一个红色背景。
要添加指示器,请为 Dismissible 提供 background 参数。
dart
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('$item dismissed')));
},
// Show a red background as the item is swiped away.
background: Container(color: Colors.red),
child: ListTile(
title: Text(item),
),
互动示例
#import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
// MyApp is a StatefulWidget. This allows updating the state of the
// widget when an item is removed.
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
MyAppState createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
final items = List<String>.generate(20, (i) => 'Item ${i + 1}');
@override
Widget build(BuildContext context) {
const title = 'Dismissing Items';
return MaterialApp(
title: title,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: Scaffold(
appBar: AppBar(title: const 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.
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.
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('$item dismissed')));
},
// Show a red background as the item is swiped away.
background: Container(color: Colors.red),
child: ListTile(title: Text(item)),
);
},
),
),
);
}
}