首先看布局
<com.scwang.smartrefresh.layout.SmartRefreshLayout android:id="@+id/refresh" android:layout_width="match_parent" android:layout_height="match_parent"> <com.scwang.smartrefresh.layout.header.ClassicsHeader android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/mainColor" /> <com.scwang.smartrefresh.layout.footer.ClassicsFooter android:layout_width="match_parent" android:layout_height="wrap_content" /> <android.support.v7.widget.RecyclerView android:id="@+id/search_result_lv" android:layout_width="match_parent" android:layout_height="match_parent" android:overScrollMode="never" /> </com.scwang.smartrefresh.layout.SmartRefreshLayout>
我这里是用了SmartRefreshLayout实现的上拉加载和下拉刷新
这些都没什么问题 当我在内部嵌套了recyclerview之后就发生了冲突首先是内部的recyclerview不能滑动
然后就重写了内部的recyclerview 代码入下:
package com.langteng.courtesy.customview; import android.content.Context; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.MotionEvent; //作者: 冯浩 on 2019/1/14 17:06 // _ooOoo_ // o8888888o // 88" . "88 // (| ^_^ |) // O\ = /O // ____/`---'\____ // .' \\| |// `. // / \\||| : |||// \ // / _||||| -:- |||||- \ // | | \\\ - /// | | // | \_| ''\---/'' | | // \ .-\__ `-` ___/-. / // ___`. .' /--.--\ `. . ___ // ."" '< `.___\_<|>_/___.' >'"". // | | : `- \`.;`\ _ /`;.`/ - ` : | | // \ \ `-. \_ __\ /__ _/ .-` / / // ========`-.____`-.___\_____/___.-`____.-'======== // `=---=' // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // 佛祖保佑 永无BUG 永不修改 // 程序员之歌 作者:冯浩(字:德明) // 十年生死两茫茫 ,写程序,到天亮。 // 千行代码 ,Bug何处藏 ? // 纵使上线又怎样 ,朝令改 ,夕断肠。 // // 领导每天新想法 ,日日改 ,夜夜忙。 // 相顾无言 ,唯有泪千行。 // 每晚灯火阑珊处 ,夜难寐 ,加班狂。 // ************************************************************************************************ public class NestRecyclerView extends RecyclerView { private int lastVisibleItemPosition; private int firstVisibleItemPosition; private float mLastY = 0;// 记录上次Y位置 private boolean isTopToBottom = false; private boolean isBottomToTop = false; public NestRecyclerView(Context context) { this(context, null); } public NestRecyclerView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public NestRecyclerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: getParent().requestDisallowInterceptTouchEvent(false); break; } return super.onInterceptTouchEvent(ev); } //@Override //public boolean onTouchEvent(MotionEvent event) { // int action = event.getAction(); // switch (action) { // case MotionEvent.ACTION_DOWN: // mLastY = event.getY(); // //不允许父View拦截事件 // getParent().requestDisallowInterceptTouchEvent(true); // break; // case MotionEvent.ACTION_MOVE: // float nowY = event.getY(); // isIntercept(nowY); // if (isBottomToTop||isTopToBottom){ // getParent().requestDisallowInterceptTouchEvent(false); // return false; // }else{ // getParent().requestDisallowInterceptTouchEvent(true); // } // mLastY = nowY; // break; // case MotionEvent.ACTION_UP: // case MotionEvent.ACTION_CANCEL: // getParent().requestDisallowInterceptTouchEvent(false); // break; // } // return super.onTouchEvent(event); // } private void isIntercept(float nowY){ isTopToBottom = false; isBottomToTop = false; RecyclerView.LayoutManager layoutManager = getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { //得到当前界面,最后一个子视图对应的position lastVisibleItemPosition = ((GridLayoutManager) layoutManager) .findLastVisibleItemPosition(); //得到当前界面,第一个子视图的position firstVisibleItemPosition = ((GridLayoutManager) layoutManager) .findFirstVisibleItemPosition(); } //得到当前界面可见数据的大小 int visibleItemCount = layoutManager.getChildCount(); //得到RecyclerView对应所有数据的大小 int totalItemCount = layoutManager.getItemCount(); if (visibleItemCount>0) { if (lastVisibleItemPosition == totalItemCount - 1) { //最后视图对应的position等于总数-1时,说明上一次滑动结束时,触底了 if (NestRecyclerView.this.canScrollVertically(-1) && nowY < mLastY) { // 不能向上滑动 isBottomToTop = true; } else { } } else if (firstVisibleItemPosition == 0) { //第一个视图的position等于0,说明上一次滑动结束时,触顶了 if (NestRecyclerView.this.canScrollVertically(1) && nowY > mLastY) { // 不能向下滑动 isTopToBottom = true; } else { } } } } }
嵌套滑动冲突解决,但是出现了一个问题,内部的recyclerview的滑动和上拉加载下拉刷新冲突了
(外部recyclerview的第一个条目中的子recycletview是不可以向下滑动的因为和外部的下拉刷新冲突了 外部的recyclerview的最后一个条目中的子recyclerview是不能向上滑动的 因为和外部的上拉加载冲突了,其他位置的条目不存啊此类bug 如果只有一个条目则向上向下都不能刷新)
最后想到解决思路当内部的recyclerview触摸事件
MotionEvent.ACTION_DOWN 时 让下拉刷新和下拉加载失效
e.getAction()== MotionEvent.ACTION_UP||e.getAction()==MotionEvent.ACTION_CANCEL时
让下拉刷新和下拉加载恢复
代码如下
recyclerview.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() { @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { // rv.getParent().requestDisallowInterceptTouchEvent(true); if (e.getAction()== MotionEvent.ACTION_DOWN) { refresh.setEnableRefresh(false); refresh.setEnableLoadMore(false); } if (e.getAction()== MotionEvent.ACTION_UP||e.getAction()==MotionEvent.ACTION_CANCEL) { refresh.setEnableRefresh(true); refresh.setEnableLoadMore(true); } return false; } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) { } @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { } });