sistema setwebchromeclient onpagefinished ejemplo descargar android events webview listener

setwebchromeclient - webview android java



¿Hay un oyente para cuando WebView muestra su contenido? (11)

Al usar WebViewClient y / o WebChromeClient, puede obtener un detector para cuando se cargue la página; sin embargo, esto a veces se llama antes de que WebView tenga contenido, antes de que se muestre algo.

¿Cuál sería un método eficiente para determinar cuándo WebView ha mostrado su contenido?

Editar: (Intentando ser más claro)

Cuando cargo una página en un WebView, quiero configurar el desplazamiento a una posición específica. Parece que la posición de desplazamiento no se puede establecer hasta que se cargue la página y tenga una altura de contenido real. Por lo tanto, he probado dos enfoques diferentes para determinar cuándo la página ha terminado de cargarse, onPageFinished () desde WebViewClient y también onProgressChanged () desde WebChromeClient. Ambos me dicen cuándo la página ha terminado de cargarse.

Sin embargo, el problema es que a veces se llama antes de que se muestre la página y, por lo tanto, la página no tiene altura y la llamada de desplazamiento no hace nada.

Estoy tratando de encontrar una forma sólida de determinar cuándo la página está lista para ser desplazada, es decir. cuando tiene su altura de contenido

Me imagino que podría configurar un bucle de verificación después de que termine de cargar para seguir buscando cuando la altura está disponible, pero que parecía bastante el truco. Esperando que haya una manera más limpia.


Creé una vista personalizada que extiende la vista web, que anula el método "onSizeChanged". OnSizeChanged ocurre después de que la vista web carga todo en ella.


EDITAR: Desde que publiqué esto por primera vez, este método ha quedado obsoleto en Android API 12. ¡Gracias, Google! Dejaré la respuesta original intacta:

Sí, hay un oyente que sabe cuándo se terminó de cargar el contenido. Tuve que crear uno en mi proyecto para poder hacer una pantalla de bienvenida que permaneció activa hasta que la vista web cargó la página.

Se llama .setPictureListener.

Por ejemplo:

mWebView.setPictureListener(new MyPictureListener()); //... and then later on.... class MyPictureListener implements PictureListener { @Override public void onNewPicture(WebView view, Picture arg1) { // put code here that needs to run when the page has finished loading and // a new "picture" is on the webview. } }


Esta no es una respuesta directa a la pregunta, pero alternativamente puede usar WebChromeClient. Me parece más confiable y lo tengo configurado para mostrar el progreso de carga. Estaba teniendo el mismo problema con WebView que ocultaba ProgressBar antes de que la página estuviera completamente cargada y reemplacé WebView con el cliente WebView.

Uso el siguiente código

final WebView wvMax = (WebView) findViewById(R.id.webViewTnSmax); final ProgressBar pbMax = (ProgressBar) findViewById(R.id.progressBarTnSmax); wvMax.setWebChromeClient(new WebChromeClient() { public void onProgressChanged(WebView view, int progress) { pbMax.setVisibility(View.VISIBLE); pbMax.setProgress(progress); if (progress == 100) { pbMax.setVisibility(View.GONE); // Make the bar disappear after URL is loaded } } public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { // do something } });



Las soluciones sugeridas aquí son hacky en el mejor de los casos, mientras que hay una solución perfectamente limpia, de acuerdo con los documentos de Android :

WebViewClient client = new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { Log.d("MYAPP", "Page loaded"); } }; webView.setWebViewClient(client);


Leí esta discusión, y estoy enfrentando el mismo problema también.

Busqué mucho, pero no son la solución que prometen ser.

Y no quiero utilizar la devolución de llamada obsoleta `onNewPicture`.

En mi propia situación, solo necesito restaurar la posición de desplazamiento `WebView` cuando se inicia la actividad, y creo que es la mayoría de los casos, ya que cuando la pila de tareas de actividad va al fondo, Android guarda automáticamente el estado` WebView`, por lo que cuando aparece en primer plano, se verá igual. Si se destruye cuando está en segundo plano, estoy seguro de que podrás guardar el estado en los métodos de ciclo de vida de la actividad como `onPause`.

Entonces, en lugar de extender `WebView` y reemplazar bla, bla, bla ..., utilizo un manipulador y un modelo de publicación.

private final Handler mHandler = new Handler(); // in onCreate mHandler.postDelayed(new Runnable() { @Override public void run() { if (mWebView.getContentHeight() > 0) { mWebView.scrollTo(0, mLastPosition); Log.d("scrolling", "true"); mHandler.removeCallbacks(this); } else { mHandler.postDelayed(this, 100); } } }, 100);

Este bloque de código verificará peridicamente si la página de WebView puede ser manipulada, si es así, realiza el desplazamiento y elimina la devolución de llamada, de lo contrario, realiza un bucle. Pruebo esto y lo averiguo usualmente no tomará mucho tiempo.

¡Espero que esto ayude!


Sé que es antiguo pero puede AYUDAR, las respuestas aquí no funcionan a la perfección, lo mejor que encontré es anular el onDraw en la WebView extendida

@Override protected void onDraw(Canvas canvas) { //do your math/stuff/magic/blackmagic/hackish here super.onDraw(canvas); }

así que cada desplazamiento hacia abajo / arriba cada fontZoomCambiar

casi todo (no probado todo) llamará al onDraw

Lo uso para trabajar con SeekBar como Vertical ScrollBar

;)

es importante comprobar si es nulo, y agregar algunos otros si para evitar la llamada al método inútil


Solucioné este problema al crear una vista personalizada que anula el método onDraw y llama a mi propio oyente. Este es el código:

public class CustomWebView extends WebView{ public interface FinishedDrawListener{ void onDrawFinished(WebView view, String url); } private FinishedDrawListener drawListener; public CustomWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } public CustomWebView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public CustomWebView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomWebView(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if(drawListener != null){ drawListener.onDrawFinished(this, this.getUrl()); } } public void setOnFinishedDrawListener(FinishedDrawListener listener){ this.drawListener = listener; }

Creo que no es la mejor manera de hacerlo, pero funciona para mi aplicación.


Utilicé con éxito la respuesta de Richard con un PictureListener durante algunos años, pero ya no lo recomiendo como la mejor solución.

Esto es por dos razones:

  1. webView.setPictureListener y PictureListener están en desuso.
  2. El uso de este oyente hará que WebView asigne una nueva imagen con frecuencia. Esta asignación es costosa y esto puede tener algunos impactos significativos en el rendimiento o incluso causar bloqueos nativos en JellyBean MR1.

En su lugar, recomiendo crear una subclase de WebView y reemplazar invalidate () como sigue:

@Override public void invalidate() { super.invalidate(); if (getContentHeight() > 0) { // WebView has displayed some content and is scrollable. } }

Si aún desea utilizar el método PictureListener, obtendrá un mejor rendimiento si configura PictureListener en null después de que haya terminado con él.


EDITAR: Ya no recomiendo esta solución, pero la dejaré aquí por el bien de la información.

En caso de que esto ayude a alguien más, la forma en que terminé haciendo esto fue subclasificando el WebView y reemplazando el método computeVeritcalScrollExtent() .

@Override protected int computeVerticalScrollExtent() { // do you checking here return super.computeVerticalScrollExtent(); }

Se llamará cuando el WebView calcule su barra de desplazamiento vertical. Sin embargo, la primera vez que se llame donde getContentHeight() > 0 , entonces será la primera vez que se muestre el contenido.


onLoadResource(WebView view, String url)

Notifique a la aplicación de host que WebView cargará el recurso especificado por la url determinada.

Todavía no está claro cuál es el objetivo aquí, pero podría intentarlo

public void doUpdateVisitedHistory (WebView view, String url, boolean isReload)

Yo "asumiría" que la página ha terminado de cargarse antes de que se agregue a la historia ...