Question

Jusqu'à présent, je suis un développeur iPhone uniquement et maintenant j'ai décidé de donner un tourbillon Android. Quelque chose que je ne l'ai pas été en mesure de trouver sur Android est comment empêcher le défilement dans un programme WebView?

Quelque chose de similaire à la prévention de l'iPhone de l'événement onTouchMove serait génial!

Était-ce utile?

La solution

Voici mon code pour désactiver le défilement tous dans WebView:

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

Pour que masquer les barres de défilement, mais pas désactiver le défilement:

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

ou vous pouvez essayer d'utiliser mise en page d'une seule colonne , mais cela ne fonctionne qu'avec des pages simples et il désactive le défilement horizontal:

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

Vous pouvez également essayer de envelopper votre WebView avec scrollview défilement vertical et désactiver tout le défilement sur le 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>

set

webview.setScrollContainer(false);

Ne pas oublier d'ajouter le code webview.setOnTouchListener(...) ci-dessus pour désactiver le défilement dans tout le WebView. La ScrollView verticale permettra de faire défiler du contenu du WebView.

Autres conseils

Je ne sais pas si vous avez encore besoin ou non, mais voici la solution:

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

Faire la WebView ignorer les événements de mouvement est la mauvaise façon de s'y prendre. Que faire si le WebView a besoin d'entendre parler de ces événements?

WebView lieu la sous-classe et remplacer les méthodes de défilement non-privé.

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 vous regardez le Source pour WebView vous pouvez voir que les appels onTouchEvent doDrag qui appelle overScrollBy .

Ajout des détails de marge au corps empêchera le défilement si votre contenu correctement enveloppe, comme ceci:

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

Assez facile, et un code beaucoup moins + bug frais généraux:)

Définir un écouteur sur votre WebView:

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

Je ne l'ai pas essayé ce que j'ai encore rencontré ce problème, mais vous pourriez peut-être overrive la fonction OnScroll?

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

Mon sale, mais facile à mettre en œuvre la solution et fonctionne bien:

Il suffit de mettre le WebView dans un scrollview. Faites le WebView est beaucoup trop grand que le contenu possible (en une ou deux dimensions, en fonction des besoins). ..et mis en place la barre de défilement du scrollview (s) que vous le souhaitez.

Exemple de désactiver la barre de défilement horizontal sur 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>

J'espère que cette aide;)

Pour désactiver ce défilement Utilisez

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

Cela peut ne pas être la source de votre problème, mais j'ai passé des heures à essayer de retrouver pourquoi mon application qui fonctionne bien sur l'iPhone que le navigateur Android pour jeter constamment les barres de défilement verticales / horizontales et déplacer réellement la page. J'ai eu une balise body html avec la hauteur et la largeur fixée à 100%, et le corps était plein de différentes balises dans des endroits différents. Peu importe ce que j'ai essayé, les navigateurs Android montreraient leurs barres de défilement et déplacer la page un peu, surtout lorsque vous faites un simple glissement rapide. La solution qui a fonctionné pour moi sans avoir rien à faire dans un APK était d'ajouter ce qui suit à la balise body:

leftmargin="0" topmargin="0"

Il semble que les marges par défaut pour la balise body ont été appliquées sur le droïde mais ignoré sur l'iphone

Je résolu le scintillement et le défilement automatique par:

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

Toutefois, si cela ne fonctionne toujours pas pour une raison quelconque, il suffit de faire une classe qui étend WebView, et de mettre cette méthode là-dessus:

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

Je suggère d'étendre WebView, afin d'assurer un contrôle plus efficace, comme désactiver / activer swipes, activer / désactiver les touches, les auditeurs, les transitions de contrôle, des animations, définir les paramètres en interne ainsi de suite ..

Si vous sous-classe Webview, vous pouvez simplement remplacer onTouchEvent pour filtrer les déplacer-événements qui déclenchent le défilement.

public class SubWebView extends WebView {

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

étudier les réponses ci-dessus presque fonctionné pour moi ... mais j'avais encore un problème que je pouvais « jeter » la vue sur 2.1 (semblait être fixé avec 2,2 et 2,3).

voici ma solution 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);
}
}

Cela devrait être la réponse complète. Comme l'a suggéré @GDanger. Étendre WebView pour remplacer les méthodes de défilement et intégrer le WebView personnalisé dans les mise en page 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();
        }
    }
}

Et puis incorporer dans le fichier de mise en page comme suit

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

Ensuite, dans l'activité, utilisez des méthodes supplémentaires pour désactiver les barres de défilement trop.

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

Il suffit d'utiliser android:focusableInTouchMode="false" sur votre webView .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top