首先看布局
<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) {
}
});
本文详细介绍了在使用SmartRefreshLayout实现上拉加载和下拉刷新功能时,如何解决内部嵌套RecyclerView滑动冲突的问题。通过重写内部RecyclerView的触摸事件处理逻辑,确保内外部滑动操作不会相互干扰。
1754

被折叠的 条评论
为什么被折叠?



