问题描述:Android端WebView中使用了SwipeRefreshLayout下拉刷新,前端h5页面中使用了滚轮控件。当滚轮控件向下滑动时会触发下拉刷新事件,导致滚轮控件无法下拉。正常情况下,通过判断webView的offsetY=0来控制SwipeRefreshLayout是否可以刷新,但是当h5页面就是在offsetY = 0时调用滚轮控件,就会触发上述问题,解决办法如下:
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.webkit.WebView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
public class ScrollWebView extends WebView {
private boolean overScrolledY = false;
private float startY = 0f;
private boolean refreshEnable = false;
private boolean isPullDown = false;
public interface IScrollListener {
void refreshEnableChanged(boolean refreshEnable);//解决webView下拉刷新和h5滚轮控件滑动冲突的问题
}
private IScrollListener mScrollListener;
public void setOnScrollListener(IScrollListener listener) {
mScrollListener = listener;
}
public ScrollWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
if (clampedY){
overScrolledY = true;
}
}
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
//判断当前over scroll 方向
isPullDown = deltaY < 0;
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
startY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
float diffY = event.getY() - startY;
if (diffY < 0) {
overScrolledY = false;
refreshEnable = false;
}
if (overScrolledY && !refreshEnable && isPullDown) {
refreshEnable = true;
MotionEvent obtain = MotionEvent.obtain(event);
obtain.setAction(MotionEvent.ACTION_DOWN);
dispatchTouchEvent(obtain);
if (getParent() instanceof SwipeRefreshLayout) {
((SwipeRefreshLayout) getParent()).dispatchTouchEvent(obtain);
}
}
if (mScrollListener != null) {
mScrollListener.refreshEnableChanged(refreshEnable);
}
break;
}
return super.onTouchEvent(event);
}
}
调用如下:
webView.setOnScrollListener(refreshEnable -> {
swipeRefreshLayout.setEnabled(refreshEnable);
});
经过实际测试,基本满足实际交互需求