When ViewPager is used as a page switch, many views can be stored in it, but sometimes it is possible to jump to the next page without careful sliding during the operation of the View, which is not what we want, here we need to override ViewPager to modify its sliding condition.
Program directory structure
BTViewPager. java
Package com. example. viewpagerdemo; import android. content. context; import android. support. v4.view. viewPager; import android. util. attributeSet; import android. util. log; import android. view. motionEvent; import android. widget. scroller;/*** solves the problem that ViewPager sliding is too sensitive, slide to another page only when the sliding distance exceeds 100 ** @ author Administrator **/public class BTViewPager extends ViewPager {private static final String TAG = "dzt_pager"; private stati C final int MOVE_LIMITATION = 100; // The distance between the trigger pixel and the private float mLastMotionX; // The Last x coordinate of the finger touching the screen. private int mCurScreen; private Scroller mScroller; // sliding control public BTViewPager (Context context) {super (context); // TODO Auto-generated constructor stubinit (context);} public BTViewPager (Context context, AttributeSet attrs) {super (context, attrs); // TODO Auto-generated constructor stubinit (context);} private void Init (Context context) {mScroller = new Scroller (context); mCurScreen = 0; // The first VIEW is displayed by default.} @ Overridepublic boolean onTouchEvent (MotionEvent event) {// TODO Auto-generated method stubfinal int action = event. getAction (); final float x = event. getX (); switch (action) {case MotionEvent. ACTION_DOWN: Log. d (TAG, "[BTViewPager->] onTouchEvent ACTION_DOWN"); mLastMotionX = x; break; case MotionEvent. ACTION_MOVE: L Og. d (TAG, "[BTViewPager->] onTouchEvent ACTION_MOVE"); break; case MotionEvent. ACTION_UP: Log. d (TAG, "Item =" + getCurrentItem () + "count =" + getChildCount (); if (Math. abs (x-mLastMotionX) <MOVE_LIMITATION) {// snapToDestination (); // jump to the specified page snapToScreen (getCurrentItem (); return true;} break; default: break ;} log. d (TAG, "[BTViewPager->] onTouchEvent -- end"); return super. onTouchEvent (event) ;}@ Overridepubl Ic void computeScroll () {// TODO Auto-generated method stubLog. d (TAG, "[BTViewPager->] computeScroll"); super. computeScroll (); if (mScroller. computescroloffset () {Log. d (TAG, "[BTViewPager->] computeScroll x =" + mScroller. getCurrX (); scrollTo (mScroller. getCurrX (), mScroller. getCurrY (); invalidate () ;}}/*** determine the number of views to be moved to based on the sliding distance */public void snapToDestination () {final int screenWidth = getWidth (); final Int destScreen = (getScrollX () + screenWidth/2)/screenWidth; Log. d (TAG, "[BTViewPager->] snapToDestination screenWidth =" + screenWidth + "destScreen =" + destScreen); snapToScreen (destScreen );} /*** scroll to the created view ** @ param whichScreen * view subscript */public void snapToScreen (int whichScreen) {// whichScreen = Math. max (0, Math. min (whichScreen, getChildCount ()-// 1); if (getScrollX ()! = (WhichScreen * getWidth () {final int delta = whichScreen * getWidth ()-getScrollX (); Log. d (TAG, "[BTViewPager->] snapToScreen-whichScreen =" + whichScreen + "delta =" + delta + "scrollX =" + getScrollX (); mScroller. startScroll (getScrollX (), 0, delta, 0, Math. abs (delta) * 2); mCurScreen = whichScreen; invalidate () ;}/ *** used to intercept gesture events. This method is called for each gesture event first. The default value of onInterceptTouchEvent in Layout is false. * The touch event is passed to the childview control. If false is returned, the subcontrol can respond. Otherwise, the control does not respond, here we mainly intercept the response of the subcontrol. * The onTouchEvent */@ Overridepublic boolean onInterceptTouchEvent (MotionEvent arg0) will be executed for the ViewGroup regardless of the returned value. {// TODO Auto-generated method stubLog. d (TAG, "[BTViewPager->] onInterceptTouchEvent"); final int action = arg0.getAction (); final float x = arg0.getX (); switch (action) {case MotionEvent. ACTION_DOWN: Log. d (TAG, "onInterceptTouchEvent --- ACTION_DOWN"); mLastMotionX = x; break; case MotionEvent. ACTION_MOVE: Log. d (TAG, "onInterceptTouchEvent --- ACTION_MOVE"); break; case MotionEvent. ACTION_UP: Log. d (TAG, "onInterceptTouchEvent --- ACTION_UP"); break; default: break;} return super. onInterceptTouchEvent (arg0 );}}
As long as it is a condition for processing slide in the onTouchEvent UP
If (Math. abs (x-mLastMotionX) <MOVE_LIMITATION) {// snapToDestination (); // jump to the specified page snapToScreen (getCurrentItem (); return true ;}
Only when the sliding distance is greater than 100 can the upper and lower pages be processed. Otherwise, the current page will be stopped. The current page will be obtained using getCurrentItem (). Note that getChildCount () is used in ViewPager () the obtained value is incorrect. It is not clear what the cause is. It is valid in ViewGroup. You may need to check the source code of ViewPager to find out what the cause is. If you know it, please let me know!
Complete Demo: http://download.csdn.net/detail/deng0zhaotai/7384637