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()获取的值是错误的。
ViewPager的getChildCount不对,是因为Viewpager不是根据adapter的数据个数生成对应的数量的View,生成View的个数由setOffscreenPageLimit()指定,默认是生成两个,滑动时,将不可见的上一页destroy掉,新滑到的页通过Adpater的instantiateItem生成。

更多相关文章

  1. android之转化inputstream为list
  2. 仿微信滑动Tab框架
  3. Android(安卓)滑动验证的一种简单实现
  4. android手势滑动关闭当前activity
  5. 安卓控件注入
  6. Android(安卓)圆形头像
  7. ScrollView和EditText 滑动冲突的解决办法
  8. Android读取SeekBar数值方法
  9. android 端生成随机验证码 实现

随机推荐

  1. android 调用图库中选择的图片
  2. Android:theme="@android:style/Theme.Di
  3. 记一次趣头条 Android(安卓)面试经历!
  4. Android一分钟环境搭建,包含Mac、Linux、W
  5. 那两年炼就的Android内功修养
  6. 创建第一个Android(安卓)3 工程
  7. Android—Http连接之GET/POST请求
  8. Android(安卓)app——常见控件的使用方法
  9. Android重点
  10. Android之如何打开USB调试模式