WebView hides soft keyboard during loadUrl(), which means a keyboard cannot stay open while calling javascript

后端 未结 3 1385
星月不相逢
星月不相逢 2020-12-14 03:06

Since the way you call javascript on a WebView is through loadUrl(\"javascript: ... \"); The keyboard cannot stay open.

The loadUrl() method calls loadUrlImpl() , wh

3条回答
  •  再見小時候
    2020-12-14 04:03

    I could implement cottonBallPaws's idea to use the internals of WebView with reflection, and got it to work for my 4.2 device. There are gracious fallbacks for Android versions older than KitKat.

    The code is written in Xamarin, but it should be easily adaptable to native Java code.

    /// 
    /// Executes a JavaScript on an Android WebView. This method offers fallbacks for older
    /// Android versions, to avoid closing of the soft keyboard when executing JavaScript.
    /// 
    /// The WebView to run the JavaScript.
    /// The JavaScript code.
    private static void ExecuteJavaScript(Android.Webkit.WebView webView, string script)
    {
        if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat)
        {
            // Best way for Android level 19 and above
            webView.EvaluateJavascript(script, null);
        }
        else
        {
            try
            {
                // Try to do with reflection
                CompatExecuteJavaScript(webView, script);
            }
            catch (Exception)
            {
                // Fallback to old way, which closes any open soft keyboard
                webView.LoadUrl("javascript:" + script);
            }
        }
    }
    
    private static void CompatExecuteJavaScript(Android.Webkit.WebView androidWebView, string script)
    {
        Java.Lang.Class webViewClass = Java.Lang.Class.FromType(typeof(Android.Webkit.WebView));
        Java.Lang.Reflect.Field providerField = webViewClass.GetDeclaredField("mProvider");
        providerField.Accessible = true;
        Java.Lang.Object webViewProvider = providerField.Get(androidWebView);
    
        Java.Lang.Reflect.Field webViewCoreField = webViewProvider.Class.GetDeclaredField("mWebViewCore");
        webViewCoreField.Accessible = true;
        Java.Lang.Object mWebViewCore = webViewCoreField.Get(webViewProvider);
    
        Java.Lang.Reflect.Method sendMessageMethod = mWebViewCore.Class.GetDeclaredMethod(
            "sendMessage", Java.Lang.Class.FromType(typeof(Message)));
        sendMessageMethod.Accessible = true;
    
        Java.Lang.String javaScript = new Java.Lang.String(script);
        Message javaScriptCodeMsg = Message.Obtain(null, 194, javaScript);
        sendMessageMethod.Invoke(mWebViewCore, javaScriptCodeMsg);
    }
    

提交回复
热议问题