2010-03-27 20 views
74

Hasta ahora he sido desarrollador de iPhone solamente y ahora he decidido darle un giro a Android. Algo que no he podido averiguar en Android es cómo prevenir el desplazamiento mediante programación en un WebView?¿Desea desactivar el desplazamiento en la vista web?

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

Respuesta

159

Aquí está mi código para desactivar todos desplazamiento en 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 única ocultar las barras de desplazamiento, pero no desactivar el desplazamiento:

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

o puede probar usando sola estructura de columnas pero esto sólo funciona con páginas sencillas y se desactiva el desplazamiento horizontal:

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

También puede tratar de envolver su vista web con verticalmente desplazarse scrollview y deshabilitar 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 SET

webview.setScrollContainer(false); 

No se olvide de añadir el código de webview.setOnTouchListener (...) por encima de desactivar todo el desplazamiento en la vista web.El ScrollView vertical permitirá el desplazamiento del contenido de WebView.

+0

funciona bien, pero después de unos segundos provoca un bloqueo en Samsung i5700 spica en /system/lib/libwebcore.so. – Lukas

+0

LayoutAlgorithm.SINGLE_COLUMN o webview.setOnTouchListener? – peceps

+0

Estoy comenzando otra actividad en onTouchListener así que ¿puedes decirme cómo desplazar el desplazamiento vertical ..? – Noby

4

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

En pocas palabras la vista web dentro de un ScrollView. 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 ayuda;)

+0

sí, pero entonces el tamaño de la espiral no sería demasiado grande con un montón de espacio en blanco en la parte inferior? –

+1

¿Qué sucede si el ancho del contenido será 1001dp? – Waltsu

7

Establecer un oyente en su vista web:

// breakingart.com: This prevents the webview being scrolled 
webView.setOnTouchListener(new View.OnTouchListener() { 
      public boolean onTouch(View v, MotionEvent event) { 
       return(event.getAction() == MotionEvent.ACTION_MOVE)); 
      } 
     }); 
+2

Hay un paréntesis adicional al final de la línea 'return' allí. También esto rompe el lienzo HTML5 y los eventos táctiles de JavaScript. –

+0

Esto ciertamente lo desactiva, pero ¿cómo puedo matar al oyente más tarde a la entrada de Renable? Intenté 'event.getAction()! = MotionEvent.ACTION_MOVE' así como' return true' – CQM

6

No he probado esto como todavía tengo que encontrar este problema, pero tal vez podría anular la función onScroll?

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

Esto es lo que llamamos en la India un Jugaad ... aunque funcionó bien – R4chi7

22

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

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

ok. esto desactiva las barras de desplazamiento, pero no evita el desplazamiento arrastrando. Parece que el html debe caber también ... – rdmueller

+0

Si estás diseñando tus páginas web solo para la vista web de Android, te recomiendo que hagas tus páginas web en la tabla. El ancho debe ser como width = "100%" y el mismo para la altura. por lo que ya no se arrastrará más. – umar

+0

ancho = 100% no siempre funciona, por ejemplo: http://stackoverflow.com/questions/6460871/incorrect-width-in-android-webkit-browser – NoBugs

1

el estudio de las respuestas anteriores casi trabajaron 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 & 2.3).

aquí es 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); 
} 
} 
+0

Para anular el método onScrollChanged() funciona para mí. En mi caso, no puedo arrastrar la barra de progreso de video y audio incrustada en WebView usando la respuesta de aceptación. ¡Muchas gracias! – codezjx

2

Puede que esta no sea la fuente de su problema, pero he pasado horas intentando rastrear por qué mi aplicación que funcionaba bien en el iphone causaba que el navegador android lanzara constantemente las barras de desplazamiento vertical/horizontal y realmente moviera 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 era añadir lo siguiente a la etiqueta del cuerpo:

leftmargin="0" topmargin="0" 

Parece que los márgenes predeterminados de la etiqueta del cuerpo se están aplicando en el androide pero se ignoran en el iPhone

12

añadiendo los detalles de margen para el cuerpo impedirá el desplazamiento si su contenido se ajusta adecuadamente, de modo que:

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

bastante fácil, y un código de error de + menor carga :)

+0

Brillante! +1 para una solución simple de solo HTML. A veces deseo, el diseño en Android era tan fácil como css ... –

+0

Se ve bien en el navegador de Android, pero no parece funcionar en Firefox (Fennec) ... a pesar de que no hay nada para desplazarse horizontalmente, Firefox todavía me permite desplazarme hacia la derecha hasta el punto donde todo el contenido se ha desplazado de la pantalla. – Michael

+0

No funciona en WebView moderno (Android 5 y superior) – Roel

1

Si subclase Webview, puede simplemente anular en TouchEvent para filtrar 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); 
    } 
    ... 
1

me resolvieron el parpadeo y el desplazamiento automático por:

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

¡Trabaja como un encanto! – Ernest

14

haciendo que el WebView ignoran los eventos de movimiento es la forma equivocada de hacerlo. ¿Qué pasa si el WebView necesita saber 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 nos fijamos en la source para WebView se puede ver que onTouchEvent llamadas doDrag que se pide overScrollBy.

+1

Si necesita deshabilitar/habilitar mediante programación el desplazamiento, mire este [sentido] (https://gist.github.com/GavinDBrown/a73c53093dc2dd62aa17) que creé. – GDanger

+1

Tu método funciona para mí. Y estoy de acuerdo con usted. En mi caso, no puedo arrastrar la barra de progreso de video y audio incrustada en WebView usando la respuesta de aceptación. – codezjx

+1

Esta debería ser la respuesta aceptada, ¡funciona genial! – 0101100101

4

Para disbale uso de desplazamiento de este

webView.setOnTouchListener (nueva View.OnTouchListener() {

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

sólo tiene que utilizar android:focusableInTouchMode="false" en su web View .

0

// Desactivar todos 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); 
    } 
    }); 

// Desactivar desplazamiento horizontal solamente

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

// desplazamiento vertical sólo desactivan

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 valor umbral caso fue 20

0

Utilice la clase mencionada a continuación en orden para desactivar 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; 

    } 
} 
Cuestiones relacionadas