Flutter(十三)——事件处理:手势识别与事件通知

简介: Flutter(十三)——事件处理:手势识别与事件通知

前言


Flutter开发App的过程中,我们除了需要灵活的使用各种组件之外,还需要掌握手势的识别,比如我们常常需要在操作App的时候使用到缩放,双击,放大,缩小等操作,这些Flutter都给我们提供了监听的组件GestureDetector。这篇博文将详细介绍GestureDetector手势识别的使用规则。(拖动手势监听)


GestureDetector基本用法


我们前面提到过,在Flutter开发中,一切皆是组件,所以GestureDetector同样是一个组件,我们使用它,通常是作为一个父Widget包裹一个子Widget外面(也就是你需要捕捉那个组件的手势,就把GestureDetector套在外外面),而内部我们通过onTap回调来实现其点击的效果,代码如下:

GGestureDetector(
  onTap:(){
  print("tap");
  },
  child:Container{
  padding:EdgeInsets.all(20),
  decoration:BoxDecoration(
    color:Theme.of(context).buttonColor,
    borderRadius:BorderRadius.circular(8.0),
  ),
  child:new Text("文本"),
  }
);


比如上面的代码就是改造Text组件成为按钮的方式,这里捕捉了点击事件。


常用事件


GestureDetector手势识别不仅仅只有onTap事件,还有很多很多的常用事件,博主通过一张表格将它们全部列举了出来,方便大家查阅:

属性 取值意义

onTapDwon

当按下屏幕时触发
onTap 当与屏幕短暂地触碰时触发,最常用
onTapUp 当用户停止触碰屏幕时触发
onTapCancel 当用户触摸屏幕,但没有完成Tap事件时触发
onDoubleTap 快速双击屏幕时触发
onLongPress 当长按屏幕时触发(与屏幕接触事件必须超过500ms)
onPanUpdate 当在屏幕上移动时触发
onVerticalDragDown 当手指触碰屏幕且准备往屏幕垂直方向移动时触发
onVerticalDragStart 当手指触碰屏幕且开始往屏幕垂直方向移动时触发
onVerticalDragUpdate 当手指触碰屏幕且开始往屏幕垂直方向移动并发生位移时触发
onVerticalDragEnd 当用户完成垂直方向触摸屏幕时触发
onVerticalDragCancel 当用户中断了onVerticalDragDown时触发
onHorizontalDragDown 当手指触摸屏幕且准备往屏幕水平方向移动时触发
onHorizontalDragStart 当手指触摸屏幕且开始往屏幕水平方向移动时触发
onHorizontalDragUpdate 当手指触摸屏幕且开始往屏幕水平方向移动并发生位移时触发
onHorizontalDragEnd 当用户完成水平方向触摸屏幕时触发
onHorizontalDragCancel 当用户中断了onHorizontalDragDown时触发
onPanDown 当用户触摸屏幕时触发
onPanStart 当用户触摸屏幕并开始移动时触发
onPanUpdate 当用户触摸屏幕并产生移动时触发
onPanEnd 当用户完成触摸屏幕时触发
onScaleStart 当用户触摸屏幕并开始缩放时触发
onScaleUpdate 当用户触摸屏幕并产生缩放时触发
onScaleEnd 当用户完成缩放时触发

虽然说上面表格非常详细,但其中有些事件是互斥的,并不能同时存在,比如onVerticalUpdate,onHorizontalUpdate,onPanUpdate这些三个事件都不能同时存在,否则会报错。


另外,onPanUpdate和onScaleUpdate也不能同时存在,这是因为在Gesture识别器里,Scale操作是Pan操作的超集。


监听事件实现缩放


既然我们了解了如何使用这些事件,那么,我们就应该实践起来,这里小编将用上面的事件实现一个缩放效果,代码如下:

class _MyHomePageState extends State<MyHomePage>{
  double _top=0.0;
  double _left=0.0;
  double _size=100.0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: new Text("忽略事件"),),
      body: Stack(
        children: <Widget>[
          Positioned(
            top: this._top,
            left: this._left,
            child: GestureDetector(
              child: FlutterLogo(
                size: this._size,
              ),
              onScaleUpdate: (e){
                setState(() {
                  this._size=300*e.scale.clamp(.5, 10.0);缩放倍数在0.5到10倍之间
                });
              },
            ),
          ),
        ],
      ),
    );
  }
}


代码非常的简单,就是缩放FlutterLogo的大小,实现的效果如下图所示:


监听事件实现拖拽


既然我们已经了解这么多事件,不妨多来一个事件,也就是App中常用的拖拽操作,代码如下(略微改改上上面的代码就行):

class _MyHomePageState extends State<MyHomePage>{
  double _top=0.0;
  double _left=0.0;
  double _size=100.0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: new Text("忽略事件"),),
      body: Stack(
        children: <Widget>[
          Positioned(
            top: this._top,
            left: this._left,
            child: GestureDetector(
              child: FlutterLogo(
                size: this._size,
              ),
              onPanUpdate: (e){
                setState(() {
                  this._left+=e.delta.dx;
                  this._top+=e.delta.dy;
                });
              },
            ),
          ),
        ],
      ),
    );
  }
}


仅仅改变了事件的代码,前面说过onPanUpdate与onScaleUpdate不能同时存在,所以不能直接添加事件,需要删除onScaleUpdate后在添加。


事件通知


Notification是“通知”的意思,这和Android中不一样。在Flutter里,Notification会沿着当前的context节点从下往上传递,所有父节点都可以通过NotificationListener来监听通知,这种由子向父的传递方式,我们称为“通知冒泡”,并继承至Notification,而父Widget使用NotificationListener进行监听并捕获通知。常用的NotificatioListener有LayoutChangeNotification,SizeChangedLayoutNotifier,ScrollNotification等。比如本篇将监听ListView滚动状态:是通过NotificationListener里的onNotification回调方法来判断状态。代码如下:

class _MyHomePageState extends State<MyHomePage> {
  String _message = "我是通知";
  void _onScrollStart(ScrollMetrics scrollMetrics){
    print(scrollMetrics.pixels);
    setState(() {
      this._message="滚动开始";
    });
  }
  void _onScrollEnd(ScrollMetrics scrollMetrics){
    print(scrollMetrics.pixels);
    setState(() {
      this._message="滚动结束";
    });
  }
  void _onScrollUpdate(ScrollMetrics scrollMetrics){
    print(scrollMetrics.pixels);
    setState(() {
      this._message="滚动进行时";
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: new Text("事件通知"),
      ),
      body: Column(
        children: <Widget>[
          Container(
            height: 50.0,
            color: Colors.green,
            child: Center(
              child: new Text(this._message),
            ),
          ),
          Expanded(
            child: NotificationListener<ScrollNotification>(
              // ignore: missing_return
              onNotification: (scrollNotification) {
                if (scrollNotification is ScrollStartNotification) {
                  this._onScrollStart(scrollNotification.metrics);
                } else if (scrollNotification is ScrollUpdateNotification) {
                  this._onScrollUpdate(scrollNotification.metrics);
                } else if (scrollNotification is ScrollEndNotification) {
                  this._onScrollEnd(scrollNotification.metrics);
                }
              },
              child: ListView.builder(
                  itemCount: 30,
                  itemBuilder: (context, index) {
                    return ListTile(title: Text("索引:$index"),);
                  }),
            ),
          ),
        ],
      ),
    );
  }
}


实现效果如下图所示,代码很好理解,这里就不在赘述了:

相关文章
|
4天前
|
传感器 Android开发 iOS开发
Flutter插件开发指南02: 事件订阅 EventChannel
上一节我们讲了 Channel 通道,但是如果你是卫星定位业务,原生端主动推消息给 Flutter 这时候就要用到 EventChannel 通道了。 本节会写一个 1~50 的计数器,到 50 后自动关闭原生的消息订阅。
Flutter插件开发指南02:  事件订阅 EventChannel
|
4天前
|
前端开发 开发者 UED
【Flutter前端技术开发专栏】Flutter中的手势识别与触摸事件处理
【4月更文挑战第30天】本文探讨了Flutter中的手势识别和触摸事件处理,关键点包括: 1. 使用`GestureRecognizer`类体系实现手势识别,如`TapGestureRecognizer`检测点击,`HorizontalDragGestureRecognizer`和`VerticalDragGestureRecognizer`识别滑动,`ScaleGestureRecognizer`识别捏合和扩张。
【Flutter前端技术开发专栏】Flutter中的手势识别与触摸事件处理
|
11月前
|
容器
Flutter的手势识别功能实现GestureDetector
Flutter的手势识别功能实现GestureDetector
|
Dart JavaScript
Flutter | 事件处理(下)
Flutter | 事件处理(下)
Flutter | 事件处理(下)
|
API 容器
Flutter | 事件处理(上)
Flutter | 事件处理(上)
Flutter | 事件处理(上)
flutter事件evevt详解
在Flutter中,手势有两个不同的层次: 第一层:原始指针事件(Pointer Events):描述了屏幕上由触摸板、鼠标、指示笔等触发的指针的位置和移动。 第二层:手势识别(Gesture Detector):这个是在原始事件上的一种封装。
152 0
Flutter中焦点FocusNode使用分析Flutter输入框焦点事件的捕捉与监听
在Flutter使用FocusNode来捕捉监听TextField的焦点获取与失去,同时也可通过FocusNode来使用绑定对应的TextField获取焦点与失去焦点。
Flutter中焦点FocusNode使用分析Flutter输入框焦点事件的捕捉与监听
|
4天前
|
缓存 监控 前端开发
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
【4月更文挑战第30天】本文探讨了Flutter应用启动优化策略,包括理解启动过程、资源加载优化、减少初始化工作、界面布局简化、异步初始化、预加载关键数据、性能监控分析以及案例和未来优化方向。通过这些方法,可以缩短启动时间,提升用户体验。使用Flutter DevTools等工具可助于识别和解决性能瓶颈,实现持续优化。
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
|
2天前
|
前端开发 C++ 容器
Flutter-完整开发实战详解(一、Dart-语言和-Flutter-基础)(1)
Flutter-完整开发实战详解(一、Dart-语言和-Flutter-基础)(1)