使用ViewPager作为一个页面进行切换,里面可以存放很多View,但有时在操作View时不小心滑动一下就有可能跳到下一页,这并不是我们想要的,这里就需要重写ViewPager修改它的滑动条件
效果图
程序目录结构
BTViewPager.java
- packagecom.example.viewpagerdemo;
- importandroid.content.Context;
- importandroid.support.v4.view.ViewPager;
- importandroid.util.AttributeSet;
- importandroid.util.Log;
- importandroid.view.MotionEvent;
- importandroid.widget.Scroller;
- /**
- *解决ViewPager滑动过于灵敏,只有滑动距离大于100才滑到另一页
- *
- *@authorAdministrator
- *
- */
- publicclassBTViewPagerextendsViewPager{
- privatestaticfinalStringTAG="dzt_pager";
- privatestaticfinalintMOVE_LIMITATION=100;//触发移动的像素距离
- privatefloatmLastMotionX;//手指触碰屏幕的最后一次x坐标
- privateintmCurScreen;
- privateScrollermScroller;//滑动控件
- publicBTViewPager(Contextcontext){
- super(context);
- //TODOAuto-generatedconstructorstub
- init(context);
- }
- publicBTViewPager(Contextcontext,AttributeSetattrs){
- super(context,attrs);
- //TODOAuto-generatedconstructorstub
- init(context);
- }
- privatevoidinit(Contextcontext){
- mScroller=newScroller(context);
- mCurScreen=0;//默认设置显示第一个VIEW
- }
- @Override
- publicbooleanonTouchEvent(MotionEventevent){
- //TODOAuto-generatedmethodstub
- finalintaction=event.getAction();
- finalfloatx=event.getX();
- switch(action){
- caseMotionEvent.ACTION_DOWN:
- Log.d(TAG,"[BTViewPager->]onTouchEventACTION_DOWN");
- mLastMotionX=x;
- break;
- caseMotionEvent.ACTION_MOVE:
- Log.d(TAG,"[BTViewPager->]onTouchEventACTION_MOVE");
- break;
- caseMotionEvent.ACTION_UP:
- Log.d(TAG,"Item="+getCurrentItem()+"count="
- +getChildCount());
- if(Math.abs(x-mLastMotionX)<MOVE_LIMITATION){
- //snapToDestination();//跳到指定页
- snapToScreen(getCurrentItem());
- returntrue;
- }
- break;
- default:
- break;
- }
- Log.d(TAG,"[BTViewPager->]onTouchEvent--end");
- returnsuper.onTouchEvent(event);
- }
- @Override
- publicvoidcomputeScroll(){
- //TODOAuto-generatedmethodstub
- Log.d(TAG,"[BTViewPager->]computeScroll");
- super.computeScroll();
- if(mScroller.computeScrollOffset()){
- Log.d(TAG,
- "[BTViewPager->]computeScrollx="+mScroller.getCurrX());
- scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
- invalidate();
- }
- }
- /**
- *根据滑动的距离判断移动到第几个视图
- */
- publicvoidsnapToDestination(){
- finalintscreenWidth=getWidth();
- finalintdestScreen=(getScrollX()+screenWidth/2)/screenWidth;
- Log.d(TAG,"[BTViewPager->]snapToDestinationscreenWidth="
- +screenWidth+"destScreen="+destScreen);
- snapToScreen(destScreen);
- }
- /**
- *滚动到制定的视图
- *
- *@paramwhichScreen
- *视图下标
- */
- publicvoidsnapToScreen(intwhichScreen){
- //whichScreen=Math.max(0,Math.min(whichScreen,getChildCount()-
- //1));
- if(getScrollX()!=(whichScreen*getWidth())){
- finalintdelta=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();
- }
- }
- /**
- *用于拦截手势事件的,每个手势事件都会先调用这个方法。Layout里的onInterceptTouchEvent默认返回值是false,
- *这样touch事件会传递到childview控件,如果返回false子控件可以响应,否则了控件不响应,这里主要是拦截子控件的响应,
- *对ViewGroup不管返回值是什么都会执行onTouchEvent
- */
- @Override
- publicbooleanonInterceptTouchEvent(MotionEventarg0){
- //TODOAuto-generatedmethodstub
- Log.d(TAG,"[BTViewPager->]onInterceptTouchEvent");
- finalintaction=arg0.getAction();
- finalfloatx=arg0.getX();
- switch(action){
- caseMotionEvent.ACTION_DOWN:
- Log.d(TAG,"onInterceptTouchEvent---ACTION_DOWN");
- mLastMotionX=x;
- break;
- caseMotionEvent.ACTION_MOVE:
- Log.d(TAG,"onInterceptTouchEvent---ACTION_MOVE");
- break;
- caseMotionEvent.ACTION_UP:
- Log.d(TAG,"onInterceptTouchEvent---ACTION_UP");
- break;
- default:
- break;
- }
- returnsuper.onInterceptTouchEvent(arg0);
- }
- }
- if(Math.abs(x-mLastMotionX)<MOVE_LIMITATION){
- //snapToDestination();//跳到指定页
- snapToScreen(getCurrentItem());
- returntrue;
- }
完整Demo: http://download.csdn.net/detail/deng0zhaotai/7384637