Android 获取控件滑动速度,速度跟踪器VelocityTracker;
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;相关推荐
- android 获取控件在屏幕中的坐标
今天,简单讲讲android如何获取控件在屏幕中的坐标. 这个其实也很简单,但是昨天做一个功能时,需要功能控件的坐标做一些逻辑操作时,居然不知道怎么做.所以在网上查找了资料后,解决了这个问题.这里记录 ...
- android获取控件宽和高
Android获取控件宽高 在项目中用到了测量控件的宽和高,这个在Activity的onCreate去使用控件的getHeight()和getWidth()方法去获取是会失败的,返回的都是0.这是由于 ...
- android 获取控件高度_安卓开发入门教程UI控件_ImageView
什么是ImageView ImageView是用于显示图片的UI控件. 基础样例 1.展示本地图片 效果图 代码 <ImageViewandroid:layout_width="wra ...
- android 获取控件高度_安卓开发入门教程UI控件_ProgressBar
什么是ProgressBar ProgressBar是用于提示用户进行等待的UI控件,. 基础样例 1.loading图 效果图 代码 布局文件代码 <ProgressBarandroid:id ...
- android 获取控件 id 工具,如何使用appium desktop 获取Android APP 控件的id
背景: 随着Android 版本的更新,你会发现我们之前用的最新的版本的Appium 1.5.3无法启动我们的 Android APP 在模拟器为7.0的设备上,所以我们有必要了解如何使用 appiu ...
- android获取控件的id(标识符)-根据控件id获取对应的值或控件名字-动态获取R.string的值
更多其他页面-自定义View-实用功能合集:点击查看 项目中需要动态获取资源R.string的值,记录一下解决方案. demo链接: link. 直接先上个示例,下面再有详细解说: @Override ...
- android获取控件宽度高度
前几天,在自定义控件的时候碰到个问题,就是在如何获取自定义控件的高宽.在自定义控件类的构造函数中,本来以为可以轻松获取,但事实不是这样.我测试了下面代码: 先是布局代码: <com.lml.ge ...
- android ListView控件滑动时出现黑色背景问题解法方案
设置ListView属性android:cacheColorHint="#00000000" <ListViewandroid:id="@+id/orderDeta ...
- Android图表控件MPAndroidChart实现左右滑动以及联动
前言 MPAndroidChart是一个功能强大的Android图表控件库,它实现了许多常见的图表效果.关于MPAndroidChart的使用文章已经很多了,这里不再详细介绍它的使用.当数据量过多时, ...
最新文章
- mongodb android,如何在Android中连接到MongoDB数据库?
- Spring使用@Required注解依赖检查
- NgRx Selector 的 Memoization 特性学习笔记
- java+long是什么_Java中long的模运算符是什么? - java
- 机器学习 导论_机器学习导论
- 聊一聊开发常用小工具
- 服务器并发性能报告,一般的服务器瞬时并发应该怎么样才算是合格呢?
- C++之判断当前是debug还是realease
- Oliver运维管理系统之一庐山真面目
- 质性数据分析软件NVivo的代码
- Python入门教程三:显示'Welcome to Python'五次
- Google知识集锦
- 我们可能都低估了浪潮存储
- 华为荣耀play3分辨率_华为全新国行原封报价
- Tensorflow图像识别-2
- Android studio的ADBWifi使用
- 运维安全要了解的二三事
- QT5简易音乐播放器的设计
- 提高企业竞争力,如何开展知识管理工作?
- 【修改蓝牙设备名称】一步简单操作