Flutter实现手势识别功能详解方法

 更新时间:2022年11月17日 11:46:44   作者:@我不认识你  
在Flutter中使用GestureDetector可以来完成对手势的识别,包括长按、滑动、双击等手势,这篇文章主要介绍了Flutter实现手势识别功能

GestureDetector

GestureDetector 是手势识别的组件,可以识别点击、双击、长按事件、拖动、缩放等手势

点击事件

点击相关事件包括:

  • onTapDown:按下时回调。
  • onTapUp:抬起时回调。
  • onTap:点击事件回调。
  • onTapCancel:点击取消事件回调。

按下然后抬起调用顺序

onTapDown-> onTapUp-> onTap

按下后移动调用顺序

onTapDown-> onTapCancel

示例

class _YcHomeBodyState extends State<YcHomeBody> {
  String desc = '';
  Color containerColor = Colors.red;
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      child: Column(
        children: [
          Container(
            width: 420,
            height: 330,
            color: containerColor,
          ),
          const SizedBox(
            width: 100,
            height: 20,
          ),
          Text("点击事件:$desc")
        ],
      ),
      onTapDown: (TapDownDetails tapDownDetails) {
        setState(() {
          desc += '按下,';
          containerColor = Colors.blue;
        });
      },
      onTapUp: (TapUpDetails tapUpDetails) {
        setState(() {
          desc += '抬起,';
          containerColor = Colors.red;
        });
      },
      onTap: () {
        setState(() {
          desc += '点击,';
          containerColor = Colors.yellow;
        });
      },
      onTapCancel: () {
        setState(() {
          desc += '取消,';
          containerColor = Colors.pink;
        });
      },
    );
  }
}

双击事件

双击是快速且连续2次在同一个位置点击,双击监听使用onDoubleTap方法

return GestureDetector(
  child: Column(
    children: [
      Container(
        width: 420,
        height: 330,
        color: containerColor,
      ),
      const SizedBox(
        width: 100,
        height: 20,
      ),
      Text("点击事件:$desc")
    ],
  ),
  onDoubleTap: () {
    setState(() {
      desc = '双击了';
    });
  },

长按事件

长按事件(LongPress)包含长按开始、移动、抬起、结束事件,说明如下:

  • onLongPressStart:长按开始事件回调。
  • onLongPressMoveUpdate:长按移动事件回调。
  • onLongPressUp:长按抬起事件回调。
  • onLongPressEnd:长按结束事件回调。
  • onLongPress:长按事件回调。

示例

return GestureDetector(
  child: Column(
    children: [
      Container(
        width: 420,
        height: 330,
        color: containerColor,
      ),
      const SizedBox(
        width: 100,
        height: 20,
      ),
      Text("点击事件:$desc")
    ],
  ),
  onLongPressStart: (v) {
    setState(() {
      desc += '长按开始,';
      print("长按开始:$v");
    });
  },
  onLongPressMoveUpdate: (v) {
    setState(() {
      desc += '长按移动,';
      print("长按移动:$v");
    });
  },
  onLongPressUp: () {
    setState(() {
      desc += '长按抬起,';
      print("长按抬起");
    });
  },
  onLongPressEnd: (v) {
    setState(() {
      desc += '长按结束,';
      print("长按结束:$v");
    });
  },
  onLongPress: () {
    setState(() {
      desc += '长按回调,';
      print("长按回调");
    });
  });

执行顺序

1、长按开始->回调->结束->抬起
2、长按开始->回调->移动->结束->抬起

水平/垂直拖动事件

垂直/水平拖动事件包括按下、开始、移动更新、结束、取消事件,以垂直为例说明如下:

  • onVerticalDragDown:垂直拖动按下事件回调
  • onVerticalDragStart:垂直拖动开始事件回调
  • onVerticalDragUpdate:指针移动更新事件回调
  • onVerticalDragEnd:垂直拖动结束事件回调
  • onVerticalDragCancel:垂直拖动取消事件回调
GestureDetector(
  onVerticalDragStart: (v) => print('onVerticalDragStart'),
  onVerticalDragDown: (v) => print('onVerticalDragDown'),
  onVerticalDragUpdate: (v) => print('onVerticalDragUpdate'),
  onVerticalDragCancel: () => print('onVerticalDragCancel'),
  onVerticalDragEnd: (v) => print('onVerticalDragEnd'),
  child: Center(
    child: Container(
      width: 200,
      height: 200,
      color: Colors.red,
    ),
  ),
)

缩放事件

缩放(Scale)包含缩放开始、更新、结束。说明如下:

  • onScaleStart:缩放开始事件回调。
  • onScaleUpdate:缩放更新事件回调。
  • onScaleEnd:缩放结束事件回调。
GestureDetector(
  onScaleStart: (v) => print('onScaleStart'),
  onScaleUpdate: (ScaleUpdateDetails v) => print('onScaleUpdate'),
  onScaleEnd: (v) => print('onScaleEnd'),
  child: Center(
    child: Container(
      width: 200,
      height: 200,
      color: Colors.red,
    ),
  ),
)

InkWell

InkWell 组件在用户点击时出现“水波纹”效果。事件和属性挺多的,就看一下常用的

设置水波纹颜色

点击和长按都能够触发水波纹,点击波纹效果快,长按波纹效果慢

 return  InkWell(
      onTap: (){
        print("点击了");
      },
      splashColor: Colors.red,
      child: const Text('点击InkWell,水波纹'),
    );

给字体添加边距和圆角边框,扩大“水波纹”效果:

Center(
      child: InkWell(
          onTap: () {
            print("点击了");
          },
          splashColor: Colors.red,
          child: Container(
              padding: const EdgeInsets.all(10),
              decoration: BoxDecoration(
                  border: Border.all(color: Colors.red),
                  borderRadius: const BorderRadius.all(Radius.circular(20))),
              child: const Text('点击InkWell,水波纹'))),
    );

可以看到水波纹会超出圆角,为了解决这个问题可以使用Ink

Ink

Ink控件用于在[Material]控件上绘制图像和其他装饰,以便[InkWell]、[InkResponse]控件的“水波纹”效果在其上面显示。

  return Center(
        child: Ink(
      decoration: const BoxDecoration(
          gradient: LinearGradient(
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
              colors: [Color(0xFFDE2F21), Color(0xFFEC592F)]),
          borderRadius: BorderRadius.all(Radius.circular(20))),
      child: InkWell(
        borderRadius: const BorderRadius.all(Radius.circular(20)),
        child: Container(
          padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 20),
          child: const Text(
            '这是InkWell的点击效果',
            style: TextStyle(color: Colors.white),
          ),
        ),
        onTap: () {},
      ),
    ));
  }

总感觉有点复杂,InkWell 会导致水纹超出边框,就需要外面再套一层组件,然后还要写个渐变,不知道咋形容。

Listener

Listener 是一个监听指针事件的控件,比如按下、移动、释放、取消等指针事件,但Listener无法监听鼠标特有的事件,比如:移入、悬停、移出事件。鼠标事件使用MouseRegion监听。

通常情况下,监听手势事件使用GestureDetector,GestureDetector是更高级的手势事件。

Listener的事件介绍如下:

  • onPointerDown:按下时回调
  • onPointerMove:移动时回调
  • onPointerUp:抬起时回调
Listener(
  onPointerDown: (PointerDownEvent pointerDownEvent) {
    print('$pointerDownEvent');
  },
  onPointerMove: (PointerMoveEvent pointerMoveEvent) {
    print('$pointerMoveEvent');
  },
  onPointerUp: (PointerUpEvent upEvent) {
    print('$upEvent');
  },
  child: Container(
    height: 200,
    width: 200,
    color: Colors.blue,
    alignment: Alignment.center,
  ),
)

常用属性说明如下:

position:相对屏幕的坐标的偏移。

localPosition:相对当前控件的偏移。

pressure:按压力度。

delta:2次指针移动事件的偏移。

orientation:指针移动方向

案例

进度按钮

// 使用枚举定义按钮的状态
enum ButtonStates { none, loading, done }
class YcHomeBody extends StatefulWidget {
  const YcHomeBody({Key? key}) : super(key: key);
  @override
  State<YcHomeBody> createState() => _YcHomeBodyState();
}
class _YcHomeBodyState extends State<YcHomeBody> {
  //定义按钮的状态
  ButtonStates _buttonStates = ButtonStates.none;
  @override
  Widget build(BuildContext context) {
    return Center(
      child: MaterialButton(
        color: Colors.blue,
        textColor: Colors.white,
        minWidth: 200,
        height: 40,
        //通过自定义方法,根据情况返回相应的组件
        child: _build(),
        onPressed: () {
          //点击按钮后将按钮状态变为加载中
          setState(() {
            _buttonStates = ButtonStates.loading;
            //延迟2s后将状态变为完成
            Future.delayed(const Duration(seconds: 2), () {
              setState(() {
                _buttonStates = ButtonStates.done;
              });
            });
          });
        },
      ),
    );
  }
  //自定义方法
  _build() {
    if (_buttonStates == ButtonStates.none) {
      //无状态
      return const Text("登录");
    } else if (_buttonStates == ButtonStates.loading) {
      //进度条组件
      return const CircularProgressIndicator(
        backgroundColor: Colors.white,
        strokeWidth: 2,
      );
    } else if (_buttonStates == ButtonStates.done) {
      return const Icon(
        Icons.check,
        color: Colors.white,
      );
    }
  }
}

代码看着很长但是逻辑很简单,定义了一个枚举类型的按钮类型。一开始类型为无状态,此时显示登录;当点击按钮后,状态变为加载中,显示圆形进度条组件;2s后将按钮状态变为加载完成,现成完成的图标

到此这篇关于Flutter实现手势识别功能详解方法的文章就介绍到这了,更多相关Flutter手势识别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • ANDROID应用程序的混淆打包分享

    ANDROID应用程序的混淆打包分享

    这篇文章主要介绍了ANDROID应用程序的混淆打包,有需要的朋友可以参考一下
    2014-01-01
  • Android基于OkHttpUtils网络请求的二次封装

    Android基于OkHttpUtils网络请求的二次封装

    这篇文章主要介绍了Android基于OkHttpUtils网络请求的二次封装,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03
  • Flutter实现自定义搜索框AppBar的示例代码

    Flutter实现自定义搜索框AppBar的示例代码

    开发中,页面头部为搜索样式的设计非常常见,为了可以像系统AppBar那样使用,本文将利用Flutter自定义一个搜索框,感兴趣的可以了解一下
    2022-04-04
  • Android实现自动填充短信验证码功能

    Android实现自动填充短信验证码功能

    这篇文章主要为大家详细介绍了Android实现自动填充短信验证码功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • Android使用相机实现拍照存储及展示功能详解

    Android使用相机实现拍照存储及展示功能详解

    这篇文章主要介绍了Android使用相机实现拍照存储及展示功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-01-01
  • Android中EditText显示明文与密码的两种方式

    Android中EditText显示明文与密码的两种方式

    这篇文章主要介绍了Android中EditText显示明文与密码的两种方式,非常不错,具有参考借鉴价值,需要的盆友一起学习吧
    2016-08-08
  • Android从相册选择图片剪切和上传

    Android从相册选择图片剪切和上传

    这篇文章主要为大家详细介绍了Android从相册选择一个图片剪切、上传的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-02-02
  • Android 中的 Runtime详解

    Android 中的 Runtime详解

    Runtime 是 Android 系统中的核心组件之一,它提供了执行应用程序代码的环境,并影响着应用程序的性能和响应性能,这篇文章主要介绍了Android 中的 Runtime,需要的朋友可以参考下
    2024-01-01
  • Android 属性动画原理与DataBinding

    Android 属性动画原理与DataBinding

    这篇文章主要介绍了Android 属性动画原理与DataBinding的相关资料,需要的朋友可以参考下
    2017-04-04
  • Android Binder 通信原理图文详解

    Android Binder 通信原理图文详解

    这篇文章主要为大家介绍了Android Binder 通信原理图文详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10

最新评论