Android scrollview onScrollChanged

j'ai un contenu fixe dans ma vue texte à l'intérieur d'une vue parchemin. Lorsque l'utilisateur passe à une certaine position, je voudrais démarrer une activité ou déclencher un 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 trouver la position de la vue de défilement.

j'ai trouvé cette réponse, est-il une solution plus facile à cela plutôt que de déclarer une interface, over ride le scrollview etc comme vu sur le lien que j'ai posté?

22
demandé sur Vadim Kotov 2010-11-24 05:48:38

10 réponses

Pas de.

ScrollView ne fournit pas d'écouteur pour les événements de défilement ou même un moyen de vérifier jusqu'où l'Utilisateur a défiler, donc vous devez faire ce qui est suggéré par le lien.

12
répondu Computerish 2010-11-24 03:46:38

il y a un moyen beaucoup plus facile que de sous-classer le ScrollView . L'objet ViewTreeObserver du ScrollView peut être utilisé pour écouter les rouleaux.

étant donné que l'objet ViewTreeObserver pourrait changer pendant la durée de vie du ScrollView , nous devons enregistrer un OnTouchListener sur le ScrollView pour obtenir le ViewTreeObserver au moment du rouleau.

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
répondu Shubhadeep Chaudhuri 2015-01-13 08:27:10

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

commençant par API 23 , le View D'Android a un OnScrollChangeListener et le setter correspondant .

le NestedScrollView de la bibliothèque de soutien prend également en charge la définition d'un écouteur de parchemin avant même le niveau de L'API. Pour autant que je sache, NestedScrollView peut être utilisé en remplacement de la normal ScrollView sans aucun problème.

9
répondu Lovis 2016-12-05 10:00:24

en fait, il y a un moyen de savoir jusqu'à quel point l'Utilisateur a roulé. La méthode getScrollY () de ScrollView vous le dit.

8
répondu tulio84z 2012-04-16 10:58:34

j'ai prolongé mon scrollView. ce lien peut vous 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
répondu Ovechkin Pavel 2016-04-18 15:39:33

NestedScrollView est exactement comme android.widget.ScrollView, mais il prend en charge agir à la fois un parent de défilement imbriqué et l'enfant sur les deux nouvelles et anciennes versions D'Android.

1ère Utilisation NestedScrollView plutôt la liaison ScrollView

2e Set de Défilement à l'écoute, comme ça, pour détecter le déplacement de l'axe Y pour un headerView 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
répondu Javier Amor Penas 2017-12-12 14:01:26

il est composant prêt à l'emploi , qui aide à écouter les événements de défilement de vues arbitraires sur Android. En interne, ce composant ajoute L'auditeur de scroll events de ViewTreeObserver sur les appareils avec L'ancienne API Android (similaire à celle proposée dans la réponse de Shubhadeep Chaudhuri) et L'auditeur de scroll events de View scroll sur les appareils avec la nouvelle API Android (niveau API 23+).

0
répondu Denis 2017-06-13 02:50:52

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

0
répondu Kai Wang 2017-10-24 06:42:22

à partir de 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
répondu S.D.N Chanaka Fernando 2017-11-28 06:48:25

vous pouvez utiliser ce déclencheur pour montrer Toast ou démarrer L'activité

 scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {
             // do something when Scroll  
        }
    });
0
répondu yousef 2018-03-26 13:21:07