Pregunta

Hasta ahora he sido solo un desarrollador de iPhone y ahora he decidido darle un giro a Android. Algo que no he podido descubrir en Android es cómo evitar programar programar un desplazamiento en un WebView?

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

¿Fue útil?

Solución

Aquí está mi código para Deshabilitar todo desplazamiento En WebView:

  // 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 solo las barras de desplazamiento, pero no deshabilitar el desplazamiento:

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

O puedes intentar usar Diseño de columna de una sola Pero esto solo funciona con páginas simples y deshabilita el desplazamiento horizontal:

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

También puedes intentar Envuelva su WebView con desplazamiento vertical ScrollView y deshabilite todo 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 webview.setOnTouchListener(...) Código anterior para deshabilitar todo el desplazamiento en WebView. El vertical vertical permitirá el desplazamiento del contenido de WebView.

Otros consejos

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

Haciendo el WebView Ignore Motion Events es la forma incorrecta de hacerlo. ¿Qué pasa si el WebView ¿Necesita escuchar sobre estos eventos?

En su lugar subclase WebView y anular 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 miras el fuente por WebView puedes ver eso onTouchEvent llamadas doDrag que llama sobrescrito.

Agregar los detalles del margen al cuerpo evitará el desplazamiento si su contenido se envuelve correctamente, como así:

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

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

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 he probado esto, ya que todavía tengo que encontrar este problema, pero ¿tal vez podrías exponer la función de Onscroll?

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

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

Simplemente coloque la vista web dentro de una vista de desplazamiento. Haga que WebView sea demasiado mayor que el contenido posible (en una o ambas dimensiones, dependiendo de los requisitos). .. y configure los barras de desplazamiento de ScrollView 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 ;)

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 altura y ancho establecidos en 100%, y el cuerpo estaba lleno de varias etiquetas en diferentes ubicaciones. No importa lo que probé, los navegadores de Android mostrarían sus barras de desplazamiento y moverían la página un poco, particularmente cuando hicieron un golpe rápido. 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 aplicaron en el droide pero se ignoraron en el iPhone

I resolved the flicker and auto-scroll by:

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

However if it still does not work for some reason, simply make a class that extends WebView, and put this method on it:

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

I am suggesting to extend WebView, in order to provide more effective control, like disable/enable swipes, enable/disable touches, listeners, control transitions, animations, define settings internally so on..

Si usted subclase WebView, simplemente puede anular OnTouchEvent para filtrar los eventos de movimiento que activan 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);
    }
    ...

Estudiar las respuestas anteriores casi funcionó para mí ... pero aún tenía el problema de que podía "arrojar" la vista en 2.1 (parecía arreglarse 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);
}
}

Esta debería ser la respuesta completa. Según lo sugerido por @gdanger. Extienda WebView para anular los métodos de desplazamiento e incruste 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 incrustarse en el archivo de diseño de la siguiente manera

<com.sample.apps.ScrollDisabledWebView
    android:id="@+id/webView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"
    tools:context="com.sample.apps.HomeActivity"/>

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

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

Solo usa android:focusableInTouchMode="false" en tu WebView.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top