Android ViewPager和ScrollView嵌套滾動問題解決方案

問題描述:java

  1. 個人嵌套是ViewPager-->ScrollView-->ViewPager.android


  2. 首先最裏面的ViewPager水平滾動時老是會觸發最外層的ViewPager滾動,看了網上不少的解決辦法基本上是同樣的,須要自定義ViewPager。ide

import android.content.Context;
import android.graphics.PointF;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;

/**
 * 自定義ViewPager,解決ViewPagger嵌套使用時不滑動問題。
 * Created by Administrator on 2015/4/20.
 */
public class HorizontalInnerViewPager extends ViewPager {
    /** 觸摸時按下的點 **/
    PointF downP = new PointF();
    /** 觸摸時當前的點 **/
    PointF curP = new PointF();


    public HorizontalInnerViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        mGestureDetector = new GestureDetector(context, new XScrollDetector());
    }
    public HorizontalInnerViewPager(Context context) {
        super(context);

        mGestureDetector = new GestureDetector(context, new XScrollDetector());
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev);//default
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        //每次進行onTouch事件都記錄當前的按下的座標
        curP.x = ev.getX();
        curP.y = ev.getY();

        if(ev.getAction() == MotionEvent.ACTION_DOWN){
            //記錄按下時候的座標
            //切記不可用 downP = curP ,這樣在改變curP的時候,downP也會改變
            downP.x = ev.getX();
            downP.y = ev.getY();
            //此句代碼是爲了通知他的父ViewPager如今進行的是本控件的操做,不要對個人操做進行干擾
            getParent().requestDisallowInterceptTouchEvent(true);
        }

        if(ev.getAction() == MotionEvent.ACTION_MOVE){
            //此句代碼是爲了通知他的父ViewPager如今進行的是本控件的操做,不要對個人操做進行干擾
                getParent().requestDisallowInterceptTouchEvent(true);
        }

        return super.onTouchEvent(ev);
    }

}


3.解決了上面的問題,又出現了新的問題,當最裏面的ViewPager垂直滾動時外層的ScrollView並不會滾動,解決方法以下:spa

import android.content.Context;
import android.graphics.PointF;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;

/**
 * 自定義ViewPager,解決ViewPagger嵌套使用時不滑動問題。
 * Created by Administrator on 2015/4/20.
 */
public class HorizontalInnerViewPager extends ViewPager {
    /** 觸摸時按下的點 **/
    PointF downP = new PointF();
    /** 觸摸時當前的點 **/
    PointF curP = new PointF();

    /** 自定義手勢**/
    private GestureDetector mGestureDetector;

    public HorizontalInnerViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        mGestureDetector = new GestureDetector(context, new XScrollDetector());
    }
    public HorizontalInnerViewPager(Context context) {
        super(context);

        mGestureDetector = new GestureDetector(context, new XScrollDetector());
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev);//default
        //當攔截觸摸事件到達此位置的時候,返回true,
        //說明將onTouch攔截在此控件,進而執行此控件的onTouchEvent
//        return true;
        //接近水平滑動時子控件處理該事件,不然交給父控件處理
//        return mGestureDetector.onTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        //每次進行onTouch事件都記錄當前的按下的座標
        curP.x = ev.getX();
        curP.y = ev.getY();

        if(ev.getAction() == MotionEvent.ACTION_DOWN){
            //記錄按下時候的座標
            //切記不可用 downP = curP ,這樣在改變curP的時候,downP也會改變
            downP.x = ev.getX();
            downP.y = ev.getY();
            //此句代碼是爲了通知他的父ViewPager如今進行的是本控件的操做,不要對個人操做進行干擾
            getParent().requestDisallowInterceptTouchEvent(true);
        }

        if(ev.getAction() == MotionEvent.ACTION_MOVE){
            float distanceX = curP.x - downP.x;
            float distanceY = curP.y - downP.y;
            //接近水平滑動,ViewPager控件捕獲手勢,水平滾動
            if(Math.abs(distanceX) > Math.abs(distanceY)){
                //此句代碼是爲了通知他的父ViewPager如今進行的是本控件的操做,不要對個人操做進行干擾
                getParent().requestDisallowInterceptTouchEvent(true);
            }else{
                //接近垂直滑動,交給父控件處理
                getParent().requestDisallowInterceptTouchEvent(false);
            }
        }

        return super.onTouchEvent(ev);
    }

    private class XScrollDetector extends GestureDetector.SimpleOnGestureListener{
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//            return super.onScroll(e1, e2, distanceX, distanceY);

            //接近水平滑動時子控件處理該事件,不然交給父控件處理
            return (Math.abs(distanceX) > Math.abs(distanceY));
        }
    }

}
相關文章
相關標籤/搜索