1. 程式人生 > >PullToRefreshListView中嵌套ViewPager滑動沖突的解決

PullToRefreshListView中嵌套ViewPager滑動沖突的解決

import lstat 也看 alt ref tor and target down

PullToRefreshListView中嵌套ViewPager滑動沖突的解決

最近恰好遇到PullToRefreshListView中需要嵌套ViewPager的情況,ViewPager 作為頭部添加到ListView中,發先ViewPager在滑動過程中流暢性太差幾乎很難左右滑動。在網上也看了很多大神的介紹,看了ViewPager的源碼。其實思路很簡單,只不過沒有看到有教完整的說明,為了幫轉像我這樣的green hand 少走彎路,將過程整理下。大神自動略過~_~:

滑動沖突的解決大概要處理的問題無非是事件分發,事件攔截,和事件的處理,關於這部分內容大家可以在網上查看相關的資料,基本原理比較容易理解。有了這部分內容做鋪墊。下面正式進入正題。

解決這個問題有兩種實現方式

一 首先采取了給ViewPager設置監聽的方式

vPager.setOnPageChangeListener(new OnPageChangeListener() {
            @Override
            public void onPageSelected(int arg0) {
                //該方法是ViewPager滑動結束後,頁面別選定後調用此方法
                /*在ViewPager滑動結束後需要通知父容器(ListView)可以
                 * 對後續的事件進行適當的處理了(包括自身事件的攔截)
*/ lsv.requestDisallowInterceptTouchEvent(false); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { //該方法是ViewPager滑動時調用此方法 /*在ViewPager滑動時需要通知父容器(ListView)不要攔截, 也就是說此事件交給ViewPager處理
*/ lsv.requestDisallowInterceptTouchEvent(true); } @Override public void onPageScrollStateChanged(int arg0) { //該方法是ViewPager滑動狀態發生變化時調用此方法 //這裏暫時不要進行相關的操作。 } });



這種方式可以解決ViewPager左右滑動與listView的沖突問題,但是會有一個問題,此時在VIewPager上的下拉事件也被ViewPager接收,只能在ViewPager下邊下拉才能實現PullToRefreshListView 的下拉刷新效果。

技術分享

如果不需要下拉刷新,普通的ListView 通過上面的方式完全可以達到預期的效果

二 重寫ViewPager的disPatchTouchEvent方法

基本思路就是要重寫ViewPager的disPatchTouchEvent方法,通過比較x、y軸的移動距離,決定事件是否自己進行處理。

package com.ccq.tuangou.myview;

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

public class MyViewPager extends ViewPager {
    float mDownX;
    float mDownY;
    public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            //DOWN 事件的時候記錄下當前的xy左標
            mDownX=ev.getX();
            mDownY=ev.getY();
            getParent().requestDisallowInterceptTouchEvent(true);
            break;
        case MotionEvent.ACTION_MOVE:
            /*MOVE 事件後計算x軸y軸的移動距離 ,如果x軸移動距離大於y軸,
            那麽該事件有ViewPager處理,否則交給父容器處理*/
            if(Math.abs(ev.getX()-mDownX)>Math.abs(ev.getY()-mDownY)){
                getParent().requestDisallowInterceptTouchEvent(true);
            }else{
                getParent().requestDisallowInterceptTouchEvent(false);
            }
            break;
        case MotionEvent.ACTION_CANCEL:
            getParent().requestDisallowInterceptTouchEvent(false);
            break;
        default:
            break;
        }
        return super.dispatchTouchEvent(ev);
    }
}

PullToRefreshListView中嵌套ViewPager滑動沖突的解決