web-dev-qa-db-fra.com

Puis-je faire défiler un ScrollView par programme dans Android?

Est-il possible de faire défiler un ScrollView par programme jusqu'à une certaine position?

J'ai créé un TableLayout dynamique qui est placé dans un ScrollView. Je souhaite donc que pour une action spécifique (comme cliquer sur un bouton, etc.), la ligne en question défile automatiquement vers la première position.

C'est possible?

135
AB1209
ScrollView sv = (ScrollView)findViewById(R.id.scrl);
sv.scrollTo(0, sv.getBottom());

ou

sv.scrollTo(5, 10);

157
Android

La réponse de Pragna ne fonctionne pas toujours, essayez ceci:

mScrollView.post(new Runnable() { 
        public void run() { 
             mScrollView.scrollTo(0, mScrollView.getBottom());
        } 
});

ou

mScrollView.post(new Runnable() { 
        public void run() { 
             mScrollView.fullScroll(mScrollView.FOCUS_DOWN);
        } 
});

si vous voulez faire défiler pour commencer

mScrollView.post(new Runnable() { 
        public void run() { 
             mScrollView.fullScroll(mScrollView.FOCUS_UP);
        } 
});
196
ercu

Je voulais que le scrollView défile directement après onCreateView () (pas après, par exemple, un clic de bouton). Pour que cela fonctionne, je devais utiliser un ViewTreeObserver:

mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mScrollView.post(new Runnable() {
                public void run() {
                    mScrollView.fullScroll(View.FOCUS_DOWN);
                }
            });
        }
    });

Mais attention, cela sera appelé à chaque fois que quelque chose sera mis en page (par exemple, si vous définissez une vue invisible ou similaire), alors n'oubliez pas de supprimer cet écouteur si vous n'en avez plus besoin avec:

public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) sur SDK Lvl <16

ou

public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) in SDK Lvl> = 16

34
patrickf

Utilisez quelque chose comme ceci:

mScrollView.scrollBy(10, 10);

ou

mScrollView.scrollTo(10, 10);
19
Srichand Yella

Il y a beaucoup de bonnes réponses ici, mais je veux seulement ajouter une chose. Il arrive parfois que vous souhaitiez faire défiler votre ScrollView vers une vue spécifique de la présentation, au lieu d'un défilement complet vers le haut ou le bas.

Un exemple simple: dans un formulaire d'inscription, si l'utilisateur clique sur le bouton "Inscription" lorsqu'un texte d'édition du formulaire n'est pas rempli, vous souhaitez accéder à ce texte d'édition spécifique pour indiquer à l'utilisateur qu'il doit remplir ce champ.

Dans ce cas, vous pouvez faire quelque chose comme ça:

scrollView.post(new Runnable() { 
        public void run() { 
             scrollView.scrollTo(0, editText.getBottom());
        } 
});

ou, si vous voulez un défilement régulier au lieu d’un défilement instantané:

scrollView.post(new Runnable() { 
            public void run() { 
                 scrollView.smoothScrollTo(0, editText.getBottom());
            } 
    });

Évidemment, vous pouvez utiliser n’importe quel type de vue au lieu de Modifier le texte. Notez que getBottom () renvoie les coordonnées de la vue en fonction de la disposition parent, de sorte que toutes les vues utilisées dans ScrollView doivent avoir uniquement un parent (par exemple, une disposition linéaire).

Si vous avez plusieurs parents dans l'enfant de ScrollView, la seule solution que j'ai trouvée consiste à appeler requestChildFocus sur la vue parent:

editText.getParent().requestChildFocus(editText, editText);

mais dans ce cas, vous ne pouvez pas avoir un défilement lisse.

J'espère que cette réponse peut aider quelqu'un avec le même problème.

18
Mattia Ruggiero

Essayez d’utiliser la méthode scrollToPlus d’informations

9
bluefalcon

Si vous voulez faire défiler instantanément, vous pouvez utiliser:

ScrollView scroll= (ScrollView)findViewById(R.id.scroll);
scroll.scrollTo(0, scroll.getBottom());

            OR

scroll.fullScroll(View.FOCUS_DOWN);

            OR

scroll.post(new Runnable() {            
    @Override
    public void run() {
           scroll.fullScroll(View.FOCUS_DOWN);              
    }
});

Ou si vous voulez faire défiler en douceur et lentement afin que vous puissiez utiliser ceci:

private void sendScroll(){
        final Handler handler = new Handler();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {Thread.sleep(100);} catch (InterruptedException e) {}
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        scrollView.fullScroll(View.FOCUS_DOWN);
                    }
                });
            }
        }).start();
    }
7
Maddy

Je dois faire ceci pour faire défiler au bas d'un ScrollView (avec un TextView à l'intérieur):

(Je mets ceci sur une méthode qui met à jour le TextView)

final ScrollView myScrollView = (ScrollView) findViewById(R.id.myScroller);
    myScrollView.post(new Runnable() {
    public void run() {
        myScrollView.fullScroll(View.FOCUS_DOWN);
    }
});
4
Ohiovr

Oui, vous pouvez.

Disons que vous avez un Layout et à l'intérieur de celui-ci, vous avez beaucoup de Views. Donc, si vous voulez faire défiler jusqu'à n'importe quel View par programme, vous devez écrire l'extrait de code suivant:

Par exemple.

content_main.xml

<ScrollView
    Android:id="@+id/scrollView"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content">

    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:orientation="vertical">

        <Button
            Android:id="@+id/btn"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content" />

        <TextView
            Android:id="@+id/txtView"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content" />

    </LinearLayout>
</ScrollView>

MainActivity.Java

ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
Button btn = (Button) findViewById(R.id.ivEventBanner);
TextView txtView = (TextView) findViewById(R.id.ivEditBannerImage);

Si vous voulez faire défiler jusqu'à View spécifique, disons txtview dans ce cas, écrivez simplement:

scrollView.smoothScrollTo(txtView.getScrollX(),txtView.getScrollY());

Et vous êtes fait..

4
Pankaj Lilan

** pour faire défiler à la hauteur désirée. J'ai trouvé une bonne solution **

                scrollView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        scrollView.scrollBy(0, childView.getHeight());
                    }
                }, 100);
3
Vikas Chauhan

Ajouter une autre réponse qui n'implique pas de coordonnées.

Cela amènera la vue souhaitée à se concentrer (mais pas à la position la plus haute):

  yourView.getParent().requestChildFocus(yourView,yourView);

public void RequestChildFocus (Afficher un enfant, Voir ciblé)

enfant - Enfant de ce ViewParent qui veut se concentrer. Cette vue contiendra la vue focalisée. Ce n'est pas nécessairement la vue qui a réellement le focus.

concentré - La vue qui est un descendant d'enfant qui a réellement le focus

3
Swas_99

juste page défiler:

ScrollView sv = (ScrollView) findViewById(your_scroll_view);
sv.pageScroll(View.FOCUS_DOWN);
3
Kirill Vashilo

Remarque: si vous êtes déjà dans un fil de discussion, vous devez créer un nouveau fil de discussion ou ne pas faire défiler la nouvelle hauteur jusqu'à la fin complète (pour moi). Pour ex:

void LogMe(final String s){
    runOnUiThread(new Runnable() {
        public void run() {
            connectionLog.setText(connectionLog.getText() + "\n" + s);
            final ScrollView sv = (ScrollView)connectLayout.findViewById(R.id.scrollView);
            sv.post(new Runnable() {
                public void run() {
                    sv.fullScroll(sv.FOCUS_DOWN);
                    /*
                    sv.scrollTo(0,sv.getBottom());
                    sv.scrollBy(0,sv.getHeight());*/
                }
            });
        }
    });
}
3
djdance

Tout le monde publie des réponses aussi compliquées.

J'ai trouvé une réponse facile, pour faire défiler vers le bas, bien:

final ScrollView myScroller = (ScrollView) findViewById(R.id.myScrollerView);

// Scroll views can only have 1 child, so get the first child's bottom,
// which should be the full size of the whole content inside the ScrollView
myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );

Et, si nécessaire, vous pouvez mettre la deuxième ligne de code, ci-dessus, dans un exécutable:

myScroller.post( new Runnable() {
    @Override
    public void run() {
        myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );
    }
}

Il m'a fallu beaucoup de recherches et de jeux pour trouver cette solution simple. J'espère que ça vous aide aussi! :)

2
Nalorin

J'utilisais le Runnable avec sv.fullScroll (View.FOCUS_DOWN); Cela fonctionne parfaitement pour le problème immédiat, mais cette méthode fait en sorte que ScrollView prenne le focus de tout l'écran, si vous faites qu'AutoScroll se produise à chaque fois, aucun EditText ne pourra recevoir d'informations de l'utilisateur, ma solution a été d'utiliser un code différent sous le runnable:

sv.scrollTo (0, sv.getBottom () + sv.getScrollY ());

faire la même chose sans perdre de vue les points de vue importants

salutations.

1
Sebasu
I had to create Interface

public interface ScrollViewListener {
    void onScrollChanged(ScrollViewExt scrollView, 
                         int x, int y, int oldx, int oldy);
}    

import Android.content.Context;
import Android.util.AttributeSet;
import Android.widget.ScrollView;

public class CustomScrollView extends ScrollView {
    private ScrollViewListener scrollViewListener = null;
    public ScrollViewExt(Context context) {
        super(context);
    }

    public CustomScrollView (Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public CustomScrollView (Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, l, t, oldl, oldt);
        }
    }
}




<"Your Package name ".CustomScrollView 
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:id="@+id/scrollView"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:focusableInTouchMode="true"
    Android:scrollbars="vertical">

    private CustomScrollView scrollView;

scrollView = (CustomScrollView)mView.findViewById(R.id.scrollView);
        scrollView.setScrollViewListener(this);


    @Override
    public void onScrollChanged(ScrollViewExt scrollView, int x, int y, int oldx, int oldy) {
        // We take the last son in the scrollview
        View view = (View) scrollView.getChildAt(scrollView.getChildCount() - 1);
        int diff = (view.getBottom() - (scrollView.getHeight() + scrollView.getScrollY()));

        // if diff is zero, then the bottom has been reached
        if (diff == 0) {
                // do stuff
            //TODO keshav gers
            pausePlayer();
            videoFullScreenPlayer.setVisibility(View.GONE);

        }
    }
0
Keshav Gera

ça marche pour moi

mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mScrollView.post(new Runnable() {
                public void run() {
                    mScrollView.fullScroll(View.FOCUS_DOWN);
                }
            });
        }
    });
0
ali asadi
private int totalHeight = 0;

ViewTreeObserver ScrollTr = loutMain.getViewTreeObserver();
ScrollTr.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            loutMain.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        } else {
            loutMain.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
        TotalHeight = loutMain.getMeasuredHeight();

    }
});

scrollMain.smoothScrollTo(0, totalHeight);
0
Maahi Patel