北京地铁建设的官方网站,网站什么意思,wordpress主题下新建页面,宁波seo关键词优化教程在编写自己定义滑动控件时经常会用到Android触摸机制和Scroller及VelocityTracker。Android Touch系统简单介绍#xff08;二#xff09;:实例具体解释onInterceptTouchEvent与onTouchEvent的调用过程对Android触摸机制须要用到的函数进行了具体的解释。本文主要介绍两个重要… 在编写自己定义滑动控件时经常会用到Android触摸机制和Scroller及VelocityTracker。Android Touch系统简单介绍二:实例具体解释onInterceptTouchEvent与onTouchEvent的调用过程对Android触摸机制须要用到的函数进行了具体的解释。本文主要介绍两个重要的类Scroller及VelocityTracker。利用上述知识最后给出了一个自己定义滑动控件的demo该demo类似于ImageGallery。ImageGallery通常是用GridView来实现的能够左右滑动。本样例实现的控件直接继承一个ViewGroup对其回调函数如 onTouchEvent、onInterceptTouchEvent、computeScroll等进行重载。弄懂该代码。对Android touch的认识将会更深一层。 VelocityTracker:用于对触摸点的速度跟踪方便获取触摸点的速度。 使用方法一般在onTouchEvent事件中被调用。先在down事件中获取一个VecolityTracker对象然后在move或up事件中获取速度调用流程可例如以下列所看到的 VelocityTracker vTracker null
Override
public boolean onTouchEvent(MotionEvent event){ int action event.getAction(); switch(action){ case MotionEvent.ACTION_DOWN: if(vTracker null){ vTracker VelocityTracker.obtain(); }else{ vTracker.clear(); } vTracker.addMovement(event); break; case MotionEvent.ACTION_MOVE: vTracker.addMovement(event); //设置单位1000 表示每秒多少像素pix/second),1代表每微秒多少像素pix/millisecond)。 vTracker.computeCurrentVelocity(1000); //从左向右划返回正数从右向左划返回负数System.out.println(the x velocity is vTracker.getXVelocity()); //从上往下划返回正数从下往上划返回负数System.out.println(the y velocity is vTracker.getYVelocity()); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: vTracker.recycle(); break; } return true;
} Scroller用于跟踪控件滑动的轨迹。此类不会移动控件须要你在View的一个回调函数computerScroll()中使用Scroller对象还获取滑动的数据来控制某个View。 /*** Called by a parent to request that a child update its values for mScrollX* and mScrollY if necessary. This will typically be done if the child is* animating a scroll using a {link android.widget.Scroller Scroller}* object.*/
public void computeScroll()
{
}parentView在绘制式。会调用dispatchDraw(Canvas canvas)该函数会调用ViewGroup中的每一个子view的boolean draw(Canvas canvas, ViewGroup parent, long drawingTime)用户绘制View此函数在绘制View的过程中会调用computeScroll 以下给出一段代码Override
public void computeScroll() { // TODO Auto-generated method stubLog.e(TAG, computeScroll);if (mScroller.computeScrollOffset()) { //or !mScroller.isFinished()Log.e(TAG, mScroller.getCurrX() mScroller.getCurrY());scrollTo(mScroller.getCurrX(), mScroller.getCurrY());Log.e(TAG, ### getleft is getLeft() ### getRight is getRight());postInvalidate();}elseLog.i(TAG, have done the scoller -----);
}这段代码在滑动view之前先调用mScroller.computeScrollOffset()来推断滑动动画是否已结束。computerScrollerOffset()的源码例如以下 /*** Call this when you want to know the new location. If it returns true,* the animation is not yet finished.*/
public boolean computeScrollOffset() {if (mFinished) {return false;}//滑动已经持续的时间int timePassed (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);//若在规定时间还未用完则继续设置新的滑动位置mCurrX和mCurryif (timePassed mDuration) {switch (mMode) {case SCROLL_MODE:float x timePassed * mDurationReciprocal;if (mInterpolator null)x viscousFluid(x); elsex mInterpolator.getInterpolation(x);mCurrX mStartX Math.round(x * mDeltaX);mCurrY mStartY Math.round(x * mDeltaY);break;case FLING_MODE:final float t (float) timePassed / mDuration;final int index (int) (NB_SAMPLES * t);float distanceCoef 1.f;float velocityCoef 0.f;if (index NB_SAMPLES) {final float t_inf (float) index / NB_SAMPLES;final float t_sup (float) (index 1) / NB_SAMPLES;final float d_inf SPLINE_POSITION[index];final float d_sup SPLINE_POSITION[index 1];velocityCoef (d_sup - d_inf) / (t_sup - t_inf);distanceCoef d_inf (t - t_inf) * velocityCoef;}mCurrVelocity velocityCoef * mDistance / mDuration * 1000.0f;mCurrX mStartX Math.round(distanceCoef * (mFinalX - mStartX));// Pin to mMinX mCurrX mMaxXmCurrX Math.min(mCurrX, mMaxX);mCurrX Math.max(mCurrX, mMinX);mCurrY mStartY Math.round(distanceCoef * (mFinalY - mStartY));// Pin to mMinY mCurrY mMaxYmCurrY Math.min(mCurrY, mMaxY);mCurrY Math.max(mCurrY, mMinY);if (mCurrX mFinalX mCurrY mFinalY) {mFinished true;}break;}}else {mCurrX mFinalX;mCurrY mFinalY;mFinished true;}return true;
}ViewGroup.computeScroll()被调用时机 当我们运行ontouch或invalidate(或postInvalidate()都会导致这种方法的运行。 我们在开发控件时。常会有这种需求当单机某个button时。某个图片会在规定的时间内滑出窗体。而不是一下子进入窗体。实现这个功能能够使用Scroller来实现。以下给出一段代码该代码控制下一个界面在3秒时间内缓慢进入的效果。 public void moveToRightSide(){if (curScreen 0) {return;}curScreen-- ;Log.i(TAG, ----moveToRightSide---- curScreen curScreen);mScroller.startScroll((curScreen 1) * getWidth(), 0, -getWidth(), 0, 3000);scrollTo(curScreen * getWidth(), 0);invalidate();
}上述代码用到了一个函数void android.widget.Scroller.startScroll(int startX, int startY, int dx, int dy, int duration) 当startScroll运行过程中即在duration时间内computeScrollOffset 方法会一直返回true但当动画运行完毕后会返回返加false. 这个函数的源代码例如以下所看到的主要用于设置滑动參数 /*** Start scrolling by providing a starting point, the distance to travel,* and the duration of the scroll.* * param startX Starting horizontal scroll offset in pixels. Positive* numbers will scroll the content to the left.* param startY Starting vertical scroll offset in pixels. Positive numbers* will scroll the content up.* param dx Horizontal distance to travel. Positive numbers will scroll the* content to the left.* param dy Vertical distance to travel. Positive numbers will scroll the* content up.* param duration Duration of the scroll in milliseconds.*/
public void startScroll(int startX, int startY, int dx, int dy, int duration) {mMode SCROLL_MODE;mFinished false;mDuration duration;mStartTime AnimationUtils.currentAnimationTimeMillis();mStartX startX;mStartY startY;mFinalX startX dx;mFinalY startY dy;mDeltaX dx;mDeltaY dy;mDurationReciprocal 1.0f / (float) mDuration;
}
invalidate()会使得视图重绘导致parent调用了dispatchDraw(Canvas canvas)然后递归调用child View的draw()函数。该函数又会调用我们定义的computeScroll(), 而这个函数又会调用mScroller.computeScrollOffset()推断动画是否结束。若没结束则继续重绘直到直到startScroll中设置的时间耗尽mScroller.computeScrollOffset()返回false才停下来。 附上完整的实例代码 自己定义Android可滑动控件源代码 执行效果图例如以下滑动屏幕会显示不同的图片。 转载于:https://www.cnblogs.com/claireyuancy/p/6714587.html