You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwipeRefreshLayout嵌套WebView无法向下滚动、误触发刷新及Odoo适配问题

问题根源

你遇到的冲突核心是SwipeRefreshLayout的下拉手势和WebView滚动手势的判定逻辑不兼容,Odoo站点失效是因为Odoo前端采用内部独立div做滚动容器,WebView本身的scrollY始终为0,导致你原来的滚动监听逻辑完全失效。


可直接生效的修复步骤

1. 修正现有代码的语法&逻辑错误

你修改后的代码存在三处基础错误,先修复:

  • onStart、onStop方法写在了onCreate方法内部,需移出到类的同级作用域
  • 重复添加了两次OnScrollChangedListener,删掉多余的添加代码
  • 滚动判定逻辑错误,mWebView.getScrollY() == -1的判断无实际意义,替换为系统提供的滚动能力判定方法canScrollVertically

2. 自定义SwipeRefreshLayout适配WebView内部滚动

自定义SwipeRefreshLayout重写触摸拦截逻辑,直接判定WebView是否真的滚动到顶部,无需额外监听滚动事件:

public class CustomSwipeRefreshLayout extends SwipeRefreshLayout {
    private WebView mWebView;

    public CustomSwipeRefreshLayout(@NonNull Context context) {
        super(context);
    }

    public CustomSwipeRefreshLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public void setWebView(WebView webView) {
        mWebView = webView;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (mWebView != null && mWebView.canScrollVertically(-1)) {
            // WebView还能向上滚动,不拦截手势
            return false;
        }
        return super.onInterceptTouchEvent(ev);
    }
}

3. 修改布局文件

将布局中的androidx.swiperefreshlayout.widget.SwipeRefreshLayout替换为你自定义的CustomSwipeRefreshLayout(注意替换成你自己的完整包名):

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <!-- 替换为自定义的SwipeRefreshLayout -->
    <com.yourpackage.CustomSwipeRefreshLayout
        android:id="@+id/swipe"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <WebView
            android:id="@+id/activity_main_webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </com.yourpackage.CustomSwipeRefreshLayout>
</LinearLayout>

4. 调整Activity初始化逻辑

删除原来的滚动监听代码,在初始化时给自定义的刷新布局绑定WebView,同时补充Odoo站点必需的WebView配置:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mWebView = findViewById(R.id.activity_main_webview);
    swipeRefreshLayout = findViewById(R.id.swipe);
    // 绑定WebView到自定义刷新布局
    swipeRefreshLayout.setWebView(mWebView);

    WebSettings webSettings = mWebView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    // Odoo站点必需的配置
    webSettings.setDomStorageEnabled(true);
    webSettings.setUseWideViewPort(true);
    webSettings.setLoadWithOverviewMode(true);

    mWebView.setWebViewClient(new MyWebViewClient());
    mWebView.loadUrl("https://hkmu.comercio.co.id");

    // 保留你原来的刷新逻辑即可,无需再做滚动监听
    swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            swipeRefreshLayout.setRefreshing(true);
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    swipeRefreshLayout.setRefreshing(false);
                    mWebView.reload();
                }
            }, 2000);
        }
    });
    swipeRefreshLayout.setColorSchemeColors(
            getResources().getColor(android.R.color.holo_blue_dark),
            getResources().getColor(android.R.color.holo_orange_dark),
            getResources().getColor(android.R.color.holo_green_dark),
            getResources().getColor(android.R.color.holo_red_dark)
    );
}

极端场景适配

如果上述方案仍然失效,说明Odoo站点的滚动逻辑做了特殊处理,可通过JS注入的方式获取页面真实滚动状态:

  1. 给WebView添加JS接口,接收页面滚动状态
  2. 在WebViewClient的onPageFinished方法中注入JS,监听页面滚动容器的滚动事件,滚动到顶部时通知原生端开启刷新,否则关闭。

内容的提问来源于stack exchange,提问作者Mangetsu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:06:03