web-dev-qa-db-fra.com

Scrollview Android surScrollChanged

J'ai un contenu fixe dans ma vue de texte à l'intérieur d'une vue de défilement. Lorsque l'utilisateur fait défiler jusqu'à une certaine position, j'aimerais commencer une activité ou déclencher une Toast.

<ScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
 Android:layout_width="fill_parent" Android:layout_height="fill_parent"
 Android:id="@+id/scroller">
 <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
  Android:orientation="vertical" Android:layout_width="fill_parent"
  Android:layout_height="fill_parent">
  <TextView Android:layout_width="fill_parent" Android:id="@+id/story"
   Android:layout_height="wrap_content" Android:text="@string/lorem"
   Android:gravity="fill" />
 </LinearLayout>
</ScrollView>

Mon problème est de mettre en œuvre la méthode protégée onScrollChanged pour connaître la position de la vue de défilement.

J'ai trouvé ceci réponse, y a-t-il une solution plus facile à cela plutôt que de déclarer une interface, de passer outre le scrollview, etc. comme on le voit sur le lien que j'ai posté?

22
SteD

Non.

ScrollView ne fournit pas d'écouteur pour les événements de défilement ni même un moyen de vérifier jusqu'à quel point l'utilisateur a fait défiler l'écran. Vous devez donc suivre les indications du lien.

12
Computerish

Il existe un moyen beaucoup plus facile que de sous-classer la ScrollView. L'objet ViewTreeObserver de la ScrollView peut être utilisé pour écouter les parchemins.

Puisque l'objet ViewTreeObserver peut changer pendant la durée de vie de la ScrollView, nous devons enregistrer une OnTouchListener sur la ScrollView pour qu'elle soit ViewTreeObserver au moment du défilement.

final ViewTreeObserver.OnScrollChangedListener onScrollChangedListener = new
                           ViewTreeObserver.OnScrollChangedListener() {

    @Override
    public void onScrollChanged() {
        //do stuff here 
    }
};

final ScrollView scrollView = (ScrollView) findViewById(R.id.scroller);
scrollView.setOnTouchListener(new View.OnTouchListener() {
    private ViewTreeObserver observer;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (observer == null) {
            observer = scrollView.getViewTreeObserver();
            observer.addOnScrollChangedListener(onScrollChangedListener);
        }
        else if (!observer.isAlive()) {
            observer.removeOnScrollChangedListener(onScrollChangedListener);
            observer = scrollView.getViewTreeObserver();
            observer.addOnScrollChangedListener(onScrollChangedListener);
        }

        return false;
    }
});
48

Cette question est assez ancienne, mais au cas où quelqu'un passerait (comme moi):

À partir de API 23, la variable View d'Android a une variable OnScrollChangeListener et le paramètre de configuration correspondant .

Le NestedScrollView de la bibliothèque Support prend également en charge la définition d'un écouteur de défilement avant même le niveau de l'API. Autant que je sache, NestedScrollView peut être utilisé en remplacement de la ScrollView normale sans aucun problème.

9
Lovis

En réalité, il existe un moyen de savoir dans quelle mesure l'utilisateur a fait défiler l'écran. La méthode getScrollY () de ScrollView vous le dit.

8
tulio84z

J'ai étendu mon scrollView. Ce lien peut aider.

class MyScroll extends ScrollView {
    boolean onTop=true;
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        //Log.d(TAG, "scroll changed: " + this.getTop() + " "+t);
        if(t <= 0){
            onTop = true;
            //Log.d(TAG, "scroll top: " + t);
            super.onScrollChanged(l, t, oldl, oldt);
            return;
            // reaches the top end
        }
        onTop = false;

        View view = (View) getChildAt(getChildCount()-1);
        int diff = (view.getBottom()-(getHeight()+getScrollY()+view.getTop()));// Calculate the scrolldiff
        if( diff <= 0 ){
            // if diff is zero, then the bottom has been reached
        }
        super.onScrollChanged(l, t, oldl, oldt);
    }
}
2
Ovechkin Pavel

NestedScrollView est semblable à Android.widget.ScrollView, mais il prend en charge le rôle de parent et d'enfant de défilement imbriqué sur les versions nouvelles et anciennes d'Android.

1er - Utilisez la liaison NestedScrollView à la place de ScrollView

2ème - Définissez le programme d'écoute de défilement, comme celui-ci, pour détecter l'axe Y se déplaçant pour un en-têteVue par exemple

    nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {

        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            Log.d(TAG, "onScrollChangeForY - scrollY: " + scrollY + " oldScrollY: " + oldScrollY);

            int MOVE = -1, SCROLL_UP = 0, SCROLL_DOWN = 1;
            float initialPositionY = headerView.getY();

            MOVE = scrollY > oldScrollY ? SCROLL_UP : SCROLL_DOWN;

            if (MOVE == SCROLL_UP) {

                int incrementY = scrollY - oldScrollY;

                headerView.setY(initialPositionY - incrementY);

            } else {

                int incrementY = oldScrollY - scrollY;

                headerView.setY(initialPositionY + incrementY);
            }
        }
    });
1
Javier Amor Penas

vous pouvez utiliser ce déclencheur pour afficher Toast ou Démarrer l'activité

 scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {
             // do something when Scroll  
        }
    });
0
yousef

Il suffit d'utiliser NestedScroll et NestedScroll.setOnScrollChangeListener().

0
Kai Wang

Il existe un composant prêt à l'emploi , qui permet d'écouter les événements de défilement de vues arbitraires sous Android. En interne, ce composant ajoute l'écouteur d'événements de défilement ViewTreeObserver sur les appareils dotés d'une ancienne API Android (similaire à celle proposée dans la réponse de Shubhadeep Chaudhuri) et l'écouteur Afficher les événements de défilement sur les appareils dotés d'une nouvelle API Android (API de niveau 23+). 

0
Denis

À partir de l'API 23 Android M, vous pouvez utiliser OnScrollChangeListener.

 scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
        @Override
        public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            //work with parameters
        }
    });
0