推荐阅读:
Android中的dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent()_Tiger的专栏-CSDN博客
面试之Android事件传递_Tiger的专栏-CSDN博客
【Android】onInterceptTouchEvent 方法收不到ACTION_MOVE事件_Tiger的专栏-CSDN博客
通过以上阅读可以了解事件传递的机制,及源码事件如何派发
1.瀑布流效果参考
2.嵌套滚动效果实现
以上是实现TabLayout+ViewPager,ViewPager嵌套Fragment,Fragment下RecyclerView嵌套RecyclerView瀑布流效果,今天我们主要说一下如何解决ViewPager嵌套RecyclerView,RecyclerView嵌套RecyclerView瀑布流事件冲突问题;
2.1外层RecyclerView(OutRecyclerView)
dispatchTouchEvent()处理ViewPager和RecyclerView事件冲突
- ViewPager嵌套RecyclerView,判断事件是否下发,若RecyclerView滚动顶部,则执行getParent().requestDisallowInterceptTouchEvent(false),ViewPager事件不再继续下发给RecyclerView
- 否则,getParent().requestDisallowInterceptTouchEvent(true),ViewPager事件下发给RecyclerView;
OutRecyclerView.java
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
//解决recyclerView和viewPager的滑动影响
if (isGoTop()){
if (mChangeRefreshListener != null){
//RecyclerView滚动了顶部,设置可以刷新 true
mChangeRefreshListener.updateRefreshStatus(true);
}
//设置父视图例如ViewPager拦截事件,不继续下发
getParent().requestDisallowInterceptTouchEvent(false);
} else {
//当滑动recyclerView时,告知父控件不要拦截事件,交给子view处理
getParent().requestDisallowInterceptTouchEvent(true);
}
return super.dispatchTouchEvent(ev);
}
//判断是否滚动到RecyclerView顶部
private boolean isGoTop(){
boolean isScrollTop = false;
LayoutManager layoutManager = getLayoutManager();
//瀑布流
if (layoutManager instanceof StaggeredGridLayoutManager){
int scrollPos[] = ((StaggeredGridLayoutManager)layoutManager).findFirstVisibleItemPositions(null);
//判断是否滚到了顶部
isScrollTop = !canScrollVertically(SCROLLING_UP) ||
(getChildAt(0).getY()==0f && scrollPos[0]==0);
//线性布局
} else if (layoutManager instanceof LinearLayoutManager){
int firstItemPosition = ((LinearLayoutManager)layoutManager).findFirstCompletelyVisibleItemPosition();
//判断是否滚到了顶部
isScrollTop = !canScrollVertically(SCROLLING_UP) ||
(getChildAt(0).getY()==0f && firstItemPosition==0);
}
return isScrollTop;
}
onInterceptTouchEvent()拦截事件处理