Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android重寫ViewPager修改滑動靈敏度

Android重寫ViewPager修改滑動靈敏度

編輯:關於Android編程

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

效果圖

\

程序目錄結構<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PGltZyBzcmM9"/uploadfile/Collfiles/20140523/20140523091225139.png" alt="\">

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;

/**
 * 解決ViewPager滑動過於靈敏,只有滑動距離大於100才滑到另一頁
 * 
 * @author Administrator
 * 
 */
public class BTViewPager extends ViewPager {

	private static final String TAG = "dzt_pager";
	private static final int MOVE_LIMITATION = 100;// 觸發移動的像素距離
	private float mLastMotionX; // 手指觸碰屏幕的最後一次x坐標
	private int mCurScreen;

	private Scroller mScroller; // 滑動控件

	public BTViewPager(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		init(context);
	}

	public BTViewPager(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		init(context);
	}

	private void init(Context context) {
		mScroller = new Scroller(context);
		mCurScreen = 0;// 默認設置顯示第一個VIEW
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub

		final 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:
			Log.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(); // 跳到指定頁
				snapToScreen(getCurrentItem());
				return true;
			}
			break;
		default:
			break;
		}
		Log.d(TAG, "[BTViewPager->]onTouchEvent--end");
		return super.onTouchEvent(event);
	}

	@Override
	public void computeScroll() {
		// TODO Auto-generated method stub
		Log.d(TAG, "[BTViewPager->]computeScroll");
		super.computeScroll();

		if (mScroller.computeScrollOffset()) {
			Log.d(TAG,
					"[BTViewPager->]computeScroll x = " + mScroller.getCurrX());
			scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
			invalidate();
		}

	}

	/**
	 * 根據滑動的距離判斷移動到第幾個視圖
	 */
	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);
	}

	/**
	 * 滾動到制定的視圖
	 * 
	 * @param whichScreen
	 *            視圖下標
	 */
	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();
		}
	}

	/**
	 * 用於攔截手勢事件的,每個手勢事件都會先調用這個方法。Layout裡的onInterceptTouchEvent默認返回值是false,
	 * 這樣touch事件會傳遞到childview控件 ,如果返回false子控件可以響應,否則了控件不響應,這裡主要是攔截子控件的響應,
	 * 對ViewGroup不管返回值是什麼都會執行onTouchEvent
	 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent arg0) {
		// TODO Auto-generated method stub
		Log.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);
	}
}
只要是在onTouchEvent的UP中處理滑動的條件

if (Math.abs(x - mLastMotionX) < MOVE_LIMITATION) {
				// snapToDestination(); // 跳到指定頁
				snapToScreen(getCurrentItem());
				return true;
			}
只有滑動的距離大於100才進行上下頁處理,否則就停在當前頁,當前頁使用getCurrentItem()獲取,有一點要注意在ViewPager中getChildCount()獲取的值是錯誤的,不清楚是什麼原因,在ViewGroup中是有效的,這個可能要查看ViewPager源碼才能弄清楚是什麼原因,有知道的朋友可以告知我!
完整Demo:http://download.csdn.net/detail/deng0zhaotai/7384637

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved