缩放手势 ScaleGestureDetector 源码解析,这一篇就够了

其实在我们日常的编程中,对于缩放手势的使用并不是很经常,这一手势主要是用在图片浏览方面,比如下方例子。但是(敲重点),作为 Android 入门的基础来说,学习 ScaleGestureDetector 的使用,算是不得不过的一道坎,好在 ScaleGestureDetector 使用起来非常简单,就是源码分析上得花些功夫。

本文首先将简单的介绍下 ScaleGestureDetector 的使用,在重点给大家分析下源码(由于源码方面是我自己的理解,可能有偏差,希望各位大佬能在评论区指出,万分感谢~)

缩放手势 ScaleGestureDetector 源码解析,这一篇就够了

ScaleGestureDetector 使用

ScaleGestureDetector 包括一个监听器,以及它所有方法的空实现:

名称 用途
ScaleGestureDetector   缩放手势的监听器  
SimpleOnScaleGestureListener   该监听器的空实现,在其中重写方法  
ScaleGestureDetector 方法 名称 用途
onScaleBegin   当 >= 2 个手指碰触屏幕时调用,若返回 false 则忽略改事件调用  
onScale   滑动(缩放)过程中调用,若成功处理,则用户返回 true,监听器继续记录下一个缩放等动作,若为 false 表明数据未处理,则监听器继续积累  
onScaleEnd   全部手指离开屏幕,结束监听  

通常情况下,手势监听会结合自定义 View 来讲,这里我给出一个最简单的使用,具体的使用实例,以后再结合自定义 View 讲讲。

private void iniScaleGestureListener(){ mListener = new ScaleGestureDetector.SimpleOnScaleGestureListener(){ @Override public boolean onScaleBegin(ScaleGestureDetector detector) { return super.onScaleBegin(detector); } @Override public boolean onScale(ScaleGestureDetector detector) { MyLog.d("X:" + detector.getFocusX()); MyLog.d("Y:" + detector.getFocusY()); MyLog.d("scale:" + detector.getScaleFactor()); return super.onScale(detector); } @Override public void onScaleEnd(ScaleGestureDetector detector) { super.onScaleEnd(detector); } }; detector = new ScaleGestureDetector(getContext(), mListener); } @Override public boolean onTouchEvent(MotionEvent event) { detector.onTouchEvent(event); return true; } ScaleGestureDetector 的使用

ScaleGestureDetector 在具体项目的使用有点复杂,我打算过段时间结合自定义 View 写一篇用来总结,所以这篇我们就先了解下 ScaleGestureDetector 的基本使用。

ScaleGestureDetector 源码分析

好了,现在我们进入本章重点,ScaleGestureDetector 源码分析,敲黑板敲黑板。首先,我们打开 ScaleGestureDetector 的源码可以看到,几乎所有的代码都集中在了 onTouchEvent 这个方法上,所以在这里,我就主要给大家介绍这个方法的实现。

第一部分:前期准备 if (mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onTouchEvent(event, 0); } mCurrTime = event.getEventTime(); final int action = event.getActionMasked(); // Forward the event to check for double tap gesture if (mQuickScaleEnabled) { mGestureDetector.onTouchEvent(event); } final int count = event.getPointerCount(); final boolean isStylusButtonDown = (event.getButtonState() & MotionEvent.BUTTON_STYLUS_PRIMARY) != 0; mInputEventConsistencyVerifier

输入事件一致性验证器 @有道

根据名字以及前面的定义

我们可以猜测这个对象应该是手势监听 Event 是否注册(连接到硬件)

所以,如果他为空,那么我们在这里调用 onTouchEvent 进行注册

if (mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onTouchEvent(event, 0); } mCurrTime

获得事件发生时的时间

mCurrTime = event.getEventTime(); action

获得事件类型

final int action = event.getActionMasked(); mQuickScaleEnabled

Forward the event to check for double tap gesture

@有道 转发事件以检查双击手势

首先是 mQuickScaleEnabled 这个对象

翻译过来是: @有道 启用快速扩展

作用大概就是调用双击监听事件,比如双击最大化

if (mQuickScaleEnabled) { mGestureDetector.onTouchEvent(event); } count

获得屏幕上手指的数目

final int count = event.getPointerCount(); isStylusButtonDown

这个主要是由于判断手写笔是否按下
由于我们很少处理手写笔,所以这里不做过多说明

final boolean isStylusButtonDown = (event.getButtonState() & MotionEvent.BUTTON_STYLUS_PRIMARY) != 0;

## 第二部分:处理与手势变化

用户的缩放手势不总是一定的,就是说对于用户而言,随时可能有手指碰触或离开屏幕,这就使得缩放中心的(焦点)随时可能发生变化,这部分主要是用来处理这一变化,并做出响应。

final boolean anchoredScaleCancelled = mAnchoredScaleMode == ANCHORED_SCALE_MODE_STYLUS && !isStylusButtonDown; final boolean streamComplete = action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL || anchoredScaleCancelled; // 如果发生了上面这种小动作,或者说有一手指离开了屏幕,进行调用 if (action == MotionEvent.ACTION_DOWN || streamComplete) { // Reset any scale in progress with the listener. // If it's an ACTION_DOWN we're beginning a new event stream. // This means the app probably didn't give us all the events. Shame on it. if (mInProgress) { mListener.onScaleEnd(this); mInProgress = false; mInitialSpan = 0; mAnchoredScaleMode = ANCHORED_SCALE_MODE_NONE; } else if (inAnchoredScaleMode() && streamComplete) { mInProgress = false; mInitialSpan = 0; mAnchoredScaleMode = ANCHORED_SCALE_MODE_NONE; } if (streamComplete) { return true; } }

### anchoredScaleCancelled

@Google 锚定规模取消

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjzfd.html