Android 解决WebView下拉刷新SwipeRefreshLayout与H5滚轮控件滑动冲突问题

问题描述: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);
        });

经过实际测试,基本满足实际交互需求

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容