的WebView使用loadURL(),这意味着键盘不能继续开放,同时调用javascript的过程中隐藏软键盘 [英] WebView hides soft keyboard during loadUrl(), which means a keyboard cannot stay open while calling javascript

查看:574
本文介绍了的WebView使用loadURL(),这意味着键盘不能继续开放,同时调用javascript的过程中隐藏软键盘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

既然你调用JavaScript在web视图的方式是通过使用loadURL(JavaScript的:......);该键盘不能停留开放。

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

的<一个href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.0.3_r1/android/webkit/WebView.java#WebView.loadUrl%28java.lang.String%29">loadUrl()方法调用<一个href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.0.3_r1/android/webkit/WebView.java#WebView.loadUrlImpl%28java.lang.String,java.util.Map%29">loadUrlImpl() ,它调用一个方法称为<一个href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.0.3_r1/android/webkit/WebView.java#WebView.clearHelpers%28%29">clearHelpers()然后调用<一个href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.0.3_r1/android/webkit/WebView.java#WebView.clearTextEntry%28%29">clearTextEntry(),然后调用<一个href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.0.3_r1/android/webkit/WebView.java#WebView.hideSoftKeyboard%28%29">hideSoftKeyboard()然后我们变得是如此的寂寞键盘消失。

The loadUrl() method calls loadUrlImpl() , which calls a method called clearHelpers() which then calls clearTextEntry(), which then calls hideSoftKeyboard() and then we become oh so lonely as the keyboard goes away.

据我可以看到所有这些都是私人的,不能被重写。

As far as I can see all of those are private and cannot be overridden.

有没有人找到了一个解决方法吗?有没有办法强制键盘保持打开状态,或者直接调用JavaScript,而无需通过使用loadURL()?

Has anyone found a workaround for this? Is there a way to force the keyboard to stay open or to call the javascript directly without going through loadUrl()?

反正有被称为覆盖的WebView的方式,以prevent(私有方法)clearTextEntry()?

Is there anyway to override the WebView in a way to prevent (the private method) clearTextEntry() from being called?

推荐答案

更新

奇巧增加了一个公共的方法直接调用的javascript:<一href="http://developer.android.com/reference/android/webkit/WebView.html#evaluateJavascript%28java.lang.String,%20android.webkit.ValueCallback%3Cjava.lang.String%3E%29">evaluateJavascript()

KitKat added a public method for invoking javascript directly: evaluateJavascript()

对于较旧的API,您可以尝试像下面一个解决方案,但如果我这样做,我再次想看看刚刚构建的奇巧使用上述方法的兼容性方法和旧设备,使用反射来深入一个内部私有方法:<一href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.0.4_r2.1/android/webkit/BrowserFrame.java#BrowserFrame.stringByEvaluatingJavaScriptFromString%28java.lang.String%29">BrowserFrame.stringByEvaluatingJavaScriptFromString()

For older apis, you could try a solution like below, but if I had to do this again I'd look at just building an compatibility method that on KitKat uses the above method and on older devices, uses reflection to drill down to a inner private method: BrowserFrame.stringByEvaluatingJavaScriptFromString()

然后,你可以调用JavaScript直接,而不必处理与使用loadURL并加入的javascript:到脚本

Then you could call javascript directly without having to deal with loadUrl and adding "javascript: " to the script.

旧答案

所要求的阿洛克库尔卡尼,我给了一个可能的解决方法我为此想了个粗略的概貌。我还没有真正尝试过,但在理论上它应该工作。这code将是粗糙,只是作为一个例子。

As requested by Alok Kulkarni, I'll give a rough overview of a possible workaround I thought of for this. I haven't actually tried it but in theory it should work. This code is going to be rough and is just to serve as an example.

而不是通过使用loadURL()发出的呼吁下,你排队你的JavaScript调用,然后让JavaScript的拉下来。有些东西,如:

Instead of sending the calls down through loadUrl(), you queue your javascript calls and then have javascript pull them down. Some thing like:

private final Object LOCK = new Object();
private StringBuilder mPendingJS;

public void execJS(String js) {
    synchronized(LOCK) {
        if (mPendingJS == null) {
            mPendingJS = new StringBuilder();
            mPendingJS.append("javascript: ");
        }
        mPendingJS
            .append(js)
            .append("; ");
    }
}

而不是调用使用loadURL的

()调用该方法。 (为了使这个简单的我用一个synchronized块,但这可能更适合于不同的路线。由于Javascript在自己的线程中运行,这将需要是线程安全的一些这样或那样)。

Instead of calling loadUrl() call that method. (For making this simple I used a synchronized block, but this might be better suited to a different route. Since javascript runs on its own thread, this will need to be thread safe in some way or another).

那么你的WebView将有一个接口是这样的:

Then your WebView would have an interface like this:

public class JSInterface {

    public String getPendingJS() {
        synchronized(LOCK) {
            String pendingCommands = mPendingJS.toString();
            mPendingJS.setLength(0);
            mPendingJS.append("javascript: ");
            return pendingCommands;
        }
    }

}

返回一个字符串的等待状态的命令,并清除他们,所以他们才不会被再次返回。

That returns a String with the pending commands and clears them so they don't get returned again.

您将它添加到的WebView是这样的:

You would add it to the WebView like this:

mWebView.addJavascriptInterface(新JSInterface(),JSInterface);

然后在你的JavaScript,你会设置在刷新等待状态的命令一定的时间间隔。在每个间隔它会调用 JSInterface.getPendingJS()这将返回所有未决命令的一个字符串,然后你可以执行它们。

Then in your javascript you would set some interval in which to flush the pending commands. On each interval it would call JSInterface.getPendingJS() which would return a String of all of the pending commands and then you could execute them.

您可以进一步通过增加在execJS方法进行检查,看是否有外地的EditText中存在的WebView,并在重点改善这一点。如果有一个,那么你可以使用此排队方法,但如果没有一个焦点,那么你可以只调用使用loadURL()像正常的。这样,它仅使用此解决方法时,它实际需要的。

You could further improve this by adding a check in the execJS method to see if a EditText field exists in the WebView and is in focus. If there is one, then you would use this queueing method, but if there wasn't one in focus then you could just call loadUrl() like normal. That way it only uses this workaround when it actually needs to.

这篇关于的WebView使用loadURL(),这意味着键盘不能继续开放,同时调用javascript的过程中隐藏软键盘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆