• 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),
          ),
        );
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    上面的代码中,我们使用 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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    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, // 确定在所有涉及此手势的计算中,用作起点的点
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5

    其中:

    • 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('缩放结束');
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    在这里插入图片描述

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

  • 相关阅读:
    vm2 组件存在沙箱逃逸漏洞
    开源实时数仓 Apache Doris 毕业了,未来如何走得更远?
    java基本web蓝桥杯名师工作室计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
    Linux中source命令的用法
    GET,POST,DELETE,PUT参数传递的形式
    【微服务】Day03
    Solana链,什么是sol跟单机器人、pump跟单机器人、sol狙击机器人、sol夹子机器人、sol聪明钱筛选
    控制一个游戏对象的旋转和相机的缩放
    【实践成果】Splunk 9.0 Configuration Change Tracking
    Excel 多条件筛选 与 数据透视表 实现
  • 原文地址:https://blog.csdn.net/qq_28550263/article/details/134485138