編輯:關於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源碼才能弄清楚是什麼原因,有知道的朋友可以告知我!
Android開發筆記(一百一十九)工具欄ToolBar
Toolbar在前面的博文《Android開發筆記(二十)頂部導航欄》中,我們學習了ActionBar的用法,可是ActionBar著實是不怎麼好用,比如文字風格不能定制
Android從零單排之獲取ImageView的寬高為0?
問題描述 說起來我也夠菜的!⊙﹏⊙b汗。 今天搞了一個關於圖片的demo,想動態的改變一張圖片的大小和margin值。但是在activity
Android 自定義View之隨機生成圖片驗證碼
本篇文章講的是Android自定義View之隨機生成圖片驗證碼,開發中我們會經常需要隨機生成圖片驗證碼,但是這個是其次,主要還是想總結一些自定義View的開發過程以及一些
Android BroadcastReceiver廣播注冊方式總結
Android:BroadcastReceiver注冊的方式分為兩種:靜態注冊動態注冊1. 靜態注冊在AndroidManifest.xml裡通過標簽聲明屬性說明:<