VelocityTracker 速度跟踪器

在写关于Android滑动的控件,如果用户手指在屏幕上(当前位置 - 起始位置 > 某个数值)就做一个界面切换,但是总感觉太生硬,只有满足上面的条件才会触发切换界面,不管用户滑动的速度有多么的快,都要去算当前位置和起始位置的距离;但是ViewPager这个控件如果你滑动速度很快的话,就触发切换页面的效果了,怎么实现的呢;于是我去看了一下Google的ViewPager的源码,发现了这么个神器的东西:VelocityTracker;

以下是Viewpager的源码:

 @Overridepublic boolean onTouchEvent(MotionEvent ev) {if (mFakeDragging) {// A fake drag is in progress already, ignore this real one// but still eat the touch events.// (It is likely that the user is multi-touching the screen.)return true;}if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {// Don't handle edge touches immediately -- they may actually belong to one of our// descendants.return false;}if (mAdapter == null || mAdapter.getCount() == 0) {// Nothing to present or scroll; nothing to touch.return false;}if (mVelocityTracker == null) {mVelocityTracker = VelocityTracker.obtain();}mVelocityTracker.addMovement(ev);final int action = ev.getAction();boolean needsInvalidate = false;switch (action & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_DOWN: {mScroller.abortAnimation();mPopulatePending = false;populate();// Remember where the motion event startedmLastMotionX = mInitialMotionX = ev.getX();mLastMotionY = mInitialMotionY = ev.getY();mActivePointerId = ev.getPointerId(0);break;}case MotionEvent.ACTION_MOVE:if (!mIsBeingDragged) {final int pointerIndex = ev.findPointerIndex(mActivePointerId);if (pointerIndex == -1) {// A child has consumed some touch events and put us into an inconsistent// state.needsInvalidate = resetTouch();break;}final float x = ev.getX(pointerIndex);final float xDiff = Math.abs(x - mLastMotionX);final float y = ev.getY(pointerIndex);final float yDiff = Math.abs(y - mLastMotionY);if (DEBUG) {Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff);}if (xDiff > mTouchSlop && xDiff > yDiff) {if (DEBUG) Log.v(TAG, "Starting drag!");mIsBeingDragged = true;requestParentDisallowInterceptTouchEvent(true);mLastMotionX = x - mInitialMotionX > 0 ? mInitialMotionX + mTouchSlop :mInitialMotionX - mTouchSlop;mLastMotionY = y;setScrollState(SCROLL_STATE_DRAGGING);setScrollingCacheEnabled(true);// Disallow Parent Intercept, just in caseViewParent parent = getParent();if (parent != null) {parent.requestDisallowInterceptTouchEvent(true);}}}// Not else! Note that mIsBeingDragged can be set above.if (mIsBeingDragged) {// Scroll to follow the motion eventfinal int activePointerIndex = ev.findPointerIndex(mActivePointerId);final float x = ev.getX(activePointerIndex);needsInvalidate |= performDrag(x);}break;case MotionEvent.ACTION_UP:if (mIsBeingDragged) {final VelocityTracker velocityTracker = mVelocityTracker;velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId);mPopulatePending = true;final int width = getClientWidth();final int scrollX = getScrollX();final ItemInfo ii = infoForCurrentScrollPosition();final float marginOffset = (float) mPageMargin / width;final int currentPage = ii.position;final float pageOffset = (((float) scrollX / width) - ii.offset)/ (ii.widthFactor + marginOffset);final int activePointerIndex = ev.findPointerIndex(mActivePointerId);final float x = ev.getX(activePointerIndex);final int totalDelta = (int) (x - mInitialMotionX);int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity,totalDelta);setCurrentItemInternal(nextPage, true, true, initialVelocity);needsInvalidate = resetTouch();}break;case MotionEvent.ACTION_CANCEL:if (mIsBeingDragged) {scrollToItem(mCurItem, true, 0, false);needsInvalidate = resetTouch();}break;case MotionEvent.ACTION_POINTER_DOWN: {final int index = ev.getActionIndex();final float x = ev.getX(index);mLastMotionX = x;mActivePointerId = ev.getPointerId(index);break;}case MotionEvent.ACTION_POINTER_UP:onSecondaryPointerUp(ev);mLastMotionX = ev.getX(ev.findPointerIndex(mActivePointerId));break;}if (needsInvalidate) {ViewCompat.postInvalidateOnAnimation(this);}return true;}

有这么几行代码:
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(ev);

final VelocityTracker velocityTracker = mVelocityTracker;
                    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
                    int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId);

它在Touch中实例化VelocityTracker ,在UP触摸事件中获取到当前的速度;

可以仿着写个自定义的View:

public class ContinueSlideScrollView extends NestedScrollView {private final String TAG = "CCB";public ContinueSlideScrollView(Context context) {super(context);this.context = context;}public ContinueSlideScrollView(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;}public ContinueSlideScrollView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);this.context = context;}@Overridepublic boolean onTouchEvent(MotionEvent ev) {if (mVelocityTracker == null) {mVelocityTracker = VelocityTracker.obtain();}mVelocityTracker.addMovement(ev);switch (ev.getAction()){case MotionEvent.ACTION_DOWN:break;case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_UP:final VelocityTracker velocityTracker = mVelocityTracker;velocityTracker.computeCurrentVelocity(1000, ViewConfiguration.get(context).getScaledMaximumFlingVelocity());int initialVelocity = (int) velocityTracker.getYVelocity();Log.i(TAG, initialVelocity>0 ? "向下滑动,速度是:"+initialVelocity : "向上滑动,速度是:"+initialVelocity);break;}return super.onTouchEvent(ev);}@Overrideprotected void onDetachedFromWindow() {mVelocityTracker.recycle();super.onDetachedFromWindow();}
}

获取到当前View的滑动速度后,你就可以对它胡作非为了!!!

Android 获取控件滑动速度,速度跟踪器VelocityTracker;相关推荐

  1. android 获取控件在屏幕中的坐标

    今天,简单讲讲android如何获取控件在屏幕中的坐标. 这个其实也很简单,但是昨天做一个功能时,需要功能控件的坐标做一些逻辑操作时,居然不知道怎么做.所以在网上查找了资料后,解决了这个问题.这里记录 ...

  2. android获取控件宽和高

    Android获取控件宽高 在项目中用到了测量控件的宽和高,这个在Activity的onCreate去使用控件的getHeight()和getWidth()方法去获取是会失败的,返回的都是0.这是由于 ...

  3. android 获取控件高度_安卓开发入门教程UI控件_ImageView

    什么是ImageView ImageView是用于显示图片的UI控件. 基础样例 1.展示本地图片 效果图 代码 <ImageViewandroid:layout_width="wra ...

  4. android 获取控件高度_安卓开发入门教程UI控件_ProgressBar

    什么是ProgressBar ProgressBar是用于提示用户进行等待的UI控件,. 基础样例 1.loading图 效果图 代码 布局文件代码 <ProgressBarandroid:id ...

  5. android 获取控件 id 工具,如何使用appium desktop 获取Android APP 控件的id

    背景: 随着Android 版本的更新,你会发现我们之前用的最新的版本的Appium 1.5.3无法启动我们的 Android APP 在模拟器为7.0的设备上,所以我们有必要了解如何使用 appiu ...

  6. android获取控件的id(标识符)-根据控件id获取对应的值或控件名字-动态获取R.string的值

    更多其他页面-自定义View-实用功能合集:点击查看 项目中需要动态获取资源R.string的值,记录一下解决方案. demo链接: link. 直接先上个示例,下面再有详细解说: @Override ...

  7. android获取控件宽度高度

    前几天,在自定义控件的时候碰到个问题,就是在如何获取自定义控件的高宽.在自定义控件类的构造函数中,本来以为可以轻松获取,但事实不是这样.我测试了下面代码: 先是布局代码: <com.lml.ge ...

  8. android ListView控件滑动时出现黑色背景问题解法方案

    设置ListView属性android:cacheColorHint="#00000000" <ListViewandroid:id="@+id/orderDeta ...

  9. Android图表控件MPAndroidChart实现左右滑动以及联动

    前言 MPAndroidChart是一个功能强大的Android图表控件库,它实现了许多常见的图表效果.关于MPAndroidChart的使用文章已经很多了,这里不再详细介绍它的使用.当数据量过多时, ...

最新文章

  1. mongodb android,如何在Android中连接到MongoDB数据库?
  2. Spring使用@Required注解依赖检查
  3. NgRx Selector 的 Memoization 特性学习笔记
  4. java+long是什么_Java中long的模运算符是什么? - java
  5. 机器学习 导论_机器学习导论
  6. 聊一聊开发常用小工具
  7. 服务器并发性能报告,一般的服务器瞬时并发应该怎么样才算是合格呢?
  8. C++之判断当前是debug还是realease
  9. Oliver运维管理系统之一庐山真面目
  10. 质性数据分析软件NVivo的代码
  11. Python入门教程三:显示'Welcome to Python'五次
  12. Google知识集锦
  13. 我们可能都低估了浪潮存储
  14. 华为荣耀play3分辨率_华为全新国行原封报价
  15. Tensorflow图像识别-2
  16. Android studio的ADBWifi使用
  17. 运维安全要了解的二三事
  18. QT5简易音乐播放器的设计
  19. 提高企业竞争力,如何开展知识管理工作?
  20. 【修改蓝牙设备名称】一步简单操作

热门文章

  1. 基于Vue和SpringBoot的毕业生追踪系统的设计和实现
  2. Android状态栏微技巧
  3. C++ 关键字之 mutable
  4. Android实验SQLite
  5. Defects4J安装问题记录
  6. linux下同一文件系统,Linux文件系统详解
  7. 你是我生命中最重要的人。我说,你是我的天使。
  8. VMware网络设置技巧
  9. Windows权限维持之php不死马、映像劫持、策略组脚本
  10. 火狐浏览器与chrome_chrome edge Firefox歌剧或野生动物园哪种浏览器最好