Android重写ViewPager修改滑动灵敏度

使用ViewPager作为一个页面进行切换,里面可以存放很多View,但有时在操作View时不小心滑动一下就有可能跳到下一页,这并不是我们想要的,这里就需要重写ViewPager修改它的滑动条件

效果图


程序目录结构


BTViewPager.java

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.example.viewpagerdemo;  
  2.   
  3. import android.content.Context;  
  4. import android.support.v4.view.ViewPager;  
  5. import android.util.AttributeSet;  
  6. import android.util.Log;  
  7. import android.view.MotionEvent;  
  8. import android.widget.Scroller;  
  9.   
  10. /** 
  11.  * 解决ViewPager滑动过于灵敏,只有滑动距离大于100才滑到另一页 
  12.  *  
  13.  * @author Administrator 
  14.  *  
  15.  */  
  16. public class BTViewPager extends ViewPager {  
  17.   
  18.     private static final String TAG = "dzt_pager";  
  19.     private static final int MOVE_LIMITATION = 100;// 触发移动的像素距离  
  20.     private float mLastMotionX; // 手指触碰屏幕的最后一次x坐标  
  21.     private int mCurScreen;  
  22.   
  23.     private Scroller mScroller; // 滑动控件  
  24.   
  25.     public BTViewPager(Context context) {  
  26.         super(context);  
  27.         // TODO Auto-generated constructor stub  
  28.         init(context);  
  29.     }  
  30.   
  31.     public BTViewPager(Context context, AttributeSet attrs) {  
  32.         super(context, attrs);  
  33.         // TODO Auto-generated constructor stub  
  34.         init(context);  
  35.     }  
  36.   
  37.     private void init(Context context) {  
  38.         mScroller = new Scroller(context);  
  39.         mCurScreen = 0;// 默认设置显示第一个VIEW  
  40.     }  
  41.   
  42.     @Override  
  43.     public boolean onTouchEvent(MotionEvent event) {  
  44.         // TODO Auto-generated method stub  
  45.   
  46.         final int action = event.getAction();  
  47.         final float x = event.getX();  
  48.         switch (action) {  
  49.         case MotionEvent.ACTION_DOWN:  
  50.             Log.d(TAG, "[BTViewPager->]onTouchEvent ACTION_DOWN");  
  51.             mLastMotionX = x;  
  52.             break;  
  53.         case MotionEvent.ACTION_MOVE:  
  54.             Log.d(TAG, "[BTViewPager->]onTouchEvent ACTION_MOVE");  
  55.             break;  
  56.         case MotionEvent.ACTION_UP:  
  57.             Log.d(TAG, "Item = " + getCurrentItem() + " count = "  
  58.                     + getChildCount());  
  59.   
  60.             if (Math.abs(x - mLastMotionX) < MOVE_LIMITATION) {  
  61.                 // snapToDestination(); // 跳到指定页  
  62.                 snapToScreen(getCurrentItem());  
  63.                 return true;  
  64.             }  
  65.             break;  
  66.         default:  
  67.             break;  
  68.         }  
  69.         Log.d(TAG, "[BTViewPager->]onTouchEvent--end");  
  70.         return super.onTouchEvent(event);  
  71.     }  
  72.   
  73.     @Override  
  74.     public void computeScroll() {  
  75.         // TODO Auto-generated method stub  
  76.         Log.d(TAG, "[BTViewPager->]computeScroll");  
  77.         super.computeScroll();  
  78.   
  79.         if (mScroller.computeScrollOffset()) {  
  80.             Log.d(TAG,  
  81.                     "[BTViewPager->]computeScroll x = " + mScroller.getCurrX());  
  82.             scrollTo(mScroller.getCurrX(), mScroller.getCurrY());  
  83.             invalidate();  
  84.         }  
  85.   
  86.     }  
  87.   
  88.     /** 
  89.      * 根据滑动的距离判断移动到第几个视图 
  90.      */  
  91.     public void snapToDestination() {  
  92.         final int screenWidth = getWidth();  
  93.         final int destScreen = (getScrollX() + screenWidth / 2) / screenWidth;  
  94.         Log.d(TAG, "[BTViewPager->]snapToDestination screenWidth = "  
  95.                 + screenWidth + " destScreen = " + destScreen);  
  96.         snapToScreen(destScreen);  
  97.     }  
  98.   
  99.     /** 
  100.      * 滚动到制定的视图 
  101.      *  
  102.      * @param whichScreen 
  103.      *            视图下标 
  104.      */  
  105.     public void snapToScreen(int whichScreen) {  
  106.         // whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() -  
  107.         // 1));  
  108.         if (getScrollX() != (whichScreen * getWidth())) {  
  109.   
  110.             final int delta = whichScreen * getWidth() - getScrollX();  
  111.             Log.d(TAG, "[BTViewPager->]snapToScreen-whichScreen = "  
  112.                     + whichScreen + " delta = " + delta + " scrollX = "  
  113.                     + getScrollX());  
  114.             mScroller.startScroll(getScrollX(), 0, delta, 0,  
  115.                     Math.abs(delta) * 2);  
  116.             mCurScreen = whichScreen;  
  117.             invalidate();  
  118.         }  
  119.     }  
  120.   
  121.     /** 
  122.      * 用于拦截手势事件的,每个手势事件都会先调用这个方法。Layout里的onInterceptTouchEvent默认返回值是false, 
  123.      * 这样touch事件会传递到childview控件 ,如果返回false子控件可以响应,否则了控件不响应,这里主要是拦截子控件的响应, 
  124.      * 对ViewGroup不管返回值是什么都会执行onTouchEvent 
  125.      */  
  126.     @Override  
  127.     public boolean onInterceptTouchEvent(MotionEvent arg0) {  
  128.         // TODO Auto-generated method stub  
  129.         Log.d(TAG, "[BTViewPager->]onInterceptTouchEvent");  
  130.         final int action = arg0.getAction();  
  131.         final float x = arg0.getX();  
  132.         switch (action) {  
  133.         case MotionEvent.ACTION_DOWN:  
  134.             Log.d(TAG, "onInterceptTouchEvent---ACTION_DOWN ");  
  135.             mLastMotionX = x;  
  136.             break;  
  137.         case MotionEvent.ACTION_MOVE:  
  138.             Log.d(TAG, "onInterceptTouchEvent---ACTION_MOVE ");  
  139.             break;  
  140.         case MotionEvent.ACTION_UP:  
  141.             Log.d(TAG, "onInterceptTouchEvent---ACTION_UP ");  
  142.             break;  
  143.         default:  
  144.             break;  
  145.         }  
  146.         return super.onInterceptTouchEvent(arg0);  
  147.     }  
  148. }  
只要是在onTouchEvent的UP中处理滑动的条件

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. if (Math.abs(x - mLastMotionX) < MOVE_LIMITATION) {  
  2.                 // snapToDestination(); // 跳到指定页  
  3.                 snapToScreen(getCurrentItem());  
  4.                 return true;  
  5.             }  
只有滑动的距离大于100才进行上下页处理,否则就停在当前页,当前页使用getCurrentItem()获取, 有一点要注意在ViewPager中getChildCount()获取的值是错误的,不清楚是什么原因,在ViewGroup中是有效的,这个可能要查看ViewPager源码才能弄清楚是什么原因,有知道的朋友可以告知我!
完整Demo: http://download.csdn.net/detail/deng0zhaotai/7384637
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值