activar / desactivar el zoom en Android WebView

Hay algunos métodos en WebSettings relacionados con el zoom:

  • WebSettings.setSupportZoom
  • WebSettings.setBuiltInZoomControls

Noté que funcionan de manera diferente en algunos dispositivos. Por ejemplo, en mi Galaxy S pellizcar para hacer zoom está habilitado de forma predeterminada, pero en LG P500 está desactivado (Y ahora no sé cómo habilitar SOLO pellizcar para acercar o alejar, pero ocultar botones de zoom).

En P500 cuando setBuiltInZoomControls(true) obtengo estas dos variantes funcionando (multitouch y botones).

¿Cómo habilitar el zoom multitouch y desactivar los botones de acercamiento en dispositivos como un LG P500? (Además, sé que los mismos problemas están en los dispositivos HTC)

ACTUALIZACIÓN: Aquí hay un código casi completo para la solución

  if (ev.getAction() == MotionEvent.ACTION_DOWN || ev.getAction() == MotionEvent.ACTION_POINTER_DOWN || ev.getAction() == MotionEvent.ACTION_POINTER_1_DOWN || ev.getAction() == MotionEvent.ACTION_POINTER_2_DOWN || ev.getAction() == MotionEvent.ACTION_POINTER_3_DOWN) { if (multiTouchZoom && !buttonsZoom) { if (getPointerCount(ev) > 1) { getSettings().setBuiltInZoomControls(true); getSettings().setSupportZoom(true); } else { getSettings().setBuiltInZoomControls(false); getSettings().setSupportZoom(false); } } } if (!multiTouchZoom && buttonsZoom) { if (getPointerCount(ev) > 1) { return true; } } 

Este código está en mi método onTouchEvent reemplazado por WebView.

Miré el código fuente de WebView y llegué a la conclusión de que no hay una manera elegante de lograr lo que estás pidiendo.

Lo que terminé haciendo fue crear subclases de WebView y anular OnTouchEvent . En OnTouchEvent para ACTION_DOWN , compruebo cuántos punteros hay utilizando MotionEvent.getPointerCount() . Si hay más de un puntero, llamo a setSupportZoom(true) ; de lo contrario, llamo a setSupportZoom(false) . Luego llamo al super.OnTouchEvent().

Esto desactivará de manera efectiva el zoom cuando se desplaza (lo que deshabilita los controles del zoom) y activará el zoom cuando el usuario esté a punto de pellizcar. No es una buena forma de hacerlo, pero me ha funcionado bien hasta ahora.

Tenga en cuenta que getPointerCount() se introdujo en 2.1 por lo que tendrá que hacer algunas cosas adicionales si es compatible con 1.6.

En API> = 11, puede usar:

 wv.getSettings().setBuiltInZoomControls(true); wv.getSettings().setDisplayZoomControls(false); 

Según el SDK:

 public void setDisplayZoomControls (boolean enabled) 

Desde: API Nivel 11

Establece si se utilizan los botones de zoom en pantalla. Una combinación de controles de zoom incorporados habilitados y controles de zoom en pantalla desactivados permite pellizcar para hacer zoom para trabajar sin los controles en pantalla

Tuvimos el mismo problema al trabajar en una aplicación de Android para un cliente y logré “piratear” esta restricción.

updateZoomButtonsEnabled() un vistazo al código fuente de Android para la clase WebView y updateZoomButtonsEnabled() un método updateZoomButtonsEnabled() que estaba trabajando con un objeto ZoomButtonsController para habilitar y deshabilitar los controles de zoom dependiendo de la escala actual del navegador.

Busqué un método para devolver ZoomButtonsController -instance y encontré getZoomButtonsController() -method , que devolvió esta misma instancia.

Aunque el método se declara public , no está documentado en la documentación de WebView y Eclipse tampoco pudo encontrarlo. Entonces, intenté reflexionar sobre eso y creé mi propia clase WebView -subclass para anular el método onTouchEvent() , que activó los controles.

 public class NoZoomControllWebView extends WebView { private ZoomButtonsController zoom_controll = null; public NoZoomControllWebView(Context context) { super(context); disableControls(); } public NoZoomControllWebView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); disableControls(); } public NoZoomControllWebView(Context context, AttributeSet attrs) { super(context, attrs); disableControls(); } /** * Disable the controls */ private void disableControls(){ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { // Use the API 11+ calls to disable the controls this.getSettings().setBuiltInZoomControls(true); this.getSettings().setDisplayZoomControls(false); } else { // Use the reflection magic to make it work on earlier APIs getControlls(); } } /** * This is where the magic happens :D */ private void getControlls() { try { Class webview = Class.forName("android.webkit.WebView"); Method method = webview.getMethod("getZoomButtonsController"); zoom_controll = (ZoomButtonsController) method.invoke(this, null); } catch (Exception e) { e.printStackTrace(); } } @Override public boolean onTouchEvent(MotionEvent ev) { super.onTouchEvent(ev); if (zoom_controll != null){ // Hide the controlls AFTER they where made visible by the default implementation. zoom_controll.setVisible(false); } return true; } } 

Es posible que desee eliminar los constructores innecesarios y reactjsr probablemente en las excepciones.

Aunque parece poco atractivo y poco confiable, funciona de nuevo en el nivel 4 de API (Android 1.6).


Como señaló @jayellos en los comentarios, el getZoomButtonsController() privado getZoomButtonsController() ya no existe en Android 4.0.4 y posteriores.

Sin embargo, no es necesario. Al usar la ejecución condicional , podemos verificar si estamos en un dispositivo con API Nivel 11+ y usar la funcionalidad expuesta (ver @Yuttadhammo answer) para ocultar los controles.

Actualicé el código de ejemplo anterior para hacer exactamente eso.

Ive modifiet la solución de Lukas Knuth un poco:

1) No hay necesidad de subclasificar la vista web,

2) el código se bloqueará durante la verificación del código de bytes en algunos dispositivos Android 1.6 si no pone métodos inexistentes en clases separadas

3) Los controles de zoom seguirán apareciendo si el usuario se desplaza hacia arriba o hacia abajo en una página. Simplemente configuro el contenedor del controlador de zoom para visibilidad GONE

  wv.getSettings().setSupportZoom(true); wv.getSettings().setBuiltInZoomControls(true); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { // Use the API 11+ calls to disable the controls // Use a seperate class to obtain 1.6 compatibility new Runnable() { public void run() { wv.getSettings().setDisplayZoomControls(false); } }.run(); } else { final ZoomButtonsController zoom_controll = (ZoomButtonsController) wv.getClass().getMethod("getZoomButtonsController").invoke(wv, null); zoom_controll.getContainer().setVisibility(View.GONE); } 

Lukas Knuth tiene una buena solución, pero en Android 4.0.4 en Samsung Galaxy SII todavía veo controles de zoom. Y lo resuelvo a través de

 if (zoom_controll!=null && zoom_controll.getZoomControls()!=null) { // Hide the controlls AFTER they where made visible by the default implementation. zoom_controll.getZoomControls().setVisibility(View.GONE); } 

en lugar de

 if (zoom_controll != null){ // Hide the controlls AFTER they where made visible by the default implementation. zoom_controll.setVisible(false); } 

La solución que publicó parece funcionar para evitar que aparezcan los controles del zoom cuando el usuario se arrastra, sin embargo, hay situaciones en las que un usuario pellizcará el zoom y aparecerán los controles del zoom. Me he dado cuenta de que hay dos maneras en que la vista web aceptará el zoom de pellizco, y solo una de ellas hace que aparezcan los controles de zoom a pesar de su código:

Los Zooms y controles de Pinch de usuario aparecen:

 ACTION_DOWN getSettings().setBuiltInZoomControls(false); getSettings().setSupportZoom(false); ACTION_POINTER_2_DOWN getSettings().setBuiltInZoomControls(true); getSettings().setSupportZoom(true); ACTION_MOVE (Repeat several times, as the user moves their fingers) ACTION_POINTER_2_UP ACTION_UP 

El zoom y los controles de pellizco del usuario no aparecen:

 ACTION_DOWN getSettings().setBuiltInZoomControls(false); getSettings().setSupportZoom(false); ACTION_POINTER_2_DOWN getSettings().setBuiltInZoomControls(true); getSettings().setSupportZoom(true); ACTION_MOVE (Repeat several times, as the user moves their fingers) ACTION_POINTER_1_UP ACTION_POINTER_UP ACTION_UP 

¿Puedes arrojar más luz sobre tu solución?

Versión mejorada de Lukas Knuth:

 public class TweakedWebView extends WebView { private ZoomButtonsController zoomButtons; public TweakedWebView(Context context) { super(context); init(); } public TweakedWebView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TweakedWebView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { getSettings().setBuiltInZoomControls(true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { getSettings().setDisplayZoomControls(false); } else { try { Method method = getClass() .getMethod("getZoomButtonsController"); zoomButtons = (ZoomButtonsController) method.invoke(this); } catch (Exception e) { // pass } } } @Override public boolean onTouchEvent(MotionEvent ev) { boolean result = super.onTouchEvent(ev); if (zoomButtons != null) { zoomButtons.setVisible(false); zoomButtons.getZoomControls().setVisibility(View.GONE); } return result; } } 

oye para cualquiera que esté buscando una solución como esta … tuve problemas para escalar dentro de WebView, así que la mejor manera de hacerlo es en tu java.class donde configuras todo para que webView ponga esta dos líneas de código: (webViewSearch es el nombre de my webView -> webViewSearch = (WebView) findViewById (R.id.id_webview_search);)

 // force WebView to show content not zoomed--------------------------------------------------------- webViewSearch.getSettings().setLoadWithOverviewMode(true); webViewSearch.getSettings().setUseWideViewPort(true);