文章插图
缩放手势对于大部分 Android 工程师来说,需要用到的机会比较少,它最常见于以下的一些应用场景中,例如:图片浏览,图片编辑(贴图效果)、网页缩放、地图、文本阅读(通过缩放手势调整文字大小)等 。应用场景相对比较狭窄,不过肯定也会有一些用武之地,它可以实现如下的效果:
文章插图
2.缩放手势检测(ScaleGestureDetector)
缩放手势检测同样是官方提供的手势检测工具,它的使用方式的 GentureDetector 类似,也是通过 Listener 进行监听用户的操作手势,它是对缩放手势进行了一次封装, 可以方便用户快速的完成缩放相关功能的开发 。缩放手势相对比较简单,网络上也能查到不少非官方实现的缩放手势计算方案,但部分非官方的方案确实有所局限,例如只支持两个手指的计算,在出现超过两个手指时,只计算了前两个手指的移动,这样显然是不合理的 。而官方的这种实现方案轻松的应对了多个手指的情况,下面我们就来看看它是如何实现的吧 。
【Android缩放手势的检测】2.1 构造方法
它有两个构造方法,和 GestureDetector 类似,如下所示:
ScaleGestureDetector(Contextcontext,ScaleGestureDetector.OnScaleGestureListenerlistener)ScaleGestureDetector(Contextcontext,ScaleGestureDetector.OnScaleGestureListenerlistener,Handlerhandler) 2.2 手势监听器
它只有两个监听器,但严格来说,这两个监听器是同一个,只不过一个是接口,另一个是空实现而已 。
监听器 简介
OnScaleGestureListener 缩放手势检测器
SimpleOnScaleGestureListene r缩放手势检测器的空实现 。
2.3 简单示例
这是使用 ScaleGestureDetector 的一个极简用例,当然,它没有实现任何功能,只是用日志的方式输出了几个我们比较关心的参数而已 。
public class ScaleGestureDemoView extends View {private static final String TAG = "ScaleGestureDemoView"; private ScaleGestureDetector mScaleGestureDetector; public ScaleGestureDemoView(Context context) {super(context); } public ScaleGestureDemoView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initScaleGestureDetector(); }private void initScaleGestureDetector() {mScaleGestureDetector = new ScaleGestureDetector(getContext(), new ScaleGestureDetector.SimpleOnScaleGestureListener() { @Override public boolean onScaleBegin(ScaleGestureDetector detector) {return true; }@Override public boolean onScale(ScaleGestureDetector detector) { Log.i(TAG, "focusX = " + detector.getFocusX()); // 缩放中心,x坐标 Log.i(TAG, "focusY = " + detector.getFocusY()); // 缩放中心y坐标 Log.i(TAG, "scale = " + detector.getScaleFactor()); // 缩放因子 return true; } @Overridepublic void onScaleEnd(ScaleGestureDetector detector) {} }); }@Override public boolean onTouchEvent(MotionEvent event) { mScaleGestureDetector.onTouchEvent(event); return true;} }3. 基本原理
由于缩放手势检测使用起来非常简单,没有什么复杂的内容,不仅如此,它的实现也非常简单,下面我就带大家简单分析一下它的基本原理 。在缩放手势中我们其实主要关心的只有两个参数而已,一个是缩放的中心点,另一个就是缩放比例了 。 下面我们就看看这两个参数是如何计算出来的.
3.1 计算缩放的中心点(焦点)
如果只有两个手指的话,缩放的中心点自然是非常容易计算的,那就是两个手指坐标的中点,但是如果有多个手指该如何计算缩放的中心点呢?
计算中心点的原理其实也非常简单,那就是将所有的坐标都加起来,然后除以数量即可 。
这是一个简单的数学原理,并不复杂,如果有不理解的,自己尝试计算一下也就能明白了 。不过在实际运用中还是需要注意一下的, 用户的手指数量可能并不是固定的,用户可能随时抬起来或者按下手指,ScaleGestureDetector 中是这样实现的:
finalbooleananchoredScaleCancelled= mAnchoredScaleMode == ANCHORED_SCALE_MODE_STYLUS && !isStylusButtonDown; final boolean streamComplete = action == MotionEvent.ACTION_UP || finalbooleanstreamComplete=action==MotionEvent.ACTION_UP|| action == MotionEvent.ACTION_CANCEL || anchoredScaleCancelled; // 注意这里 if(action==MotionEvent.ACTION_DOWN||streamComplete){ //重置侦听器正在进行的任何缩放 。//如果是ACTION_DOWN,我们正在开始一个新的事件流 。//这意味着应用程序可能没有给我们所有的事件(事件被上层直接拦截了) 。if(mInProgress){ mListener.onScaleEnd(this); mInProgress=false; mInitialSpan=0; mAnchoredScaleMode=ANCHORED_SCALE_MODE_NONE; }elseif(inAnchoredScaleMode()&&streamComplete){ mInProgress=false; mInitialSpan=0; mAnchoredScaleMode=ANCHORED_SCALE_MODE_NONE; } if(streamComplete){ returntrue; }}
推荐阅读
- 自动识别 Android 不合理的内存分配
- Android面试题集锦之 Service
- 怎样搭高质量的Android项目框架,框架的结构具体描述?
- 谷歌Android 12L的适配机型,看得我们有点懵
- 浅谈Android类加载器
- Android 12推出正式版!这次的升级到底值不值得更新呢?
- 微软|来自X86的反击!微软研发Android和Windows深度整合
- 盖碗茶正确的喝法图解盖碗茶杯喝茶正确手势
- Android注解--初探
- 关于Android系统启动,你需要知道这些步骤