Flutter笔记:缩放手势

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.hqwc.cn/news/194438.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BatchNormalization:解决神经网络中的内部协变量偏移问题

ICML2015 截至目前51172引 论文链接 代码连接(planing) 文章提出的问题 减少神经网络隐藏层中的”内部协变量偏移”问题。 在机器学习领域存在“协变量偏移”问题,问题的前提是我们划分数据集的时候,训练集和测试集往往假设是独立同分布(i.i.d)的,这种独立同分布更有利于…

RabbitMQ消息的可靠性

RabbitMQ消息的可靠性 一 生产者的可靠性 生产者重试 有时候由于网络问题&#xff0c;会出现连接MQ失败的情况&#xff0c;可以配置重连机制 注意&#xff1a;SpringAMQP的重试机制是阻塞式的&#xff0c;重试等待的时候&#xff0c;当前线程会等待。 spring:rabbitmq:conne…

OSI参考模型

目录 一. OSI参考模型的各层功能二. 网络排错三. 网络安全四. 实体、协议、服务和服务访问点SAP五. TCP IP体系结构 一. OSI参考模型的各层功能 \quad \quad \quad \quad 我们首先来看应用层实现的功能 每个字段的各种取值所代表的意思 \quad \quad 比如要保存的文件内容是ab…

Linux 网络:PMTUD 简介

文章目录 1. 前言2. Path MTU Discovery(PMTUD) 协议2.1 PMTUD 发现最小 MTU 的过程 3. Linux 的 PMTUD 简析3.1 创建 socket 时初始化 PMTUD 模式3.2 数据发送时 PMTUD 相关处理3.2.1 源头主机发送过程中 PMTU 处理3.2.2 转发过程中 PMTUD 处理 4. PMTUD 观察5. 参考链接 1. 前…

配置VNC环境时,出现xauth: file /root/.Xauthority does not exist的解决方案。

问题描述 在配置VNC&#xff08;Virtual Network Computing&#xff09;环境的过程时&#xff0c;首先安装了tigervnc-server包。在使用&#xff1a; vncserver命令创建VNC会话号的时候出现了一个报错&#xff1a;xauth: file /root/.Xauthority does not exist 原因分析&…

【Linux进阶之路】动静态库

文章目录 回顾一. 静态库1.代码传递的方式2.简易制作3.原理 二. 动态库1.简易制作2.基本原理 尾序 回顾 前面在gcc与g的使用中&#xff0c;我们简单的介绍了动态库与静态库的各自的优点与区别&#xff1a; 动态链接库&#xff0c;也就是所有的程序公用一份代码,虽然方便省空间&…

SpringBoot 整合 JdbcTemplate

数据持久化有几个常见的方案&#xff0c;有 Spring 自带的 JdbcTemplate 、有 MyBatis&#xff0c;还有 JPA&#xff0c;在这些方案中&#xff0c;最简单的就是 Spring 自带的 JdbcTemplate 了&#xff0c;这个东西虽然没有 MyBatis 那么方便&#xff0c;但是比起最开始的 Jdbc…

Go——一、Go语言安装及介绍

Go 一、Windows下安装Go1、下载Go2、配置环境变量3、下载Jetbrain下的GoLang4、编写hello world5、编译和执行 二、Go语言介绍1、开发文档2、Go语言核心开发团队3、为什么要创建Go4、Go语言发展史5、Go语言特点6、Golang执行过程6.1 执行过程分析6.2 编译是什么 7、开发注意事项…

RobotFramework进阶之自定义的python模块(十四)

引言 RobotFramework自动化框架&#xff08;以下简称RF&#xff09;之前文章我们讲了通过import第三方的library&#xff08;RequestsLibrary等&#xff09;&#xff0c;在实际项目中第三方的包并不能满足我们的需要&#xff0c;此时我们可自己编写python模块&#xff08;.py文…

算法通关村第十六关白银挑战——滑动窗口高频问题

关注微信公众号&#xff1a;怒码少年。回复关键词【电子书】&#xff0c;领取多本计算机相关电子书 公众号后台开启了咨询业务&#xff0c;欢迎大家向我提问&#xff0c;免费&#xff0c;为爱发电&#x1f60e; 大家好&#xff0c;我是怒码少年小码。 武汉今天真的超级冷&…

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

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

volatile 无法保证原子性 案例展示

volatile 无法保证原子性 在 Java 中&#xff0c;原子性是指一个操作是不可中断的&#xff0c;要么都执行要么都不执行。 但是 volatile 修饰的变量&#xff0c;只是保证了从主内存加载到工作内存的值是最新的&#xff0c;并不能保证对变量的操作是原子性的 变量的写操作和读…