Activar / desactivar el zoom en Android WebView

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

  • WebSettings.setSupportZoom
  • WebSettings.setBuiltInZoomControls

Me di cuenta de que funcionan de forma diferente en algunos dispositivos. Por ejemplo, en mi Galaxy S pellizcar para el zoom está habilitado de forma predeterminada, pero en LG P500 está deshabilitado (Y ahora no sé cómo habilitar sólo pellizcar para ampliar, pero ocultar los botones de zoom).

En P500 cuando llamo setBuiltInZoomControls(true) Tengo ambas variantes funcionando (multitouch y botones).

¿Cómo activar el zoom multitáctil y desactivar los botones de zoom en dispositivos como un LG P500? (También, sé que los mismos problemas están en los dispositivos de HTC)

UPDATE: Aquí hay casi código 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 sobreescrito de la WebView.

He mirado el código fuente para WebView y he llegado a la conclusión de que no hay manera elegante de lograr lo que estás pidiendo.

Lo que acabé haciendo fue subclase WebView y sobreescribir OnTouchEvent . En OnTouchEvent para ACTION_DOWN , compruebo cuántos punteros hay usando MotionEvent.getPointerCount() . Si hay más de un puntero, llamo setSupportZoom(true) , de lo contrario llamo setSupportZoom(false) . A continuación, llamar a la super.OnTouchEvent().

Esto desactivará eficazmente el zoom cuando se desplaza (desactivando así los controles de zoom) y habilita el zoom cuando el usuario está a punto de pellizcar el zoom. No es una buena manera de hacerlo, pero ha funcionado bien para mí hasta ahora.

Tenga en cuenta que getPointerCount() fue introducido en 2.1 por lo que tendrá que hacer algunas cosas extra si getPointerCount() 1.6.

En API> = 11, puede utilizar:

 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 deshabilitados permite pinch to zoom para trabajar sin los controles en pantalla

Tuvimos el mismo problema al trabajar en una aplicación de Android para un cliente y me las arreglé para "hackear" alrededor de 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 el ZoomButtonsController -instance y encontré el método getZoomButtonsController() , que devolvió esta misma instancia.

Aunque el método se declara public , no está documentado en la documentación de WebView y Eclipse no pudo encontrarlo tampoco. Por lo tanto, traté de reflexionar sobre eso y creé mi propia subclase WebView 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 reaccionar probablemente en las excepciones.

Aunque esto parece hacky y poco confiable, funciona de nuevo a API Nivel 4 (Android 1.6).


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

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

He actualizado el código de ejemplo anterior para hacer exactamente eso.

He modificado la solución de Lukas Knuth un poco:

1) No hay necesidad de subclasificar la webview,

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

3) Los controles de zoom seguirán apareciendo si el usuario se desplaza hacia arriba / abajo de una página. Simplemente establezco el contenedor del controlador de zoom en la 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 busco controles de zoom. Y lo resuelvo vía

 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 que funciona para detener los controles de zoom de aparecer cuando el usuario arrastra, sin embargo, hay situaciones en las que un usuario pinch zoom y los controles de zoom aparecerá. He notado que hay 2 maneras en que la webview acepta pinch zoom, y sólo uno de ellos hace que los controles de zoom aparezcan a pesar de su código:

Pinch del usuario Los zoom y los controles 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 Pinch Zoom y los controles de 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 

¿Puede arrojar más luz sobre su 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; } } 

Hey allí para cualquier persona que podría estar buscando una solución como esta .. tuve problema con la escala dentro de WebView así que la mejor manera de hacer es en su java.class donde se establece todo para webView poner esta dos línea de código: (webViewSearch es el nombre de Mi webView -> webViewSearch = (WebView) findViewById (R.id.id_webview_search);)

 // force WebView to show content not zoomed--------------------------------------------------------- webViewSearch.getSettings().setLoadWithOverviewMode(true); webViewSearch.getSettings().setUseWideViewPort(true); 
  • Ampliación de Android en capas dinámicamente cambiantes
  • Zoom de Android y rotación de la vista de imagen
  • Google Maps v2 Establecer nivel de zoom
  • Cambiar controles de zoom en un MapView
  • Android imageView: configuración de los parámetros de arrastrar y comprimir el zoom
  • Mantenga el mapa centrado, independientemente de dónde pinche el zoom en android
  • Android - Google Maps api v2 - Desactivar el control de zoom
  • Canvas.scale (mScaleFactor, mScaleFactor, detector.getFocusX (), detector.getFocusY ()) arrastrando límite de lío?
  • Android: no se muestra ImageView con UIL y TouchImageView
  • Implementar pinch Zoom usando ViewPager
  • En evento de zoom para google maps en android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.