一、使用recyclerview.scrollToPosition(index)滑动布局,结果定位不准确

解决办法:

//使用LayoutManager滑动位置并设置offset为0,可以保证滑动的位置正确

mLayoutManager.scrollToPositionWithOffset(index, 0);

二、区分手动滑动和代码滑动

/**

* @author : zhn

* @date : 2022/7/1 18:02

* description :滑动监听,判断是不是用户自己手动滑动

*/

public class ScrollListenerRecyclerView extends RecyclerView {

//用户触发的滑动含filling状态

private boolean userScroll;

//用户拖动

private boolean userTouch;

public ScrollListenerRecyclerView(@NonNull Context context) {

super(context);

}

public ScrollListenerRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

}

public ScrollListenerRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

}

@Override

protected void onScrollChanged(int l, int t, int oldl, int oldt) {

super.onScrollChanged(l, t, oldl, oldt);

if (mListener != null) {

mListener.onScrollChanged(userScroll, l, t, oldl, oldt);

}

}

@Override

public void onScrollStateChanged(int state) {

super.onScrollStateChanged(state);

if (state == SCROLL_STATE_IDLE && !userTouch) {

userScroll = false;

}

}

@Override

public boolean onTouchEvent(MotionEvent e) {

if (e.getAction() == MotionEvent.ACTION_MOVE) {

userTouch = true;

userScroll = true;

} else if (e.getAction() == MotionEvent.ACTION_UP) {

userTouch = false;

}

return super.onTouchEvent(e);

}

public interface ScrollChangeListener {

void onScrollChanged(boolean fromUser, int l, int t, int oldl, int oldt);

}

private ScrollChangeListener mListener;

public void setListener(ScrollChangeListener listener) {

mListener = listener;

}

}

用法:

mBinding.rlvCourseDetail.setListener(new ScrollListenerRecyclerView.ScrollChangeListener() {

@Override

public void onScrollChanged(boolean fromUser, int l, int t, int oldl, int oldt) {

if (fromUser) {

scrollSwitchTab();

}

}

});

三、RecyclerView嵌套WebView滑动冲突解决

 原则上WebView不应该作为RecyclerView中的一个Item,因为会有滑动冲突。如果有这样的需求必须这么处理,那么就需要解决滑动冲突了,以竖直方向上的普通列表为例。

3.1 竖直方向上滑动冲突解决

一般方案是,让webView在竖直方向上不能滑动,通过js跟原生交互,动态设置Webview的高度正好是内容的高度。

3.2 水平方向上的滑动冲突解决

水平方向和RecycleView滑动方向不同,所以原则上我们应该允许webView水平滑动,但是实际操作中会发现水平滑动十分不流畅,原因是水平滑动事件有时被RecyclerView处理了。为了解决这个问题,我们让水平滑动时RecyclerView始终不处理touch事件。

private float startX;

private float startY;

private float offsetX;

private float offsetY;

webView.setOnTouchListener(new OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

//父布局(RecyclerView)不消费点击事件

getParent().requestDisallowInterceptTouchEvent(true);

startX = event.getX();

startY = event.getY();

break;

case MotionEvent.ACTION_MOVE:

offsetX = Math.abs(event.getX() - startX);

offsetY = Math.abs(event.getY() - startY);

if (offsetX > offsetY) {

//父布局(RecyclerView)不消费水平滑动事件

getParent().requestDisallowInterceptTouchEvent(true);

} else {

//竖直方向上的滑动事件,正常分发

getParent().requestDisallowInterceptTouchEvent(false);

}

break;

default:

break;

}

return false;

}

});

四、RecyclerView以WebView作为item时,列表位置跳动

原因是webview焦点变化,导致RecyclerView默认定位到焦点位置了。可以设置webview不获取焦点。

webView.setFocusable(enabled);

好文链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: