android 触摸监听重写_Flutter 触摸

这篇博客对比了Android和Flutter中触摸事件处理的区别,指出Flutter的GestureDetector使得处理触摸事件更加简洁。文章介绍了GestureDetector常用方法,包括监听单击、双击、长按,以及如何获取触摸数值。还提供了一个简单的使用示例和关于缩放的说明。
摘要由CSDN通过智能技术生成

b8b58a62402533ce0c10f00f07eaf83f.png

秦子帅 明确目标,每天进步一点点..... 4e0e6597798ad5d64eba633dfdaded58.png
作者 |  前行的乌龟 地址 |  juejin.im/post/5dcea24ff265da0bd05e5236

前言

Flutter 的触摸原理和 android 一样,但是再使用上有很大区别,Flutter 比 android 好用多了,android 里我们要写个类继承目标 view 重写 onTouchEvent 方法,这样我们会多写一个类,这个类只是重新定义了触摸事件的处理方法而已,其实得不偿失,还会造成类爆炸,不方便理解的问题

Flutter 中一切都是 Widget,触摸事件也是一个 Widget:GestureDetector,我们只要用 GestureDetector 包裹内容 Widget 就行了,不需要我们单独搞一个类出来,方便阅读,方便理解,也方便编写,是编程语言发展的趋势

GestureDetector方法大全

GestureDetector 的构造函数中有很多方法,我们用不上,只用那么常用的就行,下面的这样监听函数大家看一下就行了

class GestureDetector extends StatelessWidget {
  GestureDetector({
    Key key,this.child,this.onTapDown,this.onTapUp,this.onTap,this.onTapCancel,this.onDoubleTap,this.onLongPress,this.onLongPressUp,this.onLongPressDragStart,this.onLongPressDragUpdate,this.onLongPressDragUp,this.onVerticalDragDown,this.onVerticalDragStart,this.onVerticalDragUpdate,this.onVerticalDragEnd,this.onVerticalDragCancel,this.onHorizontalDragDown,this.onHorizontalDragStart,this.onHorizontalDragUpdate,this.onHorizontalDragEnd,this.onHorizontalDragCancel,this.onForcePressStart,this.onForcePressPeak,this.onForcePressUpdate,this.onForcePressEnd,this.onPanDown,this.onPanStart,this.onPanUpdate,this.onPanEnd,this.onPanCancel,this.onScaleStart,this.onScaleUpdate,this.onScaleEnd,this.behavior,this.excludeFromSemantics = false,this.dragStartBehavior = DragStartBehavior.down,
  })
  ...
}

监听单击,双击,长按

这是最常用的触摸处理了:

  • onTap - 单击
  • onDoubleTap - 双击
  • onLongPress - 长按
注意:  像是  双击,长按  这样的处理不可能像  单击  那样立马就响应的,而是有 200ms 的延迟,因为要在 200ms 内判断您是不是一直按着或者又按了一下
Widget build(BuildContext context) {return RaisedButton(child: Center(child: GestureDetector(child: Container(alignment: Alignment.center,color: Colors.blue,width: 200.0,height: 100.0,child: Text(
              value,style: TextStyle(color: Colors.white),
            ),
          ),onTap: () => print("点击"), //点击onDoubleTap: () => print("双击"), //双击onLongPress: () => print("长安"), //长按
        ),
      ),
    );
  }

获取触摸数值

上面的监听方法是用来处理一般事件的,下面的方法我们可以直接拿到数值,并且 Flutter 初步给我们整理好了,划分了数值类型
  • onPanDown - 用户按下时触发,数据类型:DragDownDetails.globalPosition 是触摸点相对于屏幕的坐标,看名字有 global 就知道了
onPanDown: (DragDownDetails e) {// 手指按下的位置(相对于屏幕)print("用户手指按下:${e.globalPosition}");
},
  • onPanUpdate - 用户在屏幕上滑动时触发,数据类型:DragUpdateDetails.delta 其数值是用户一次触摸的偏移量,注意不是总的偏移量,是每一次的
onPanUpdate: (DragUpdateDetails e) {
  //用户手指滑动时,更新偏移,重新构建print("单次偏移量:${e.delta.dx} :${e.delta.dy} ");
},
  • onPanEnd - 户抬起手指时触发,数据类型:DragEndDetails.velocity.pixelsPerSecond 其数据是用户手离开时 view 残留的滑动速度(包含x、y两个轴的)
onPanEnd: (DragEndDetails e){//打印滑动结束时在x、y轴上的速度print(e.velocity.pixelsPerSecond.dx,e.velocity.pixelsPerSecond.dy);
},
  • onVerticalDragUpdate - 垂直方面上手指触摸的变化值,数据类型:DragUpdateDetails
onVerticalDragUpdate: (DragUpdateDetails e){
  ......
},
  • onHorizontalDragUpdate - 水平方面上手指触摸的变化值,数据类型:DragUpdateDetails
onHorizontalDragUpdate: (DragUpdateDetails e){
  ......
},

第一个例子

这里我们搞一个拖动 widget 的小 demo 0bc50e8ba0eb9fc893c6da57364a4210.gif
class TestWidgetState extends State<TestWidget> {
  num top = 0.0;
  num left = 0.0;@overrideWidget build(BuildContext context) {return Stack(
      children: [
        Positioned(
          top: top,
          left: left,
          child: GestureDetector(
            child: Container(
              alignment: Alignment.center,
              color: Colors.blue,
              width: 100.0,
              height: 100.0,
              child: Text("AAAAAAAA",
                style: TextStyle(color: Colors.white),
              ),
            ),
            onPanUpdate: (DragUpdateDetails e) {
              setState(() {
                left += e.delta.dx;
                top += e.delta.dy;
              });
            },
          ),
        ),
      ],
    );
  }
}
废话不多说,我们使用 stack 这个布局来做,利用 top,left 定位来改变 widget 的位置。

缩放

  • onScaleUpdate - 数据类型:ScaleUpdateDetails,缩放值是:details.scale.clamp,clamp 方法中的参数是缩放范围,实测貌似不管用,不知道是不是我这的原因
onScaleUpdate: (ScaleUpdateDetails details) {
  setState(() {//缩放倍数在0.8到10倍之间
    _width=200*details.scale.clamp(.8, 10.0);
});
我是不知道打击缩放都是怎么做的,我自己跑了个例子,我写的这个那手感是烂的一B啊 2fb179a9e0539a2d7e9792ea9b2f0447.gif
class TestWidgetState extends State<TestWidget> {var width = 150.0;var height = 150.0;
  @override
  Widget build(BuildContext context) {return Center(
      child: (GestureDetector(
        child: Container(
          alignment: Alignment.center,
          color: Colors.blue,
          width: width,
          height: height,
          child: Text("AAAAAAAA",
            style: TextStyle(color: Colors.white),
          ),
        ),
        onScaleUpdate: (ScaleUpdateDetails details) {
          setState(() {if ((width *= details.scale.clamp(0.5, 1.5)) > 300) width = 200;if ((width *= details.scale.clamp(0.5, 1.5)) < 50) width = 100;if ((height *= details.scale.clamp(0.5, 1.5)) > 300) height = 200;if ((height *= details.scale.clamp(0.5, 1.5)) < 50) height = 100;print("scale: ${details.scale.clamp}");
          });
        },
      )),
    );
  }
后来想了想手感烂应该是我没加系数进去,我试了下,加入了系数,系数=0.1,但是感觉还是没啥用... ---END--- 1335d4ef66454d23805c4637259ddb69.png afe518a9030af009ec0b739a078c20ac.png 你点的每个好看,我都认真当成了喜欢
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值