k***@163.com
k***@163.com
  • 发布:2021-12-28 22:58
  • 更新:2021-12-28 22:58
  • 阅读:729

如何禁用X5内核浏览器的竖直滑块?

分类:uni-app

使用X5内核浏览器时,x5内核渲染页面的滚动条,会随着页面内容的长短显示滚动滑块。关于如何禁用滚动滑块,找了一天没找到解决方法,最后在腾讯浏览服务中心的文档(https://x5.tencent.com/docs/webview.html)中查看到可以禁用滚动滑块的接口:

//竖直快速滑块,设置null可去除  
mWebview.getX5WebViewExtension().setVerticalTrackDrawable (Drawable drawable)

但是mWebview是个全限定名为 com.tencent.smtt.sdk.WebView 的 java对象,想要在js中调用java方法setVerticalTrackDrawable,有两个方案:方案一、使用Native.js;方案二、自己写个uniapp原生插件

首先尝试了方案一,但最终失败。方案一的js代码如下:

失败原因是使用x5内核时,无法使用plus api获取到webview的nativeInstanceObject对象。这个应该是一个bug。

    var pages = getCurrentPages();    
    var page = pages[pages.length - 1];    

    var wv1 = page.$getAppWebview();  

    console.log('$getAppWebview', wv1)  
    // 尝试拿到webview的原生对象  
    let mWebView = wv1.nativeInstanceObject();    

    // 当不使用x5内核时 mWebView 可以获取到值,当使用x5内核时 mWebView 总是为 null  
    console.log('mWebView', mWebView)  
    var clazz = plus.android.invoke(mWebView, 'getClass')  
    console.log('mWebView class', clazz);  
    var name = plus.android.invoke(clazz, 'getName')  
    console.log('mWebView class name', name);  
    console.log('invoke getX5WebViewExtension')  
    var extension = plus.android.invoke(mWebView, 'getX5WebViewExtension')  
    console.log('getX5WebViewExtension result:', extension)  
    if (extension != null) {  
        plus.android.invoke(mWebView, 'setVerticalTrackDrawable', null)  
        console.log('invoke setVerticalTrackDrawable success')  
    }

目前暂时有效的方法:方案二

方案二,目前仅配适了安卓。关于如何自定义原生插件,见:https://nativesupport.dcloud.net.cn/NativePlugin/course/android
自定义的原生插件,java代码如下:

package io.dcloud.uniplugin;  

import android.util.Log;  
import android.view.View;  
import android.view.ViewGroup;  

import com.alibaba.fastjson.JSONObject;  
import com.taobao.weex.WXSDKInstance;  
import com.tencent.smtt.export.external.extension.interfaces.IX5WebViewExtension;  

import java.util.HashSet;  
import java.util.LinkedList;  
import java.util.Set;  

import io.dcloud.common.DHInterface.IApp;  
import io.dcloud.common.DHInterface.IWebAppRootView;  
import io.dcloud.common.DHInterface.IWebview;  
import io.dcloud.feature.uniapp.annotation.UniJSMethod;  
import io.dcloud.feature.uniapp.bridge.UniJSCallback;  
import io.dcloud.feature.uniapp.common.UniModule;  
import io.dcloud.feature.weex.WeexInstanceMgr;  
import io.dcloud.feature.x5.X5WebView;  

public class X5Util extends UniModule {  
    private final static String TAG = "X5Util";  

    //run ui thread  
    @UniJSMethod(uiThread = true)  
    public void disableVerticalTrack2(JSONObject options, UniJSCallback callback) {  
        JSONObject jsonObject = this.disableVerticalTrack();  
        callback.invoke(jsonObject);  
    }  

    /**  
     * {@link io.dcloud.feature.weex.extend.PlusModule#exec(String, String)}  
     * @return  
     */  
    //run JS thread  
    @UniJSMethod (uiThread = false)  
    public JSONObject disableVerticalTrack(){  
        JSONObject data = new JSONObject();  
        data.put("code", "error");  
        try {  
            WXSDKInstance instance = this.mWXSDKInstance;  
            if (instance != null && instance.isDestroy()) {  
                // ignore  
                return data;  
            } else {  
                IWebview hostWebview = WeexInstanceMgr.self().findWebview(instance);  
                IApp iApp = hostWebview.obtainApp();  
                if (iApp != null) {  
                    IWebAppRootView iWebAppRootView = iApp.obtainWebAppRootView();  
                    View view = iWebAppRootView.obtainMainView();  
                    if (view instanceof ViewGroup) {  
                        ViewGroup vg = (ViewGroup) view;  
                        Set<X5WebView> set = new HashSet<>();  
                        getChildViewGroup(vg, set);  

                        for (X5WebView iWebview : set) {  
                            disableVerticalTrackDrawable(iWebview, data);  
                        }  
                    }  
                }  
            }  
        } catch (Exception e) {  
            Log.e(TAG, "disableVerticalTrack exception: ", e);  
        }  

        return data;  
    }  

    void disableVerticalTrackDrawable(X5WebView x5, JSONObject data) {  
        IX5WebViewExtension x5WebViewExtension = x5.getX5WebViewExtension();  
        if (x5WebViewExtension != null) {  
            x5WebViewExtension.setVerticalTrackDrawable(null);  
            data.put("code", "success");  
        }  
    }  
    void getChildViewGroup(ViewGroup vg, Set<X5WebView> dist) {  
        LinkedList<ViewGroup> list = new LinkedList<>();  
        list.add(vg);  

        while (!list.isEmpty()) {  
            vg = list.removeFirst();  
            int childCount = vg.getChildCount();  
            for (int i = 0; i < childCount; i++) {  
                View childAt = vg.getChildAt(i);  
                if (childAt instanceof X5WebView) {  
                    dist.add((X5WebView)childAt);  
                } else if (childAt instanceof ViewGroup) {  
                    list.addLast((ViewGroup) childAt);  
                }  
            }  
        }  
    }  
}

在js中调用:

    // #ifdef APP-PLUS  
    //禁用滑动按钮,这个插件会遍历所有view对象,找到X5WebView,然后禁用竖直快速滑块  
    const X5Util = uni.requireNativePlugin('X5Util')  
    X5Util.disableVerticalTrack()  
    // #endif

因为没有找到如何准确地获取当前页面webview对象(也就是X5WebView对象实例), 所以想了个笨办法:遍历IWebAppRootView对象的所有子孙view然后禁用竖直滑块。存在的问题有:1. 遍历查询存在性能问题; 2. 禁用的是所有的X5WebView的竖直滑块。

如果哪位大神知道如何准确地获取X5WebView请告知一下,这样就可以解决上述两个问题了。

0 关注 分享

要回复文章请先登录注册