Désactiver le défilement dans la vue Web?

Jusqu’à présent, je n’étais qu’un développeur d’iPhone et maintenant j’ai décidé de donner un tour d’horizon à Android. Quelque chose que je n’ai pas pu comprendre sur Android, c’est comment empêcher par programmation le défilement dans une WebView ?

Quelque chose de similaire à la prévention des iPhones de l’événement onTouchMove serait génial!

Voici mon code pour désactiver tout le défilement dans la vue Web:

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

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

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

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

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

Vous pouvez également essayer d’ emballer votre vue Web en faisant défiler verticalement la vue et en désactivant tout le défilement de la vue Web:

    

Et mettre

 webview.setScrollContainer(false); 

N’oubliez pas d’append le webview.setOnTouchListener(...) ci-dessus pour désactiver tout défilement dans la vue Web. Le ScrollView vertical permettra de faire défiler le contenu de WebView.

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

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

Faire en sorte que WebView ignore les événements de mouvement est la mauvaise façon de s’y prendre. Que faire si WebView besoin d’entendre parler de ces événements?

Au lieu de cela, sous-classe WebView et remplacez les méthodes de défilement non privées.

 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 la source pour WebView vous pouvez voir que onTouchEvent appelle doDrag qui appelle overScrollBy .

L’ajout des détails de marge au corps empêchera le défilement si votre contenu est correctement encapsulé, comme suit:

  

Assez facile, et beaucoup moins de code + bug supplémentaire 🙂

Définissez un écouteur sur votre WebView:

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

Je n’ai pas essayé ceci car je n’ai pas encore rencontré ce problème, mais peut-être pourriez-vous surpasser la fonction onScroll?

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

Ma solution sale, mais facile à mettre en oeuvre et qui fonctionne bien:

Il suffit de mettre la vue Web dans une vue de défilement. Rendre la vue Web beaucoup plus volumineuse que le contenu possible (dans une ou les deux dimensions, en fonction des besoins). ..et mettre en place la barre de défilement de la scrollview comme vous le souhaitez.

Exemple pour désactiver la barre de défilement horizontale sur une vue Web:

    

J’espère que ça aide 😉

Pour Disbale scroll utilisez ceci

webView.setOnTouchListener (nouveau View.OnTouchListener () {

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

Ce n’est peut-être pas la source de votre problème, mais j’ai passé des heures à essayer de comprendre pourquoi mon application fonctionnait bien sur l’iPhone, ce qui obligeait le navigateur Android à constamment déplacer les barres de défilement verticales et horizontales. J’avais une balise de corps HTML avec la hauteur et la largeur réglées à 100% et le corps était rempli de différentes balises à différents endroits. Quels que soient mes essais, les navigateurs Android afficheraient leurs barres de défilement et déplaceraient un peu la page, en particulier lors d’un balayage rapide. La solution qui a fonctionné pour moi sans avoir à faire quoi que ce soit dans un APK était d’append ce qui suit à la balise body:

 leftmargin="0" topmargin="0" 

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

Si vous sous-classe Webview, vous pouvez simplement remplacer onTouchEvent pour filtrer les événements de déplacement 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); } ... 

J’ai résolu le scintillement et le défilement automatique par:

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

Cependant, si cela ne fonctionne toujours pas pour une raison quelconque, créez simplement une classe qui étend WebView et mettez cette méthode 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 de fournir un contrôle plus efficace, comme activer / désactiver les balayages, activer / désactiver les touches, les écouteurs, les transitions de contrôle, les animations, définir les parameters en interne, etc.

étudier les réponses ci-dessus a presque fonctionné pour moi … mais j’avais toujours un problème que je pouvais “jeter” la vue sur 2.1 (semblait être corrigé 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, AtsortingbuteSet 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); } } 

// Désactive tout le défilement

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

// Désactive le défilement horizontal uniquement

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

// Désactiver le défilement vertical uniquement

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

Dans mon cas, la valeur seuil était de 20

Cela devrait être la réponse complète. Comme suggéré par @GDanger. Étendez WebView pour remplacer les méthodes de défilement et incorporer la vue Web personnalisée dans XML de présentation.

 public class ScrollDisabledWebView extends WebView { private boolean scrollEnabled = false; public ScrollDisabledWebView(Context context) { super(context); initView(context); } public ScrollDisabledWebView(Context context, AtsortingbuteSet atsortingbuteSet) { super(context, atsortingbuteSet); 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

  

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

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

Utilisez simplement android:focusableInTouchMode="false" sur votre webView .