1. 程式人生 > >Android重寫ViewPager修改滑動靈敏度

Android重寫ViewPager修改滑動靈敏度

使用ViewPager作為一個頁面進行切換,裡面可以存放很多View,但有時在操作View時不小心滑動一下就有可能跳到下一頁,這並不是我們想要的,這裡就需要重寫ViewPager修改它的滑動條件

效果圖


程式目錄結構


BTViewPager.java

  1. package com.example.viewpagerdemo;  
  2. import android.content.Context;  
  3. import android.support.v4.view.ViewPager;  
  4. import android.util.AttributeSet;  
  5. import android.util.Log;  
  6. import android.view.MotionEvent;  
  7. import android.widget.Scroller;  
  8. /** 
  9.  * 解決ViewPager滑動過於靈敏,只有滑動距離大於100才滑到另一頁 
  10.  *  
  11.  * @author Administrator 
  12.  *  
  13.  */
  14. publicclass BTViewPager extends ViewPager {  
  15.     privatestaticfinal String TAG = "dzt_pager";  
  16.     privatestaticfinalint MOVE_LIMITATION = 100;// 觸發移動的畫素距離
  17.     privatefloat mLastMotionX; // 手指觸碰螢幕的最後一次x座標
  18.     privateint mCurScreen;  
  19.     private Scroller mScroller; // 滑動控制元件
  20.     public BTViewPager(Context context) {  
  21.         super(context);  
  22.         // TODO Auto-generated constructor stub
  23.         init(context);  
  24.     }  
  25.     public BTViewPager(Context context, AttributeSet attrs) {  
  26.         super(context, attrs);  
  27.         // TODO Auto-generated constructor stub
  28.         init(context);  
  29.     }  
  30.     privatevoid init(Context context) {  
  31.         mScroller = new Scroller(context);  
  32.         mCurScreen = 0;// 預設設定顯示第一個VIEW
  33.     }  
  34.     @Override
  35.     publicboolean onTouchEvent(MotionEvent event) {  
  36.         // TODO Auto-generated method stub
  37.         finalint action = event.getAction();  
  38.         finalfloat x = event.getX();  
  39.         switch (action) {  
  40.         case MotionEvent.ACTION_DOWN:  
  41.             Log.d(TAG, "[BTViewPager->]onTouchEvent ACTION_DOWN");  
  42.             mLastMotionX = x;  
  43.             break;  
  44.         case MotionEvent.ACTION_MOVE:  
  45.             Log.d(TAG, "[BTViewPager->]onTouchEvent ACTION_MOVE");  
  46.             break;  
  47.         case MotionEvent.ACTION_UP:  
  48.             Log.d(TAG, "Item = " + getCurrentItem() + " count = "
  49.                     + getChildCount());  
  50.             if (Math.abs(x - mLastMotionX) < MOVE_LIMITATION) {  
  51.                 // snapToDestination(); // 跳到指定頁
  52.                 snapToScreen(getCurrentItem());  
  53.                 returntrue;  
  54.             }  
  55.             break;  
  56.         default:  
  57.             break;  
  58.         }  
  59.         Log.d(TAG, "[BTViewPager->]onTouchEvent--end");  
  60.         returnsuper.onTouchEvent(event);  
  61.     }  
  62.     @Override
  63.     publicvoid computeScroll() {  
  64.         // TODO Auto-generated method stub
  65.         Log.d(TAG, "[BTViewPager->]computeScroll");  
  66.         super.computeScroll();  
  67.         if (mScroller.computeScrollOffset()) {  
  68.             Log.d(TAG,  
  69.                     "[BTViewPager->]computeScroll x = " + mScroller.getCurrX());  
  70.             scrollTo(mScroller.getCurrX(), mScroller.getCurrY());  
  71.             invalidate();  
  72.         }  
  73.     }  
  74.     /** 
  75.      * 根據滑動的距離判斷移動到第幾個檢視 
  76.      */
  77.     publicvoid snapToDestination() {  
  78.         finalint screenWidth = getWidth();  
  79.         finalint destScreen = (getScrollX() + screenWidth / 2) / screenWidth;  
  80.         Log.d(TAG, "[BTViewPager->]snapToDestination screenWidth = "
  81.                 + screenWidth + " destScreen = " + destScreen);  
  82.         snapToScreen(destScreen);  
  83.     }  
  84.     /** 
  85.      * 滾動到制定的檢視 
  86.      *  
  87.      * @param whichScreen 
  88.      *            檢視下標 
  89.      */
  90.     publicvoid snapToScreen(int whichScreen) {  
  91.         // whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() -
  92.         // 1));
  93.         if (getScrollX() != (whichScreen * getWidth())) {  
  94.             finalint delta = whichScreen * getWidth() - getScrollX();  
  95.             Log.d(TAG, "[BTViewPager->]snapToScreen-whichScreen = "
  96.                     + whichScreen + " delta = " + delta + " scrollX = "
  97.                     + getScrollX());  
  98.             mScroller.startScroll(getScrollX(), 0, delta, 0,  
  99.                     Math.abs(delta) * 2);  
  100.             mCurScreen = whichScreen;  
  101.             invalidate();  
  102.         }  
  103.     }  
  104.     /** 
  105.      * 用於攔截手勢事件的,每個手勢事件都會先呼叫這個方法。Layout裡的onInterceptTouchEvent預設返回值是false, 
  106.      * 這樣touch事件會傳遞到childview控制元件 ,如果返回false子控制元件可以響應,否則了控制元件不響應,這裡主要是攔截子控制元件的響應, 
  107.      * 對ViewGroup不管返回值是什麼都會執行onTouchEvent 
  108.      */
  109.     @Override
  110.     publicboolean onInterceptTouchEvent(MotionEvent arg0) {  
  111.         // TODO Auto-generated method stub
  112.         Log.d(TAG, "[BTViewPager->]onInterceptTouchEvent");  
  113.         finalint action = arg0.getAction();  
  114.         finalfloat x = arg0.getX();  
  115.         switch (action) {  
  116.         case MotionEvent.ACTION_DOWN:  
  117.             Log.d(TAG, "onInterceptTouchEvent---ACTION_DOWN ");  
  118.             mLastMotionX = x;  
  119.             break;  
  120.         case MotionEvent.ACTION_MOVE:  
  121.             Log.d(TAG, "onInterceptTouchEvent---ACTION_MOVE ");  
  122.             break;  
  123.         case MotionEvent.ACTION_UP:  
  124.             Log.d(TAG, "onInterceptTouchEvent---ACTION_UP ");  
  125.             break;  
  126.         default:  
  127.             break;  
  128.         }  
  129.         returnsuper.onInterceptTouchEvent(arg0);  
  130.     }  
  131. }  
只要是在onTouchEvent的UP中處理滑動的條件
  1. if (Math.abs(x - mLastMotionX) < MOVE_LIMITATION) {  
  2.                 // snapToDestination(); // 跳到指定頁
  3.                 snapToScreen(getCurrentItem());  
  4.                 returntrue;  
  5.             }  
只有滑動的距離大於100才進行上下頁處理,否則就停在當前頁,當前頁使用getCurrentItem()獲取,有一點要注意在ViewPager中getChildCount()獲取的值是錯誤的,不清楚是什麼原因,在ViewGroup中是有效的,這個可能要檢視ViewPager原始碼才能弄清楚是什麼原因,有知道的朋友可以告知我!
完整Demo:http://download.csdn.net/detail/deng0zhaotai/7384637