studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android android-webview android-scroll android-scrollbar

android - programacion - ¿Deshabilita el desplazamiento en la vista web?



manual de programacion android pdf (15)

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 programación en un WebView .

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


// 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


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

<body leftmargin="0" topmargin="0" rightmargin="0" bottommargin="0">

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


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:

<ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollbars="vertical" > <WebView android:id="@+id/mywebview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollbars="none" /> </ScrollView>

Y establecer

webview.setScrollContainer(false);

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


Establezca un oyente en su WebView:

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


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 source de WebView , puede ver que en onTouchEvent llama a doDrag que llama a overScrollBy .


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:

<ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollbars="vertical" > <WebView android:id="@+id/mywebview" android:layout_width="1000dip" android:layout_height="fill_parent" /> </ScrollView>

Espero que esto ayude ;)


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); }


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);


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 etiquetas 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


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

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


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); } ...


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


Utilice la clase mencionada a continuación para deshabilitar el desplazamiento horizontal en la vista web.

public class CustomWebView extends WebView implements View.OnTouchListener { // the initial touch points x coordinate private float touchDownX; private OnScrollChangedCallback mOnScrollChangedCallback; public CustomWebView(final Context context) { super(context); // make vertically scrollable only makeVerticalScrollOnly(); } public CustomWebView(final Context context, final AttributeSet attrs) { super(context, attrs); // make vertically scrollable only makeVerticalScrollOnly(); } public CustomWebView(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); // make vertically scrollable only makeVerticalScrollOnly(); } @Override protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt) { super.onScrollChanged(l, t, oldl, oldt); if (mOnScrollChangedCallback != null) mOnScrollChangedCallback.onScroll(l, t); } public OnScrollChangedCallback getOnScrollChangedCallback() { return mOnScrollChangedCallback; } public void setOnScrollChangedCallback(final OnScrollChangedCallback onScrollChangedCallback) { mOnScrollChangedCallback = onScrollChangedCallback; } /** * Impliment in the activity/fragment/view that you want to listen to the webview */ public static interface OnScrollChangedCallback { public void onScroll(int l, int t); } /** * make this {@link WebView} vertically scroll only */ private void makeVerticalScrollOnly() { // set onTouchListener for vertical scroll only setOnTouchListener(this); // hide horizontal scroll bar setHorizontalScrollBarEnabled(false); } @Override public boolean onTouch(View view, MotionEvent motionEvent) { // multitouch is ignored if (motionEvent.getPointerCount() > 1) { return true; } // handle x coordinate on single touch events switch (motionEvent.getAction()) { // save the x coordinate on touch down case MotionEvent.ACTION_DOWN: touchDownX = motionEvent.getX(); break; // reset the x coordinate on each other touch action, so it doesn''t move case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: motionEvent.setLocation(touchDownX, motionEvent.getY()); break; } // let the super view handle the update return false; } }


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); } }