WebView oculta el teclado virtual durante loadUrl (), lo que significa que un teclado no puede permanecer abierto mientras llama a javascript
Puesto que la manera que usted llama javascript en un WebView es a través de loadUrl ("javascript: …"); El teclado no puede permanecer abierto.
El método loadUrl () llama a loadUrlImpl () , que llama a un método llamado clearHelpers () que luego llama a clearTextEntry () , que entonces llama a hideSoftKeyboard () y luego nos volvemos tan solitarios como el teclado desaparece.
- ¿Cómo puedo desplazar un WebView a un punto específico en Android
- ¿Cómo utilizar WebView para mostrar páginas html en modo lector de libros electrónicos?
- Superposición blanca en WebView después de la actualización a AppCompat con Xamarin Forms
- Las imágenes se cargan más rápido en la vista web
- Phonegap Android Internet no funciona
Por lo que puedo ver todos los que son privados y no puede ser anulado.
¿Alguien ha encontrado una solución para esto? ¿Hay una manera de forzar el teclado para permanecer abierto o para llamar el javascript directamente sin pasar por loadUrl ()?
¿Hay alguna forma de anular el WebView de una manera de evitar (el método privado) clearTextEntry () de ser llamado?
- De ancho: 100% en CSS no bien renderizado en Android 4.4
- Html textfield en WebView en una aplicación de Android está oculto por el teclado virtual
- WebView textarea no aparece el teclado
- Inyectar CSS a un sitio con webview en android
- Comunicación entre webview y código nativo en una aplicación para móviles
- Cómo habilitar WebKitDeveloperExtras en WebView de Android
- Android y Jsoup
- ¿Cómo puedo tomar una captura de pantalla de una vista web, capturar la página completa?
Actualizar
KitKat agregó un método público para invocar javascript directamente: evaluateJavascript ()
Para los apis más antiguos, podría probar una solución como la siguiente, pero si tuviera que hacer esto de nuevo me gustaría ver sólo la construcción de un método de compatibilidad que en KitKat utiliza el método anterior y en los dispositivos más antiguos, utiliza la reflexión para profundizar en un interior Private método: BrowserFrame.stringByEvaluatingJavaScriptFromString ()
Entonces usted podría llamar javascript directamente sin tener que lidiar con loadUrl y añadir "javascript: "
al script.
Respuesta Antigua
Según lo solicitado por Alok Kulkarni, voy a dar una visión general aproximada de una posible solución que pensé para esto. No lo he probado pero en teoría debería funcionar. Este código va a ser áspero y es sólo para servir de ejemplo.
En lugar de enviar las llamadas a través de loadUrl (), cola sus llamadas de javascript y, a continuación, tienen javascript tirar de ellos. Algo como:
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("; "); } }
En lugar de llamar a loadUrl () llamar a ese método. (Para hacer esto simple he utilizado un bloque sincronizado, pero esto podría ser más adecuado para una ruta diferente. Ya que javascript se ejecuta en su propio hilo, esto tendrá que ser hilo seguro de alguna manera u otra).
Entonces su WebView tendría una interfaz como esta:
public class JSInterface { public String getPendingJS() { synchronized(LOCK) { String pendingCommands = mPendingJS.toString(); mPendingJS.setLength(0); mPendingJS.append("javascript: "); return pendingCommands; } } }
Que devuelve una cadena con los comandos pendientes y los borra para que no vuelvan a ser devueltos.
Lo agregaría al WebView de esta manera:
mWebView.addJavascriptInterface(new JSInterface(), "JSInterface");
A continuación, en su javascript se establece algún intervalo en el que para vaciar los comandos pendientes. En cada intervalo llamaría JSInterface.getPendingJS()
que devolvería una cadena de todos los comandos pendientes y, a continuación, podría ejecutarlos.
Puede mejorar aún más esto agregando una comprobación en el método execJS para ver si existe un campo EditText en el WebView y está en foco. Si hay uno, entonces usted utilizaría este método de cola, pero si no había uno en el foco entonces usted podría apenas cargar loadUrl () como normal. De esta manera sólo utiliza esta solución cuando realmente necesita.
En cuanto a las API más antiguas (pre 19), he utilizado un método similar a la respuesta exceptuada, pero ligeramente diferente.
En primer lugar, me mantengo al tanto de si el teclado se muestra mediante el uso de javascript en la webview más o menos así:
document.addEventListener( "focus", function(e){ var el = e.target; reportKeyboardDisplayedToJava( isInputElement( el ) ); }, true); document.addEventListener( "blur", function(e){ reportKeyboardDisplayedToJava( false ); }, true);
Si el teclado se muestra, y una inyección js es intentado por la capa Java de Android – "aplazar" la inyección. Lo agrego a una lista de cadenas, permite al usuario terminar su entrada, y luego al desaparecer el teclado, lo detecto y ejecuto el backlog de inyecciones.
- Establecer una cookie para un webView en Android
- Enviar solicitud de publicación con params utilizando Retrofit