下拉刷新组件与WebView内部子可滚动div冲突问题

文章讲述了在Android的WebView中处理可滚动Div与下拉刷新冲突的方案。通过使用evaluateJavascript监听Div的scrollTop值来控制是否允许下拉刷新。对于没有id的React组件,如Picker,可以通过添加隐藏div并改变其高度来同步Android端的状态,从而决定是否可以下拉刷新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我的页面,分为2个div,2个div的高度加起来是100%占据整个webview页面。而最上面的div是一个可滚动的div(overflow: "auto")。往上滑动时没问题的,但是往下滑动就会出现问题 它会直接触发下拉刷新的问题
网上有如下解决方案,但是针对这个案例是无效的,因为本案例中webView.getScrollY始终为0(三个div构成了整个webview页面,自始至终这三个div位置是不会变化的,是固定的)

// 设置子视图是否允许滚动到顶部
    refreshLayout.setOnChildScrollUpCallback(new SwipeRefreshLayout.OnChildScrollUpCallback() {
       @Override
       public boolean canChildScrollUp(SwipeRefreshLayout parent, @Nullable View child) {
           return webView.getScrollY() > 0;
       }
    });

所以问题在于如何监听webview页面内子布局的滚动,以子布局的滚动来控制刷新动作。
可以利用webview的evaluateJavascript方法来监听特定元素,第一个参数script用于执行一段js脚本以获取指定元素的指定属性比如div的height,第二个参数resultCallback是一个回调函数,当取到第一个参数指定的属性时就会执行调用。

public void evaluateJavascript(String script, ValueCallback<String> resultCallback)

所以解决方案很明了了。只需要利用evaluateJavascript来监听可滚动的div的scrollTop值,当其为0时表示在顶端,此时下拉可以刷新。否则禁止下拉刷新。注意,这里需要和前端商量约定统一的要监听的元素的id,即下面的inner_scroll_box。

        wvContent?.setOnTouchListener { _, event ->
            when (event?.action) {
                MotionEvent.ACTION_MOVE -> {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                        wvContent?.evaluateJavascript(
                            "document.getElementById('inner_scroll_box').scrollTop"
                        ) { value ->
                            if (!TextUtils.isEmpty(value) && "null" != value) {
                                var doubleVa = value.toDoubleOrNull()
                                if (doubleVa != null) {
                                    if (doubleVa <= 0) {
                                        mWebviewScrollView?.setEnableRefresh(true);
                                    } else {
                                        mWebviewScrollView?.setEnableRefresh(false);
                                    }
                                }

                            }
                        };
                    }

                }
            }
            false
        }

对于没有id的React组件,比如antd mobile组件Picker,就需要添加一个隐藏的div,然后根据Picker的状态的改变来改变div的height,最后就可以在android端根据div的高度来决定是否可以下拉刷新了。

Picker

添加id为type_picker的隐藏div,在onVisibleChange中根据Picker列表的隐藏状态来改变div的高度。

<div>
                <Picker data={vms} cols={1} title={"资金类型"} value={this.state.value} extra={v2label[this.state.value]}
                    onChange={v => {if (v === this.state.value) {this.handleChange(v2type[v]);this.setState({ value: v })}}}
                    onVisibleChange={v => {if (v===true) {document.getElementById('type_picker').style.height="1px"} else {document.getElementById('type_picker').style.height="0px"}}}
                >
                    <CustomPickerButton/>
                </Picker>
                {/*添加此div是为了与android端进行特殊操作,让android端知道Picker隐藏状态*/}
                <div id={"type_picker"} style={{visibility: "none", height: 0}}></div>
            </div>

在android端根据id为type_picker的div的高度来决定是否可以下拉刷新。

webView.evaluateJavascript("document.getElementById(\"type_picker\").style.height", new ValueCallback<String>() {
                                @Override
                                public void onReceiveValue(String value) {
                                    if (!TextUtils.isEmpty(value) && !"null".equals(value)) {
                                        if (!"0px".equals(value.replace("\"", ""))) {
                                            refreshLayout.setEnabled(false);
                                        } else {
                                            refreshLayout.setEnabled(true);
                                        }
                                    }
                                }
                            });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值