Flutter事件处理

Posted flutter开发者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter事件处理相关的知识,希望对你有一定的参考价值。

在前面的文章中我们我们学习了StatefulWidget有状态组件的用法,并且让大家试一试官方Demo中,点击FloatActionButton使文字字数增加的同时,增大字体的大小。


这个的做法很简单,就是通过TextStyle把计数器的值赋值给Text文本就行了,但是要注意的时,最好给TextSize的大小写一个最小值,如从10.0开始(10.0+_counter)。由于很简单,就不在给大家贴代码了。


在上篇文章中,我们还给大家介绍了FloatActionButton的onPressed参数,需要传入一个没有参数没有返回值的方法,这其实就是FloatActionButton点击事件的处理。

那么这篇文章我们就来看下Flutter中事件的处理

引言


在Flutter中的手势事件分为两层,第一层有原始指针事件,它描述了屏幕上指针(例如,触摸,鼠标和触控笔)的位置和移动。第二层有手势,描述由一个或多个指针移动组成的语义动作。

虽然指针在我们开发中不常用到,但是我们还是会分别对指针很手势进行介绍

指针Pointers


指针代表关于用户与设备屏幕交互的原始数据。

有四种类型的指针事件:

  • PointerDownEvent 指针已经联系了特定位置的屏幕。

  • PointerMoveEvent 指针已经从屏幕上的一个位置移动到另一个位置。

  • PointerUpEvent 指针停止接触屏幕。

  • PointerCancelEvent 来自此指针的输入不再针对此应用。


在指针向下时,框架对您的应用程序执行命中测试,以确定指针与屏幕相接的位置存在哪些小部件。指针向下事件(以及该指针的后续事件)然后被分派到由命中测试发现的最内部的小部件。


从那里开始,这些事件会冒泡到树中(事件分发),并被分派到从最内部的小部件到树根的路径上的所有小部件。没有任何机制可以取消或停止进一步调度指针事件。


由于指针不能直接用于控件的监听,所以我们在开发中一般使用Gesture来监听用户的各种事件。

手势Gestures


手势表示可以从多个单独的指针事件识别的语义动作(例如,轻敲,拖动和缩放),甚至可能是多个单独的指针。手势可以分派多个事件,对应于手势的生命周期(例如,拖动开始,拖动更新和拖动结束):


单击

  • onTapDown 可能导致水龙头的指针已经在特定位置与屏幕接触。

  • onTapUp 将触发水龙头的指针已停止在特定位置与屏幕接触。

  • onTap 出现了水龙头。

  • onTapCancel先前触发的指针onTapDown不会导致敲击。

双击

  • onDoubleTap 用户快速连续两次在同一位置轻敲屏幕。

长按

  • onLongPress 指针在相同位置长时间保持与屏幕接触。

垂直拖动

  • onVerticalDragStart 指针已经与屏幕联系并可能开始垂直移动。

  • onVerticalDragUpdate 与屏幕接触并垂直移动的指针已沿垂直方向移动。

  • onVerticalDragEnd 先前与屏幕接触并垂直移动的指针不再与屏幕接触,并且在停止接触屏幕时以特定速度移动。

水平拖拽

  • onHorizontalDragStart 指针已经与屏幕联系并可能开始水平移动。

  • onHorizontalDragUpdate 与屏幕接触并水平移动的指针已沿水平方向移动。

  • onHorizontalDragEnd 先前与屏幕接触并水平移动的指针不再与屏幕接触,并且在停止接触屏幕时以特定速度移动。


要让Gesture可以监听Widget的各种事件需要使用GestureDetector来处理这些事件。

我们来看下GestureDetector的构造方法:


GestureDetector({
 Key key,
 
this.child,
 
this.onTapDown,
 
this.onTapUp,
 
this.onTap,
 
this.onTapCancel,
 
this.onDoubleTap,
 
this.onLongPress,
 
this.onVerticalDragDown,
 
this.onVerticalDragStart,
 
this.onVerticalDragUpdate,
 
this.onVerticalDragEnd,
 
this.onVerticalDragCancel,
 
this.onHorizontalDragDown,
 
this.onHorizontalDragStart,
 
this.onHorizontalDragUpdate,
 
this.onHorizontalDragEnd,
 
this.onHorizontalDragCancel,
 
this.onPanDown,
 
this.onPanStart,
 
this.onPanUpdate,
 
this.onPanEnd,
 
this.onPanCancel,
 
this.onScaleStart,
 
this.onScaleUpdate,
 
this.onScaleEnd,
 
this.behavior,
 
this.excludeFromSemantics: false
})

GestureDetector有很多的参数,但是基本上每个参数都是对应一个事件,大家可以根据自己的需要来选择相应的事件来做监听处理。

好吧,还是来举个例子

import 'package:flutter/material.dart';

void main() {
runApp(new MaterialApp(home: new MyApp()));
}

class MyApp extends StatelessWidget {
 @override
 
Widget build(BuildContext context) {

   return new Scaffold(
     appBar: new AppBar(
       title: new Text("Gestures"),
     
),
     
body: new Center(
         child: new GestureDetector(
           child: new Icon(
             Icons.android,
             
size: 200.0,
           
),
           
onTap: () {
             print("onTap");
           
},
           
onDoubleTap: () {
             print("onDoubleTap");
           
},
           
onLongPress: () {
             print("onLongPress");
           
},
           
onVerticalDragStart: (details){
             print("在垂直方向开始位置:"+details.globalPosition.toString());
           
}, onVerticalDragEnd: (details){
           print("在垂直方向结束位置:"+details.primaryVelocity.toString());
         
},
         
)),
   
);
 
}
}

我们在屏幕的正中心放了一个icon,icon外面被GestureDetector包围着,记录在屏幕上的点击。双击、长按和滑动事件并把事件信息打印出来。

备注:在Flutter使用 print可以在flutter控制台输出信息

控制台输出:

I/flutter (20568): onTap
I/flutter (20568): onDoubleTap
I/flutter (20568): onLongPress
I/flutter (20568): 在垂直方向开始位置:Offset(154.0, 367.3)
I/flutter (20568): 在垂直方向结束位置:-366.4189656255261
I/flutter (20568): 在垂直方向开始位置:Offset(148.0, 290.3)
I/flutter (20568): 在垂直方向结束位置:619.5150358985436


  • 当我们单击屏幕是,日志便会打印onTap

  • 当我们双击屏幕时,日志便会打印onDoubleTap,同时屏蔽点击事件

  • 当我们长按屏幕时,日志便会打印onLongPress,同时屏蔽单击事件

  • 当我们在屏幕滑动时,会打印屏幕上的滑动事件,同时屏蔽Tap事件


在前面的文章中我们已经说,没有返回值和参数的函数可以直接使用函数名调用,这样我们就可以把触摸事件抽离出去做自己的处理。


事件冲突处理


正常情况下,我们仅仅会在一个方向上操作界面,但是是也不排除用户在横向和竖向操作界面(或者是多个手势),这样一来屏幕就会给底层发来多个手势识别器,这样一样就会存在手势的冲突。

  • 如果两个手势都在操作,最后剩下的识别器会享有事件的处理权

  • 如果横竖两个识别器同时存在,最先划出屏幕的识别器享有事件处理权

上述两个是Flutter中事件冲突时获取滑动事件的规则。



小结:


  • Gestures的GestureDetector负责Flutter中的事件处理

  • 在Flutter中开发者可以监听并处理单击、双击、长按、和托拽事件

  • 开发者可以根据自己的需要去避免或处理滑动冲突


当然,有什么问题也欢迎大家在后台留言,我会在看到的第一时间回复大家的




以上是关于Flutter事件处理的主要内容,如果未能解决你的问题,请参考以下文章

Flutter视频编辑轨道 | 自定义View实现UI交互效果 | 触摸事件处理

Flutter视频编辑轨道 | 自定义View实现UI交互效果 | 触摸事件处理

将数据从片段发送到活动,无需任何事件处理或侦听器

错误记录Flutter 混合开发获取 BinaryMessenger 报错 ( FlutterActivityAndFragmentDelegate.getFlutterEngine() )(代码片段

Flutter事件分发源码剖析

在 webview_flutter 中启用捏合和缩放,在哪里添加代码片段 [this.webView.getSettings().setBuiltInZoomControls(true);]