¿Deshabilita el desplazamiento en la vista web?

Hasta ahora solo he sido desarrollador de iPhone y ahora he decidido darle un giro a Android. Algo que no he podido averiguar en Android es cómo evitar el desplazamiento mediante progtwigción en un WebView .

¡Algo similar a la prevención de iPhones del evento onTouchMove sería genial!

Aquí está mi código para deshabilitar todo el desplazamiento en la vista web:

  // disable scroll on touch webview.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return (event.getAction() == MotionEvent.ACTION_MOVE); } }); 

Para ocultar las barras de desplazamiento, pero no deshabilitar el desplazamiento:

 WebView.setVerticalScrollBarEnabled(false); WebView.setHorizontalScrollBarEnabled(false); 

o puede intentar usar el diseño de una sola columna, pero esto solo funciona con páginas simples e inhabilita el desplazamiento horizontal:

  //Only disabled the horizontal scrolling: webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); 

También puede intentar envolver su vista web con scrollview verticalmente desplazable e inhabilitar todo el desplazamiento en la vista web:

    

Y establecer

 webview.setScrollContainer(false); 

No olvides agregar el webview.setOnTouchListener(...) arriba para deshabilitar todo el desplazamiento en la vista web. El ScrollView vertical permitirá el desplazamiento del contenido de WebView.

No sé si todavía lo necesitas o no, pero aquí está la solución:

 appView = (WebView) findViewById(R.id.appView); appView.setVerticalScrollBarEnabled(false); appView.setHorizontalScrollBarEnabled(false); 

Hacer que la WebView ignore los eventos de movimiento es la forma incorrecta de hacerlo. ¿Qué pasa si la WebView necesita escuchar acerca de estos eventos?

En lugar de la subclase WebView y anula los métodos de desplazamiento no privados.

 public class NoScrollWebView extends WebView { ... @Override public boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { return false; } @Override public void scrollTo(int x, int y) { // Do nothing } @Override public void computeScroll() { // Do nothing } } 

Si mira la fuente de WebView , puede ver que en onTouchEvent llama a doDrag que llama a OverScrollBy .

Agregar los detalles de los márgenes al cuerpo evitará que se desplace si su contenido se ajusta correctamente, así:

  

Bastante fácil, y mucho menos errores de código + error 🙂

Establezca un oyente en su WebView:

 webView.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { return(event.getAction() == MotionEvent.ACTION_MOVE)); } }); 

No lo he intentado ya que aún no me he encontrado con este problema, pero ¿quizás podría anular la función onScroll?

 @Override public void scrollTo(int x, int y){ super.scrollTo(0,y); } 

Mi solución sucia, pero fácil de implementar y que funciona bien:

Simplemente ponga la vista web dentro de una vista de desplazamiento. Haga que la vista web sea demasiado más grande que el contenido posible (en una o ambas dimensiones, según los requisitos). ..y configure la barra de desplazamiento de la vista de desplazamiento como desee.

Ejemplo para deshabilitar la barra de desplazamiento horizontal en una vista web:

    

Espero que esto ayude 😉

Para deshabilitar el desplazamiento, use esto

webView.setOnTouchListener (new View.OnTouchListener () {

  public boolean onTouch(View v, MotionEvent event) { return (event.getAction() == MotionEvent.ACTION_MOVE); } }); 

Puede que esta no sea la fuente de su problema, pero he pasado horas tratando de rastrear por qué mi aplicación que funcionó bien en el iPhone hace que el navegador de Android arroje constantemente las barras de desplazamiento vertical / horizontal y realmente mueva la página. Tenía una etiqueta de cuerpo html con alto y ancho establecido en 100%, y el cuerpo estaba lleno de varias tags en diferentes ubicaciones. No importa lo que intenté, los navegadores Android mostraban sus barras de desplazamiento y movían la página solo un poco, en particular cuando se deslizaba rápidamente. La solución que funcionó para mí sin tener que hacer nada en un APK fue agregar lo siguiente a la etiqueta del cuerpo:

 leftmargin="0" topmargin="0" 

Parece que los márgenes predeterminados para la etiqueta del cuerpo se estaban aplicando en el droide, pero se ignoraron en el iPhone

Si subclasifica Webview, puede anular el evento Touch para bloquear los eventos de movimiento que desencadenan el desplazamiento.

 public class SubWebView extends WebView { @Override public boolean onTouchEvent (MotionEvent ev) { if(ev.getAction() == MotionEvent.ACTION_MOVE) { postInvalidate(); return true; } return super.onTouchEvent(ev); } ... 

Resolví el parpadeo y el desplazamiento automático por:

 webView.setFocusable(false); webView.setFocusableInTouchMode(false); 

Sin embargo, si todavía no funciona por algún motivo, simplemente cree una clase que extienda WebView y coloque este método en ella:

 // disable scroll on touch setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return (event.getAction() == MotionEvent.ACTION_MOVE); } }); 

Sugiero extender WebView, para proporcionar un control más efectivo, como inhabilitar / habilitar los deslizamientos, habilitar / deshabilitar toques, oyentes, controlar transiciones, animaciones, definir configuraciones internamente, etc.

estudiar las respuestas anteriores casi funcionó para mí … pero todavía tenía un problema que podría ‘arrojar’ la vista en 2.1 (parecía ser corregido con 2.2 y 2.3).

aquí está mi solución final

 public class MyWebView extends WebView { private boolean bAllowScroll = true; @SuppressWarnings("unused") // it is used, just java is dumb private long downtime; public MyWebView(Context context, AttributeSet attrs) { super(context, attrs); } public void setAllowScroll(int allowScroll) { bAllowScroll = allowScroll!=0; if (!bAllowScroll) super.scrollTo(0,0); setHorizontalScrollBarEnabled(bAllowScroll); setVerticalScrollBarEnabled(bAllowScroll); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: if (!bAllowScroll) downtime = ev.getEventTime(); break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: if (!bAllowScroll) { try { Field fmNumSamples = ev.getClass().getDeclaredField("mNumSamples"); fmNumSamples.setAccessible(true); Field fmTimeSamples = ev.getClass().getDeclaredField("mTimeSamples"); fmTimeSamples.setAccessible(true); long newTimeSamples[] = new long[fmNumSamples.getInt(ev)]; newTimeSamples[0] = ev.getEventTime()+250; fmTimeSamples.set(ev,newTimeSamples); } catch (Exception e) { e.printStackTrace(); } } break; } return super.onTouchEvent(ev); } @Override public void flingScroll(int vx, int vy) { if (bAllowScroll) super.flingScroll(vx,vy); } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { if (bAllowScroll) super.onScrollChanged(l, t, oldl, oldt); else if (l!=0 || t!=0) super.scrollTo(0,0); } @Override public void scrollTo(int x, int y) { if (bAllowScroll) super.scrollTo(x,y); } @Override public void scrollBy(int x, int y) { if (bAllowScroll) super.scrollBy(x,y); } } 

// Deshabilita todo el desplazamiento

 WebView.setVerticalScrollBarEnabled(false); WebView.setHorizontalScrollBarEnabled(false); webview.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return (event.getAction() == MotionEvent.ACTION_MOVE); } }); 

// Deshabilitar desplazamiento horizontal solamente

 WebView.setHorizontalScrollBarEnabled(false); webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); 

// Desactivar desplazamiento vertical solamente

 WebView.setVerticalScrollBarEnabled(false); webview.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (action) { case (MotionEvent.ACTION_DOWN): /** * get Y position */ start_y = event.getY(); break; case (MotionEvent.ACTION_MOVE): /*Disable vertical scrolling*/ if (start_y-event.getY()>THRESHOLD_VALUE || start_y- event.getY()<-THRESHOLD_VALUE) return true; break; } } }); 

En mi caso, el valor umbral era 20

Esta debería ser la respuesta completa. Según lo sugerido por @GDanger. Extienda WebView para anular los métodos de desplazamiento e incrustar la vista web personalizada dentro del diseño xml.

 public class ScrollDisabledWebView extends WebView { private boolean scrollEnabled = false; public ScrollDisabledWebView(Context context) { super(context); initView(context); } public ScrollDisabledWebView(Context context, AttributeSet attributeSet) { super(context, attributeSet); initView(context); } // this is important. Otherwise it throws Binary Inflate Exception. private void initView(Context context) { LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { if (scrollEnabled) { return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); } return false; } @Override public void scrollTo(int x, int y) { if (scrollEnabled) { super.scrollTo(x, y); } } @Override public void computeScroll() { if (scrollEnabled) { super.computeScroll(); } } } 

Y luego incrustar en el archivo de diseño de la siguiente manera

  

Luego, en la Actividad, use algunos métodos adicionales para deshabilitar las barras de desplazamiento también.

 ScrollDisabledWebView webView = (ScrollDisabledWebView) findViewById(R.id.webView); webView.setVerticalScrollBarEnabled(false); webView.setHorizontalScrollBarEnabled(false); 

Simplemente use android:focusableInTouchMode="false" en su webView .