当前位置: 首页 > news >正文

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.lryc.cn/news/237369.html

相关文章:

  • JAXB:用XmlElement注解复杂类型的Java属性,来产生多层嵌套的xml元素
  • 万字长文 - Python 日志记录器logging 百科全书 - 高级配置之 日志分层
  • 工作记录---为什么双11当天不能申请退款?(有趣~)
  • ElasticSearch在Windows上的下载与安装
  • 软件测试/测试开发/人工智能丨基于Spark的分布式造数工具:加速大规模测试数据构建
  • ClickHouse的 MaterializeMySQL引擎
  • Ubuntu 22.04安装Rust编译环境并且测试
  • 制作Go程序的Docker容器(以及容器和主机的网络问题)
  • mysql清除数据痕迹_MySQL使用痕迹清理~/.mysql_history - milantgh
  • PDF控件Spire.PDF for .NET【转换】演示:自定义宽度、高度将 PDF 转 SVG
  • 01背包 P1507 NASA的食物计划
  • 平衡二叉树c语言版
  • 初始环境配置
  • 记GitLab服务器迁移后SSH访问无法生效的问题解决过程
  • 【NGINX--2】高性能负载均衡
  • Android studio run 手机或者模拟器安装失败,但是生成了debug.apk
  • 【面试经典150 | 数学】加一
  • Rust unix domain socket
  • 初识分布式键值对存储etcd
  • docker swarm集群部署
  • MySQL进阶_9.事务基础知识
  • IDEA调用接口超时,但Postman可成功调用接口
  • TableUtilCache:针对CSV表格进行的缓存
  • java源码-工程讲解
  • K8S基础笔记
  • 十一、统一网关GateWay(搭建网关、过滤器、跨越解决)
  • C语言--每日五道选择题--Day20
  • Fourier分析导论——第6章——R^d 上的Fourier变换(E.M. Stein R. Shakarchi)
  • 音视频技术在手机上的应用与挑战
  • 三十分钟学会SCALA