手势操作实用教程 | 实现「滑动清除」效果

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

Flutter 提供了 Dismissible Widget 来轻松地实现这个需求。

步骤

  1. 创建项目列表

  2. 把每一项打包成一个 Dismissible Widget

  3. 提供“滞留”提示

1. 创建项目列表

首先,我们创建一个列表,列表项是能够滑动清除的。至于如何创建列表的更多细节,请参考 长列表的处理 文档。文档链接:https://flutter-io.cn/docs/cookbook/lists/long-lists1.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]}'));

  },

);
  1. 把每一项打包一个 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 {

  final items = List.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')),

            );

          },

        ),

      ),

    );

  }

}


![](https://oss-cn-hangzhou.aliyuncs.com/codingsky/cdn/img/opt/1/a98826289c1a0c7fe5bb4de820304a14)

最多阅读

在Flutter中添加资源和图片 1年以前  |  1933次阅读
发布Flutter开发的iOS程序 1年以前  |  1351次阅读
Flutter Widget框架概述 1年以前  |  1183次阅读
在Flutter中发起HTTP网络请求 1年以前  |  1130次阅读
JSON和序列化 1年以前  |  1063次阅读
使用Inspector检查用户界面 1年以前  |  1045次阅读
Flutter框架概览 1年以前  |  994次阅读
Flutter的手势GestureDetector分析详解 8月以前  |  976次阅读
为Flutter应用程序添加交互 1年以前  |  964次阅读
使用自定义字体 1年以前  |  962次阅读
Flutter插件详解及其发布插件 8月以前  |  930次阅读
处理文本输入 1年以前  |  845次阅读
发布Flutter开发的Android程序 1年以前  |  770次阅读
使用包来开发Flutter应用 1年以前  |  768次阅读
Flutter 状态管理指南之 Provider 9月以前  |  764次阅读
编写国际化Flutter App 1年以前  |  749次阅读
Dart 语法预览 1年以前  |  724次阅读
使用平台通道编写平台特定的代码 1年以前  |  716次阅读
Flutter路由详解 8月以前  |  665次阅读