思路
最近在項(xiàng)目中遇到這樣一個(gè)需求:某個(gè)頁面中有4個(gè)Fragment,使用的是viewpager實(shí)現(xiàn)的,在某個(gè)fragment中又有一個(gè)橫向滑動(dòng)的Recyclerview,當(dāng)時(shí)心想,這個(gè)需求也不難啊坠宴,咔咔一頓響需求實(shí)現(xiàn)了,結(jié)果發(fā)現(xiàn)橫向滑動(dòng)Recyclerview時(shí)直接觸發(fā)了外層ViewPager的滑動(dòng)绷旗,滑動(dòng)到下一個(gè)Fragment了喜鼓,直接懵逼了,劇情不是這樣的啊衔肢,然后一頓咔咔百度庄岖,發(fā)現(xiàn)還是有各種各樣的問題,沒辦法角骤,只能自己解決咯
代碼已經(jīng)上傳到github:project
步驟
1.自定view繼承RecyclerView 重寫dispatchTouchEvent
2.監(jiān)聽手指移動(dòng)方向 水平方向大于豎直方向 則禁止ViewPager的滑動(dòng) 否則開啟ViewPager的滑動(dòng)以上步驟就是整個(gè)功能的核心思想隅忿,也算是一個(gè)取巧吧!
核心代碼
重寫Recyclerview觸摸事件
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewParent;
import com.apkfuns.logutils.LogUtils;
import com.meetacg.widget.pager.NoScrollViewPager;
/**
* @author ganhuanhui
* 時(shí)間:2019/12/2 0002
* 描述:
*/
public class HorizontalRecyclerView extends RecyclerView {
private float x1;
private float y1;
private SwipeRefreshLayout mSwipeRefreshLayout;
public HorizontalRecyclerView(Context context) {
super(context);
}
public HorizontalRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public HorizontalRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
//解決recyclerView和viewPager的滑動(dòng)影響
//當(dāng)滑動(dòng)recyclerView時(shí)邦尊,告知父控件不要攔截事件硼控,交給子view處理
get(false);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//當(dāng)手指按下的時(shí)候
x1 = event.getX();
y1 = event.getY();
break;
case MotionEvent.ACTION_MOVE:
//當(dāng)手指移動(dòng)的時(shí)候
float x2 = event.getX();
float y2 = event.getY();
float offsetX = Math.abs(x2 - x1);
float offsetY = Math.abs(y2 - y1);
if (offsetX >= offsetY) {
get(true);//手指左移
} else {
get(false);
}
break;
case MotionEvent.ACTION_UP:
x1 = y1 = 0;
get(false);
break;
}
return super.dispatchTouchEvent(event);
}
private ViewParent mViewParent;
//使用迭代 直至找到parent是NoScrollViewPager為止
//效率有些低 偏low 莫見怪
private void get(boolean isEnable) {
if (mViewParent == null)
mViewParent = getParent();
else
mViewParent = mViewParent.getParent();
if (mViewParent instanceof NoScrollViewPager) {
//true 禁止ViewPager滑動(dòng),自動(dòng)交給recyclerview去滑動(dòng)
//false 交給ViewPager滑動(dòng)
NoScrollViewPager viewPager = (NoScrollViewPager) mViewParent;
viewPager.setNoScroll(isEnable);
} else {
get(isEnable);
}
}
}
//重寫ViewPager onTouchEvent onInterceptTouchEvent
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
/**
* @author ganhuanhui
* 時(shí)間:2019/12/17 0017
* 描述:可禁止滑動(dòng)的ViewPager
*/
public class NoScrollViewPager extends ViewPager {
// 是否禁止 viewpager 左右滑動(dòng)
private boolean noScroll = false;
public void setNoScroll(boolean noScroll){
this.noScroll = noScroll;
}
public NoScrollViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent arg0) {
if (noScroll){
return false;
}else{
return super.onTouchEvent(arg0);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
if (noScroll){
return false;
}else{
return super.onInterceptTouchEvent(arg0);
}
}
}
使用
把HorizontalRecyclerView當(dāng)做正常的Recyclerview使用即可
好了胳赌,大功告成,目前已經(jīng)用在項(xiàng)目中 暫無發(fā)現(xiàn)問題 如有發(fā)現(xiàn)問題的朋友 還請私聊告知