flutter系列之:移动端手势的具体使用

news2024/11/25 7:23:27

文章目录

  • 简介
  • 赋予widget可以点击的功能
  • 会动的组件
  • 可删除的组件
  • 总结

简介

之前我们介绍了GestureDetector的定义和其提供的一些基本的方法,GestureDetector的好处就是可以把任何一个widget都赋予类似button的功能。

今天将会通过几个具体的例子来讲解一下GestureDetector的具体使用。

赋予widget可以点击的功能

一般情况下,我们的普通widget,比如文本是不能进行交互的,但是如果将其用GestureDetector进行包装之后,就可以将其伪装成为一个button。

比如我们有这样一个伪装成button的Container:

Container(
        padding: const EdgeInsets.all(12.0),
        decoration: BoxDecoration(
          color: Colors.green,
          borderRadius: BorderRadius.circular(8.0),
        ),
        child: const Text('My Button'),
      )

这个Container的本质是一个Text,这个Container本身是没有交互功能的,那么如何对其添加交互功能呢?

最简单的办法就是将其使用GestureDetector包装起来,如下所示:

GestureDetector(
      // The custom button
      child: Container(
        padding: const EdgeInsets.all(12.0),
        decoration: BoxDecoration(
          color: Colors.green,
          borderRadius: BorderRadius.circular(8.0),
        ),
        child: const Text('My Button'),
      ),
    )

接下来我们还要为其添加对应的手势,这里我们添加一个onTap方法,

GestureDetector(
      onTap: ()=> showDialog<String>(
        context: context,
        builder: (BuildContext context) => AlertDialog(
          title: const Text('基本手势'),
          content: const Text('这是基本的手势,你学会了吗?'),
          actions: <Widget>[
            TextButton(
              onPressed: () => Navigator.pop(context, 'Cancel'),
              child: const Text('Cancel'),
            ),
            TextButton(
              onPressed: () => Navigator.pop(context, 'OK'),
              child: const Text('OK'),
            ),
          ],
        ),
      ),
      ...

这里onTap会调用一个showDialog来弹出一个对话框,运行之后结果如下:

会动的组件

在上面的例子中,我们用手去tap按钮是没有互动效果的,也就是说按钮是不会变化的。

那么有没有可能模拟手指的按压效果呢?

答案是肯定的,flutter为我们提供了一个InkWell组件,这样手指按压下组件会产生波纹的效果。

那么InkWell和GestureDetector有什么联系呢?

InkWell和GestureDetector很类似,都提供了对手势的支持。

在InkWell中提供了多种GestureTapCallback接口,用接收手势的回调,非常的方便。

在使用上,InkWell和GestureDetector也很类似,我们可以完全照搬GestureDetector的用法。

还是上面的例子,我们可以将GestureDetector替换成为InkWell,如下所示:

  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
          content: Text('Tap'),
        ));
      },
      child: const Padding(
        padding: EdgeInsets.all(12.0),
        child: Text('Flat Button'),
      ),
    );
  }

这里,为了更好的观察手势按压之后的效果,这里onTap选择展示一个flutter自带的SnackBar。

可删除的组件

在app中的手势应用上,有一个比较常见的用法就是在list列表中,向左滑动一个item,会出现删除的按钮,这种滑动删除的效果,如何在flutter中实现呢?

flutter提供了一个Dismissible的组件来实现这个效果。

我们先来看下Dismissible的定义:

class Dismissible extends StatefulWidget {
    const Dismissible({
    required Key key,
    required this.child,
    this.background,
    this.secondaryBackground,
    this.confirmDismiss,
    this.onResize,
    this.onUpdate,
    this.onDismissed,
    this.direction = DismissDirection.horizontal,
    this.resizeDuration = const Duration(milliseconds: 300),
    this.dismissThresholds = const <DismissDirection, double>{},
    this.movementDuration = const Duration(milliseconds: 200),
    this.crossAxisEndOffset = 0.0,
    this.dragStartBehavior = DragStartBehavior.start,
    this.behavior = HitTestBehavior.opaque,
  }) : assert(key != null),
       assert(secondaryBackground == null || background != null),
       assert(dragStartBehavior != null),
       super(key: key);

可以看到Dismissible是一个StatefulWidget,它有两个必须的参数分别是key和child。

key用来标记要删除item的id,child是可以滑动删除的组件。

为了演示方便,我们使用ListView来展示如何使用Dismissible。

首先我们构建一个items的list,里面包含了每个item要展示的内容:

 final items = List<String>.generate(10, (i) => '动物 ${i + 1}');

然后使用ListView的builder方法来构建items。并且将每个items封装到Dismissible中去:

body: ListView.builder(
          itemCount: items.length,
          itemBuilder: (context, index) {
            final item = items[index];
            return Dismissible(
              key: Key(item),
              onDismissed: (direction) {
                setState(() {
                  items.removeAt(index);
                });
                ScaffoldMessenger.of(context)
                    .showSnackBar(SnackBar(content: Text('$item 被删除了')));
              },
              child: ListTile(
                title: Text(item),
              ),
            );
          },
        )

这里Dismissible的child是ListTile组件,里面的具体内容就是Text。

现在Dismissible实际上就可以工作了,当你滑动ListTile的时候,对应的item就会被删除。

为了明显起见,我们可以给Dismissible添加一个background属性,这样滑动删除的时候就有了一个背景颜色:

              background: Container(color: Colors.red),

另外,Dismissible还有一个confirmDismiss属性,可以用来判断是否真的要滑动删除,比如我们只允许从右到左滑动删除,那么可以这样做:

Dismissible(
  ...
confirmDismiss:confirmResult,
...
)

  Future<bool> confirmResult(DismissDirection direction) async {
    if(direction == DismissDirection.endToStart){
      return true;
    }
    return false;
  }

这里的confirmResult是一个异步函数,它接收一个DismissDirection的参数,这个参数表示的是滑动删除的方向,我们可以通过这个方向来判断是否真正的进行删除操作。

总结

以上就是日常手势的基本使用了,我们可以通过GestureDetector,InkWell和Dismissible来和手势进行结合来实现相应的功能。

本文的例子:https://github.com/ddean2009/learn-flutter.git

更多内容请参考 www.flydean.com

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/102168.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用ChatGPT写一段嵌入式代码

已剪辑自: https://mp.weixin.qq.com/s/uKkUwXx32LPkUYQK44z1lw 废话不多说&#xff0c;开整&#xff01; ChatGPT: Optimizing Language Models for Dialogue&#xff0c;即优化对话的语言模型&#xff0c;它以对话的方式进行交互。对话形式使ChatGPT能够回答后续问题&#…

性能测试---LoadRunner

目录 1.LoadRunner对比Jmeter的优势 2.LoadRunner三个组件之间的关系 3.学习VUG的使用 3.1创建性能测试脚本并进行录制 第一步:打开VUG,创建一个新的性能测试的脚本 第二步:对新建的脚本进行设置 第三步:启动WebTours服务 第四步:回到VUG中,点击录制按钮并设置录制选项…

学习编程的五个关键点!你需要get它,并运用!

总体来说&#xff0c;学习如何编程是一件较难的事情。我最近发现大学里的计算机课程和各种编程训练营错过了编程的一些重要因素&#xff0c;对新手的教学用了不太恰当的方法。于是&#xff0c;我准备分享一个成功的编程课程应该具备的五大基本支柱。 菜鸟的目标是掌握编程的基…

form表单发送put、delete、patch请求的实现过程

关于发送put、delete、patch请求底层实现过程 对于put这些请求&#xff0c;我们无法直接通过form表单发送&#xff0c;form表单仅支持get和post请求&#xff1b; 虽然我们无法直接通过form表单发送这些请求&#xff0c;但我们可以以form表单为载体做二次请求&#xff1a;使用f…

[附源码]计算机毕业设计Node.js宠物商店管理系统(程序+LW)

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

48数据流中的中位数 49表达式 50两数之和

48数据流中的中位数 第一次没看到要求排序&#xff0c;还以为题目答案写错了&#xff0c;用排序的内置函数也正好是nlogn import java.util.ArrayList;public class Solution {ArrayList<Integer> list new ArrayList<>();public void Insert(Integer num) {list…

小满nestjs(第二十七章 nestjs typeOrm关系)

在我们开始的过程中&#xff0c;肯定不会把数据存在一个表里面&#xff0c;我们会进行分表&#xff0c;把数据分开存&#xff0c;然后通过关联关系&#xff0c;联合查询。 typeOrm 文档 一对一 | TypeORM 中文文档 前端代码还是复用上一章的 增加了一个添加Tag <template…

腾讯安全联合发布《2022游戏安全白皮书》:外挂对抗仍然激烈

2022年以来&#xff0c;各类游戏安全事件的发生给不断影响着游戏生态的健康发展。同时&#xff0c;随着游戏行业数字化进程的加快&#xff0c;以及游戏全球化布局的不断推进&#xff0c;游戏厂商对于游戏安全的投入越来越大&#xff0c;掌握最新的行业安全态势有利于其安全防护…

外汇天眼:WiKiEXPO亮相香港亚洲博览馆,史上最强大咖阵容坐镇

凛冬已至&#xff0c;在这个寒冷的冬天&#xff0c;WikiGlobal将于2022年12月16日至17日早9:00--晚18:00在香港的亚洲国际博览馆举办为期两天的“Wiki Finance EXPO Asia 2022”。目前展会已拉开帷幕。  此次展会展厅面积高达5000多平方米&#xff0c;经过WiKiEXPO科学的规划和…

【数据结构】线性表之单链表

目录 一、链表的概念 1、概念 2、分类 3、重点 二、单链表模拟实现 1、准备 2、头插法 3、尾插法 4、指定下标插入 5、遍历 6、删除第一次出现的元素key 7、删除所有的key 8、双指针删除所有的key 一、链表的概念 1、概念 是一种物理存储结构上非连续的存储结构&a…

PS-历史记录

目录 哪里能找到【历史记录】面板 1、窗口→历史记录 2、编辑→清理→历史记录 还原 1、点击【历史记录】面板 快捷键 【ctrlz】 【shiftctrlz】 从当前状态创建新文档 创建新快照 给快照起名 1、右击你要创建快照的步骤 2、点击面板菜单 3、先按住alt不动&#…

Java 对象和类

Java作为一种面向对象语言。支持以下基本概念&#xff1a; 多态继承封装抽象类对象实例方法重载 本节我们重点研究对象和类的概念。 对象&#xff1a;对象是类的一个实例&#xff08;对象不是找个女朋友&#xff09;&#xff0c;有状态和行为。例如&#xff0c;一条狗是一个对…

猿如意|chat GPT测评

文章目录猿如意猿如意传送门猿如意个人使用感受好的一面&#xff1a;可以改进的一面:什么是猿如意chat GPT测评chat GPT使用过程使用场景描述&#xff1a;问题1问题2问题3问题4&#xff1a;问题5&#xff1a;主观感受&#xff1a;认为此功能不足的地方&#xff1a;对此功能的期…

学习编程的过程中可能会走哪些弯路,有哪些经验可以参考?

很多人学习编程, 走的弯路可以总结为以下几点: 一言不合找视频&#xff0c;几十集视频刷半年。 很多人学习编程的时候&#xff0c;喜欢看视频学&#xff0c;我这里总结一下看视频学习编程的弊端。 1. 完善的视频资源往往稍稍过时&#xff0c;比如你会发现很多java的教学视频…

产品设计市场调研有哪些特点?

产品市场种类繁多&#xff0c;变化无常&#xff0c;消费者需求各异。在工业设计之初&#xff0c;需要对行业和区域环境进行调查分析&#xff0c;深入了解市场情况、市场供求关系、客户引导、趋势等&#xff0c;客观合理地对新产品进行适当定位。只有有了正确的新产品概念规划方…

三方接口签名验签简易设计与实现

本人水平有限&#xff0c;对密码学的理解相当浅显。错误与疏漏&#xff0c;欢迎各位指正。 〇、写在前面 接口安全防护是个永恒的话题&#xff0c;提供给前端的接口需要登录&#xff0c;提供给服务的接口(下文简称"三方接口")也需要鉴权&#xff1b;当前大环境下,ht…

chatgpt教我内存对齐,对齐了但没完全对齐?

文章目录内存对齐关于chatgpt的回答总结内存对齐 关于chatgpt的回答 我与chatgpt的对话如下&#xff1a; 我现在来描述与总结上述对话都干了啥以及我为什么要问这个。 我本来是在学习rapidjson源码里面的内存池实现&#xff0c;然后 RAPIDJSON_ALIGN 没有看懂&#xff0c;所…

JSP课设:家庭相册管理系统(附源码+调试)

JSP家庭相册管理系统 &#xff08;1&#xff09;登录模块&#xff1a;分为普通用户和管理员两种角色&#xff1b; &#xff08;2&#xff09;普通用户模块&#xff1a;相册管理&#xff1a;用户可以对自己相册进行编辑&#xff0c;可以进行批量删除相册、新增相册、编辑相册以…

【Golang】案例为基浅谈Go的变量与常量

&#x1f4d3;推荐网站(不断完善中)&#xff1a;个人博客 &#x1f4cc;个人主页&#xff1a;个人主页 &#x1f449;相关专栏&#xff1a;CSDN专栏、个人专栏 &#x1f3dd;立志赚钱&#xff0c;干活想躺&#xff0c;瞎分享的摸鱼工程师一枚 &#x1f352;前言 在上一篇文章中…

Python图像识别实战(三):基于OpenCV实现批量单图像超分辨重建(附源码和实现效果)

前面我介绍了可视化的一些方法以及机器学习在预测方面的应用&#xff0c;分为分类问题&#xff08;预测值是离散型&#xff09;和回归问题&#xff08;预测值是连续型&#xff09;&#xff08;具体见之前的文章&#xff09;。 从本期开始&#xff0c;我将做一个关于图像识别的…