Domanda

Fino ad ora sono stato uno sviluppatore iPhone solo e adesso ho deciso di dare un vortice Android. Qualcosa che non sono stato in grado di capire su Android è come evitare di programmazione lo scorrimento in un WebView?

Qualcosa di simile alla prevenzione iPhone dell'evento onTouchMove sarebbe grande!

È stato utile?

Soluzione

Ecco il mio codice per disabilitando tutti scorrimento in WebView:

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

Per nascondere solo le barre di scorrimento, ma non disattivare lo scorrimento:

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

oppure si può provare a utilizzare layout a colonna singola , ma questo funziona solo con le pagine semplici e disabilita lo scorrimento orizzontale:

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

Si può anche provare a avvolgere la visualizzazione web con ScrollView a scorrimento verticale e disattivare tutti lo scorrimento sul WebView:

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

e impostare

webview.setScrollContainer(false);

Non dimenticate di aggiungere il codice webview.setOnTouchListener(...) sopra per disattivare tutti lo scorrimento in WebView. Lo ScrollView verticale consentirà lo scorrimento del contenuto del WebView.

Altri suggerimenti

Non so se hai ancora bisogno o no, ma ecco la soluzione:

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

Fare la WebView ignorare eventi di movimento è il modo sbagliato di procedere. E se il WebView ha bisogno di sentire su questi eventi?

WebView Invece sottoclasse e sovrascrivere i metodi di scorrimento non privati.

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

Se si guarda al fonte per WebView si può vedere che onTouchEvent chiama doDrag che chiama overScrollBy .

e aggiungere i dettagli di margine al corpo impedirà lo scorrimento se il contenuto correttamente avvolge, come:

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

abbastanza facile, e un codice + bug molto meno spese generali:)

Imposta un ascoltatore sul WebView:

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

Non ho provato questo come devo ancora verificare questo problema, ma forse si potrebbe overrive la funzione onscroll?

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

La mia soluzione sporca, ma facile da implementare e ben funzionante:

In poche parole il WebView all'interno di una ScrollView. Rendere il webview sia troppo grande rispetto al contenuto possibile (in una o entrambe le dimensioni, a seconda delle esigenze). ..e configurare barra di scorrimento (s) del ScrollView come si desidera.

Esempio per disattivare la barra di scorrimento orizzontale su un webview:

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

Spero che questo aiuta;)

Per disattivare l'utilizzo di scorrimento questo

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

Questo non può essere la causa del problema, ma ho passato ore a cercare di rintracciare il motivo per cui la mia applicazione che ha funzionato bene su iPhone causare il browser di Android per gettare costantemente le barre di scorrimento verticale / orizzontale e in realtà spostare la pagina. Ho avuto un tag body HTML con altezza e larghezza impostato a 100%, e il corpo era pieno di vari tag in luoghi diversi. Non importa quello che ho provato, i browser Android sarebbe mostrare le loro barre di scorrimento e spostare la pagina solo un po ', soprattutto quando si fa un colpo veloce. La soluzione che ha funzionato per me senza dover fare nulla in un APK è stato quello di aggiungere il seguente al tag body:

leftmargin="0" topmargin="0"

Sembra che i margini di default per tag body venivano applicati sul Droid, ma ignorato su iPhone

Ho risolto il tremolio e auto-scroll da:

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

Tuttavia, se ancora non funziona per qualche motivo, è sufficiente fare una classe che estende WebView, e mettere questo metodo su di esso:

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

sto suggerendo estendere WebView, al fine di fornire un controllo più efficace, come disabilitazione / abilitazione colpi, abilitare / disabilitare tocchi, ascoltatori, il controllo va, animazioni, definire le impostazioni internamente così via ..

Se sottoclasse Webview, si può semplicemente ignorare onTouchEvent per filtrare le spostare-eventi che attivano scorrimento.

public class SubWebView extends WebView {

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

studiando le risposte di cui sopra quasi ha funzionato per me ... ma ho ancora avuto un problema che ho potuto 'scappatella' la vista sul 2.1 (sembrava di essere fissato con 2.2 e 2.3).

qui è la mia soluzione finale

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

Questa dovrebbe essere la risposta completa. Come suggerito da @GDanger. Estendere WebView per ignorare i metodi di scorrimento e incorporare il WebView personalizzato all'interno di layout 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();
        }
    }
}

E poi incorporare nel file di layout come segue

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

Poi nel Attività, utilizzare alcuni metodi aggiuntivi per disabilitare le barre di scorrimento troppo.

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

Basta usare android:focusableInTouchMode="false" sul WebView .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top