Flutter手势交互 ( 跟随手指运动的小球 )

Flutter 手势 - 跟随手指运动的小球

设置小球坐标变量 : 其中 currentX 是距离左侧边界的距离 , currentY 是距离右侧边界的距离 ;

  /// 当前小球的 x 坐标
  double currentX = 0;
  /// 当前小球的 y 坐标
  double currentY = 0;

小球的位置 : 小球是在 Stack 帧布局中的 Positioned 组件 , 其 lefttop 字段值设置其坐标 , 分别对应 currentXcurrentY 值 ;

// 小球
Positioned(
  /// 当前位置
  left: currentX,
  top: currentY,
)

监听事件 : 监听 GestureDetector 组件的 onPanUpdate 事件 , 其回调方法是 void Function(DragUpdateDetails details) 类型的 方法 , 可以从 DragUpdateDetails 类型参数中获取当前 x , y 的移动距离 , 该距离需要与之前的距离累加 , 才能得到准确的坐标值 ;

在回调方法中调用 setState 方法 , 修改成员变量 currentXcurrentY , 从而修改 Positioned 组件的位置 , 以达到小球移动的目的 ;

/// 手势检测组件
child: GestureDetector(
  /// 移动操作
  onPanUpdate: (e){
    setState(() {
      // e 中只能获取到 delta 值 , 需要逐步累加
      currentX += e.delta.dx;
      currentY += e.delta.dy;
    });
  },
)

代码示例 :

// 小球
Positioned(
  /// 当前位置
  left: currentX,
  top: currentY,
  /// 手势检测组件
  child: GestureDetector(
    /// 移动操作
    onPanUpdate: (e){
      setState(() {
        // e 中只能获取到 delta 值 , 需要逐步累加
        currentX += e.delta.dx;
        currentY += e.delta.dy;
      });
    },
    // 黑色小球
    child: Container(
      width: 40,
      height: 40,
      decoration: BoxDecoration(
        color: Colors.black,
        borderRadius: BorderRadius.circular(20),
      ),
    ),
  ),),
完整代码示例

完整代码示例 :

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

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

  @override
  _GesturePageState createState() => _GesturePageState();
}

class _GesturePageState extends State<GesturePage> {
  /// 当前小球的 x 坐标
  double currentX = 0;

  /// 当前小球的 y 坐标
  double currentY = 0;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // 设置主题
      theme: ThemeData(
        primarySwatch: Colors.amber,
      ),

      // 设置主体组件
      home: Scaffold(
        // 设置标题栏
        appBar: AppBar(
          title: const Text("手势检测"),

          // 返回按钮设置
          leading: GestureDetector(
            // 点击事件回调函数
            onTap: () {
              // 退出当前界面
              Navigator.pop(context);
            },

            // 回退按钮图标
            child: const Icon(Icons.arrow_back),
          ),
        ),

        // 水平/垂直方向平铺组件
        body: FractionallySizedBox(
          // 水平方向平铺
          widthFactor: 1,

          // 帧布局
          child: Stack(
            children: <Widget>[
              // 垂直方向线性布局
              Column(
                children: <Widget>[
                  // 手势检测组件
                  GestureDetector(
                    // 点击事件
                    onTap: () {
                      if (kDebugMode) {
                        print("双击");
                      }
                    },

                    // 双击事件
                    onDoubleTap: () {
                      if (kDebugMode) {
                        print("双击");
                      }
                    },

                    // 长按事件 , ()=>方法名(参数列表) 即可回调一个现有方法
                    onLongPress: () => _longPress(),

                    // 点击取消
                    onTapCancel: () {
                      if (kDebugMode) {
                        print("点击取消");
                      }
                    },

                    // 点击按下
                    onTapDown: (e) {
                      if (kDebugMode) {
                        print("点击按下");
                      }
                    },

                    // 点击抬起
                    onTapUp: (e) {
                      if (kDebugMode) {
                        print("点击抬起");
                      }
                    },

                    // 手势检测的作用组件 , 监听该组件上的各种手势
                    child: Container(
                      // 子组件居中
                      alignment: Alignment.center,

                      // 内边距
                      padding: const EdgeInsets.all(100),

                      // 背景装饰
                      decoration: const BoxDecoration(
                        color: Colors.green,
                      ),

                      child: const Text(
                        "手势检测",
                        style: TextStyle(
                          fontSize: 50,
                          color: Colors.red,
                        ),
                      ),
                    ),
                  )
                ],
              ),

              // 小球
              Positioned(
                /// 当前位置
                left: currentX,
                top: currentY,

                /// 手势检测组件
                child: GestureDetector(
                  /// 移动操作
                  onPanUpdate: (e) {
                    setState(() {
                      // e 中只能获取到 delta 值 , 需要逐步累加
                      currentX += e.delta.dx;
                      currentY += e.delta.dy;
                    });
                  },

                  // 黑色小球
                  child: Container(
                    width: 40,
                    height: 40,
                    decoration: BoxDecoration(
                      color: Colors.black,
                      borderRadius: BorderRadius.circular(20),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  /// 长按事件
  void _longPress() {
    if (kDebugMode) {
      print("长按");
    }
  }
}

运行效果 :

参考链接


【Flutter】Flutter 手势交互 ( 跟随手指运动的小球 )

发布者

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注