Flutter笔记:缩放手势

news2024/11/16 19:29:57
Flutter笔记
缩放手势

作者李俊才 (jcLee95):https://blog.csdn.net/qq_28550263
邮箱 :291148484@163.com
本文地址:https://blog.csdn.net/qq_28550263/article/details/134485138



1. 概述

Flutter 中,缩放手势是一种常见的交互方式,它允许用户通过双指触摸屏幕来改变 UI 元素的大小。这种手势常用于查看图片、地图等场景中。本文接下来将先后介绍如何使用 GestureDetector 和更底层的 ScaleGestureRecognizer 各自实现缩放的代码如何写。

2. 缩放手势的识别和处理

在 Flutter 中,缩放手势的识别和处理主要依赖于 GestureDetector 组件。这个组件可以识别各种手势,包括缩放手势。

2.1 GestureDetector 组件

GestureDetector 组件有多个属性用于处理缩放,主要包括:

属性描述
onScaleStart当缩放手势开始时调用
onScaleUpdate当缩放手势更新时调用
onScaleEnd当缩放手势结束时调用

例如:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('GestureDetector Example'),
        ),
        body: const Center(
          child: MyScale(),
        ),
      ),
    );
  }
}

class MyScale extends StatefulWidget {
  const MyScale({super.key});

  
  State<MyScale> createState() => _MyScaleState();
}

class _MyScaleState extends State<MyScale> {
  double _scale = 1.0;

  
  Widget build(BuildContext context) {
    return GestureDetector(
      onScaleStart: (ScaleStartDetails details) {
        print('缩放开始');
      },
      onScaleUpdate: (ScaleUpdateDetails details) {
        setState(() {
          _scale = details.scale;
        });
        print('缩放更新,当前缩放值:$_scale');
      },
      onScaleEnd: (ScaleEndDetails details) {
        print('缩放结束');
      },
      child: Transform.scale(
        scale: _scale,
        child: const FlutterLogo(size: 200),
      ),
    );
  }
}

上面的代码中,我们使用 GestureDetector 组件来识别缩放手势,并在 onScaleUpdate 回调函数中更新 _scale 变量的值。然后,我们使用 Transform.scale 组件来根据 _scale 的值来改变 Flutter Logo 的大小。其效果如下:

在这里插入图片描述

2.2 RawGestureDetector 和

RawGestureDetector 组件

使用 RawGestureDetectorScaleGestureRecognizer 也可以实现缩放手势。在大多数情况下,GestureDetector 组件已经足够用于处理缩放手势。然而,在一些的场景中我们可能需要更多的控制,这时就可以使用 ScaleGestureRecognizer 类。

const RawGestureDetector({
  Key? key,
  this.child,
  this.gestures = const <Type, GestureRecognizerFactory>{},
  this.behavior,
  this.excludeFromSemantics = false,
  this.semantics,
}) : super(key: key);

ScaleGestureRecognizer 类

ScaleGestureRecognizer 继承自 GestureRecognizer 类,是更底层的手势识别器,用于识别缩放手势。

ScaleGestureRecognizer 跟踪与屏幕接触的指针,并计算它们的焦点、指示的缩放级别和旋转。当建立一个焦点时,识别器会调用 onStart回调函数。随着焦点、缩放和旋转的变化,识别器会调用 onUpdate回调函数。当指针不再与屏幕接触时,识别器会调用 onEnd回调函数。

以下是 ScaleGestureRecognizer 的一些重要属性和方法:

  • onStart:当与屏幕接触的指针建立了焦点和初始缩放级别为1.0时调用。
  • onUpdate:当与屏幕接触的指针指示了新的焦点和/或缩放时调用。
  • onEnd:当指针不再与屏幕接触时调用。
  • addPointer:注册可能与此手势检测器相关的新指针。
  • addAllowedPointer:注册已经被此手势识别器允许的新指针。
  • dispose:释放由对象使用的任何资源。

ScaleGestureRecognizer 类的造函数如下:

ScaleGestureRecognizer({
  Object? debugOwner, // 用于在调试打印中识别手势识别器的对象。
  PointerDeviceKind? kind, // 此手势识别器应该处理的设备类型
  this.dragStartBehavior = DragStartBehavior.start, // 确定在所有涉及此手势的计算中,用作起点的点
})

其中:

  • kind:此手势识别器应该处理的设备类型。例如,如果 kind 设置为 PointerDeviceKind.mouse,那么这个手势识别器只会识别鼠标的手势。
  • dragStartBehavior:确定在所有涉及此手势的计算中,用作起点的点。默认值为 DragStartBehavior.start。

案例

下面是一个使用 RawGestureDetectorScaleGestureRecognizer 来识别和处理缩放和拖动手势的示例:

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('GestureDetector Example'),
        ),
        body: const Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  const MyWidget({Key? key}) : super(key: key);

  
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  final _scaleRecognizer = ScaleGestureRecognizer();
  double _scale = 1.0;
  Offset _panOffset = Offset.zero;

  
  void initState() {
    super.initState();
    _scaleRecognizer
      ..onStart = _handleScaleStart
      ..onUpdate = _handleScaleUpdate
      ..onEnd = _handleScaleEnd;
  }

  
  void dispose() {
    _scaleRecognizer.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return RawGestureDetector(
      gestures: {
        ScaleGestureRecognizer:
            GestureRecognizerFactoryWithHandlers<ScaleGestureRecognizer>(
          () => _scaleRecognizer,
          (ScaleGestureRecognizer instance) {},
        ),
      },
      child: Transform.scale(
        scale: _scale,
        child: Transform.translate(
          offset: _panOffset,
          child: const FlutterLogo(size: 200),
        ),
      ),
    );
  }

  void _handleScaleStart(ScaleStartDetails details) {
    print('缩放开始');
  }

  void _handleScaleUpdate(ScaleUpdateDetails details) {
    setState(() {
      _scale = details.scale;
      _panOffset = details.localFocalPoint;
    });
    print('缩放更新,当前缩放值:$_scale');
    print('拖动更新,当前偏移值:$_panOffset');
  }

  void _handleScaleEnd(ScaleEndDetails details) {
    print('缩放结束');
  }
}

在这里插入图片描述

需要注意的是,使用 RawGestureDetector 比使用 GestureDetector 组件更复杂,需要手动管理手势的生命周期,包括创建、更新和释放手势。因此,除非你需要处理复杂的手势,否则通常推荐使用 GestureDetector 组件。

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

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

相关文章

QGroundControl源码编译的三种方法

1.使用QtCreator编译: 下载qgroundcontrol源码 https://github.com/mavlink/qgroundcontrol.git 克隆 同步子模块 使用打开qgroundcontrol.pro 打开前要求先安装qt 5.15.2

【神印王座】月夜大尺度诱惑,皓晨潜入月魔宫,枫秀降临男扮女装

Hello,小伙伴们&#xff0c;我是拾荒君。 为了能安全回到联盟&#xff0c;龙皓晨决定让月夜商队护送他们&#xff0c;这也是他们目前处境更快更安全回到人类境地的方法。于是&#xff0c;龙皓晨只身一人去寻找月夜&#xff0c;此次执行的任务完全超出龙皓晨的掌握之外&#xf…

数据结构与算法-图

图 &#x1f388;2.图的存储结构&#x1f4d6;2.4.2邻接表的存储✅2.4.2.1逆邻接表✅2.4.2.2邻接表存储结构的定义✅2.4.2.3邻接表存储结构的类定义✅2.4.2.4创建n个顶点m条边的无向网✅2.4.2.5创建n个顶点m条边的有向网✅2.4.2.6定位操作-查找定点信息在顶点数组中的下标✅2.4…

操作系统:操作系统教程第六版(骆斌、葛季栋、费翔林)习题一计算机操作系统概述

目录 前言1. 思考题2. 应用题 前言 本系列文章是针对操作系统教程第六版&#xff08;骆斌、葛季栋、费翔林&#xff09;的习题解答&#xff0c;其中简答题部分为博主自己搜索整理的&#xff0c;错漏之处在所难免。应用题部分有答案为依据。 1. 思考题 &#xff08;1&#xf…

算数通关村第十一关-白银挑战位运算高频题

位移的运算 位1的个数 描述 : 编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中数字位数为 1 的个数&#xff08;也被称为汉明重量&#xff09;。 题目 : LeetCode 191.位1的个数 191. 位1的个数…

pr出现由于找不到msvcp110.dll,无法继续执行代码怎么办?如何修复

为什么我们在打开运行电脑软件会出现msvcr110.dll无法继续执行此代码的问题呢&#xff1f;因为msvcr110.dll是Microsoft Visual C Redistributable Package for Visual Studio 2013的一个动态链接库。它是一个重要的组件&#xff0c;用于帮助游戏和软件运行。如果某个程序是用它…

程序的编译链接以及装载

目录 一、预处理 二、编译 三、汇编 四、链接 五、装载 一、预处理 读取c源程序&#xff0c;对其中的伪指令&#xff08;以#开头的指令&#xff09;和特殊符号进行处理&#xff0c; 伪指令主要包括以下五个方面&#xff1a; 宏定义指令&#xff0c;如#define Name Token…

BUUCTF [BJDCTF2020]你猜我是个啥 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 来源&#xff1a;https://github.com/BjdsecCA/BJDCTF2020 密文&#xff1a; 下载附件&#xff0c;得到一个zip压缩包。 解题思路&#xff1a; 1、尝试解压压缩包&#xff0c;提示“attachment_10.zip”不是压缩文…

安装宝塔,使用宝塔自动部署

这里用的是华为云服务器&#xff0c;其实也就是普普通通的一个linux操作系统 首先我们来到宝塔官网地址 宝塔面板下载&#xff0c;免费全能的服务器运维软件 (bt.cn) 翻到下面&#xff0c;会有使用脚本安装的命令。 yum install -y wget && wget -O install.sh https:/…

springboot集成nacos并实现自动刷新

目录 1.说明 2.示例 3.自动刷新的注意点 1.说明 springboot项目中存在好多配置文件&#xff0c;比如配置数据信息&#xff0c;redis信息等等&#xff0c;配置文件可以直接放在代码&#xff0c;也可以放在像nacos这样的组件中&#xff0c;实现动态的管理&#xff0c;修改配置…

Springboot 对于数据库字段加密方案(此方案是对字符串处理的方案)

背景:在erp开发中&#xff0c;有些用户比较敏感数据库里的数据比较敏感&#xff0c;系统给用户部署后&#xff0c;公司也不想让任何人看到数据&#xff0c;所以就有了数据库字段加密方案。 技术 spring boot mybatisplus 3.3.1 mybatisplus 实际提供了 字段加密方案 第一 他…

Flutter笔记:拖拽手势

Flutter笔记 拖拽手势 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/134485123 目 录 1. 概述2. 垂直拖…

JDK1.5 新特性【泛型】

前言 泛型在 JavaSE 阶段是学习过的&#xff0c;但是毕竟处理定义一些简单的集合就很少用到它了&#xff0c;至于最近 Flink 中遇到的 泛型方法&#xff0c;更是感觉闻所未闻&#xff0c;以及源码中加在接口、方法、类前的各种 <T,V> 让我实在自觉羞愧&#xff0c;于是今…

leetcode34.排序数组中查找元素第一个和最后一个位置两种解题方法(超详细)

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/description/?envTypelist&envIdZCa7r67M这道题&#xff0c;读者可能会说这道题有什么好…

二阶低通滤波器(二阶巴特沃斯滤波器)

连续传递函数G(s) 离散传递函数G(z) 差分方程形式 二阶巴特沃斯滤波器参数设计 设计采样频率100Hz&#xff0c;截止频率33Hz。 注意&#xff1a;设计参数使用在离散系统中&#xff01; 同理&#xff0c;其他不同阶数不同类型的滤波器设计&#xff0c;如二阶高通滤波器、二阶…

Transformer ZOO

Natural Language Processing Transformer:Attention is all you need URL(46589)2017.6 提出Attention机制可以替代卷积框架。引入Position Encoding&#xff0c;用来为序列添加前后文关系。注意力机制中包含了全局信息自注意力机制在建模序列数据中的长期依赖关系方面表现出…

嵌入式开发--赛普拉斯cypress的铁电存储器FM25CL64B

嵌入式开发–赛普拉斯cypress的铁电存储器FM25CL64B 简介 FM25CL64B是赛普拉斯cypress出品的一款铁电存储器&#xff0c;这种存储器最大的优势是可以像RAM一样随机存储&#xff0c;和按字节写入&#xff0c;也可以像ROM一样掉电仍然可以保存数据&#xff0c;是一种相当优秀的…

宠物信息服务预约小程序的效果如何

宠物的作用越来越重要&#xff0c;因此铲屎官们对自己爱宠的照顾也是加倍提升&#xff0c;而市场围绕宠物展开的细分服务近些年来逐渐增多&#xff0c;且市场规模快速增长。涉及之广&#xff0c;涵盖宠物衣食住行、医疗、美容、婚丧嫁娶等&#xff0c;各品牌争相抢夺客户及抢占…

java游戏制作-拼图游戏

一.制作主界面 首先创建一个Java项目命名为puzzlegame。 再在src中创建一个包&#xff0c;用来制作主界面 代码&#xff1a; 结果&#xff1a; 二.设置界面 代码&#xff1a; 三.初始化界面 代码&#xff1a; 优化代码&#xff1a; 结果&#xff1a; 四.添加图片 先在Java项…

思维模型 留白效应

本系列文章 主要是 分享 思维模型 &#xff0c;涉及各个领域&#xff0c;重在提升认知。因留白而遐想。 1 留白效应的应用 1.1 留白效应在艺术领域的应用 欧洲的艺术和设计领域有很多经典的实际案例&#xff0c;其中荷兰画家文森特梵高的作品《星夜》是一幅非常著名的油画&am…