PullToRefreshListView中嵌套ViewPager滑動沖突的解決
最近恰好遇到PullToRefreshListView中需要嵌套ViewPager的情況,ViewPager 作為頭部添加到ListView中,發先ViewPager在滑動過程中流暢性太差幾乎很難左右滑動。在網上也看了很多大神的介紹,看了ViewPager的源碼。其實思路很簡單,只不過沒有看到有教完整的說明,為了幫轉像我這樣的green hand 少走彎路,將過程整理下。大神自動略過~_~:
滑動沖突的解決大概要處理的問題無非是事件分發,事件攔截,和事件的處理,關于這部分內容大家可以在網上查看相關的資料,基本原理比較容易理解。有了這部分內容做鋪墊。下面正式進入正題。
一 首先采取了給ViewPager設置監聽的方式
vPager.setOnPageChangeListener(new OnPageChangeListener() {@Overridepublic void onPageSelected(int arg0) {//該方法是ViewPager滑動結束后,頁面別選定后調用此方法/*在ViewPager滑動結束后需要通知父容器(ListView)可以* 對后續的事件進行適當的處理了(包括自身事件的攔截)*/lsv.requestDisallowInterceptTouchEvent(false);}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {//該方法是ViewPager滑動時調用此方法/*在ViewPager滑動時需要通知父容器(ListView)不要攔截,也就是說此事件交給ViewPager處理*/lsv.requestDisallowInterceptTouchEvent(true); }@Overridepublic 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);}@Overridepublic 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);} }
?