Android中RecycleView與ViewPager沖突的解決方法及原理
1.概述
在實際開發(fā)中,我們經常遇到需要在ListView或RecycleView頭部添加ViewPager實現Banner輪播效果,并需要添加下拉刷新,上拉加載功能。
但,橫向滑動ViewPager時,稍微偏移就會失去焦點。
2.解決方案
我們知道事件攔截的順序,父ViewGroup先接收到攔截,再傳遞給子ViewGroup 或子View。事件的處理順序是,子ViewGroup 或子View先處理,若子ViewGroup處理了,父ViewGroup就不用處理,若子ViewGroup未處理,則傳給父ViewGroup處理。
根據事件攔截原理,ViewPager和RecycleView相互沖突,RecycleView相當于父ViewGroup,ViewPager相當于子View,ViewPager和RecycleView相互沖突,將父View傳到ViewPager里面處理,重寫View Pager。使用父類方法requestDisallowInterceptTouchEvent(true) ,用來子View告訴父容器不要攔截我們的事件的。
(1)重寫ViewPager
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewGroup;
/**
* Developer:chunsoft on 2016/10/31 16:04
* Email:chun_soft@qq.com
* Content:viewPager和RecycleView相互沖突,將父View傳到ViewPager里面
* 使用父類方法requestDisallowInterceptTouchEvent(true)
* 用來子View告訴父容器不要攔截我們的事件的
*/
public class DecoratorViewPager extends ViewPager{
private ViewGroup parent;
public DecoratorViewPager(Context context) {
super(context);
}
public DecoratorViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setNestedpParent(ViewGroup parent) {
this.parent = parent;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (parent != null){
parent.requestDisallowInterceptTouchEvent(true);
}
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (parent != null){
parent.requestDisallowInterceptTouchEvent(true);
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (parent != null){
parent.requestDisallowInterceptTouchEvent(true);
}
return super.onTouchEvent(ev);
}
}
(2)在Activity中:
DecoratorViewPager mPager = (DecoratorViewPager) mHeaderView.findViewById(R.id.viewpager); mPager.setNestedpParent((ViewGroup) mPager.getParent());
(3)在布局文件中:
<com.chunsoft.baseframework.utils.view.DecoratorViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="180dp" />
處理ViewPager嵌套RecycleView卡頓問題
ViewPager里面添加了三個Fragment,Fragment里面添加了RecycleView,發(fā)現ViewPager左右滑動切換非常不流暢,存在滑動沖突,使用外部攔截進行處理 so easy~~~
/**
* Created by magic on 2017/6/12 0012.外部攔截處理ViewPager嵌套RecycleView左右滑動切換Fragment卡頓問題
*/
public class MyViewPager extends ViewPager {
float x, y;
public MyViewPager(Context context) {
super(context);
}
public MyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptHoverEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = event.getX();
y = event.getY();
return super.onInterceptHoverEvent(event);
case MotionEvent.ACTION_MOVE:
if (Math.abs(x - event.getX()) > Math.abs(y - event.getY()))
return true;
else return false;
case MotionEvent.ACTION_UP:
return super.onInterceptHoverEvent(event);
}
return super.onInterceptHoverEvent(event);
}
}
注意:ACTION_DOWN和ACTION_UP中不要直接返回false 而要返回super.onInterceptHoverEvent(event) ,因為ViewGroup中對事件攔截方法做了些基本處理。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關文章
Android使用JobScheduler定期推送本地通知實例代碼
本篇文章主要介紹了Android使用JobScheduler定期推送本地通知實例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06
在Android中通過Intent使用Bundle傳遞對象的使用方法
這篇文章主要介紹了在Android中通過Intent使用Bundle傳遞對象的使用方法,詳細介紹Intent使用Bundle傳遞對象的方法。有需要的可以了解一下。2016-11-11
ListView的Adapter使用 之 初學ArrayAdapter String
ListView是Android中經常會使用的東西,綁定數據對于初學者來說,尤其是剛接觸編程的人來說,往往會覺得很難理解,我上大二的時候學的java,但是基本上相當于沒有學,什么都沒寫過,真正接觸編程就是開始上手學android,把這些記錄下來,自己可以回頭看下,也可以讓新手更好的理解2013-06-06

