157 votes

Puis-je avoir onScrollList

J'utilise un HorizontalScrollView dans une mise en page et je dois identifier si l'utilisateur a atteint le point de départ et le point d'arrivée du défilement.

Pour ListView J'ai essayé un onScrollListener et il est possible de trouver le point de départ et le point d'arrivée du défilement.

J'ai essayé de faire la même chose dans mon Scrollview mais il semble que ce ne soit pas possible. Existe-t-il d'autres moyens d'obtenir ce que je souhaite ?

414voto

Zbun Points 461

Chaque instance de View appelle getViewTreeObserver() . Maintenant, lorsque l'on tient une instance de ViewTreeObserver , vous pouvez ajouter un OnScrollChangedListener() à l'aide de la méthode addOnScrollChangedListener() .

Vous pouvez obtenir plus d'informations sur cette classe ici .

Il vous permet d'être au courant de chaque événement de défilement, mais sans les coordonnées. Vous pouvez les obtenir en utilisant getScrollY() ou getScrollX() de l'auditeur.

scrollView.getViewTreeObserver().addOnScrollChangedListener(new OnScrollChangedListener() {
    @Override
    public void onScrollChanged() {
        int scrollY = rootScrollView.getScrollY(); // For ScrollView
        int scrollX = rootScrollView.getScrollX(); // For HorizontalScrollView
        // DO SOMETHING WITH THE SCROLL COORDINATES
    }
});

62voto

wonderkid Points 578

Ça pourrait être très utile. Utilisez NestedScrollView au lieu de ScrollView. La bibliothèque de support 23.1 a introduit un OnScrollChangeListener à NestedScrollView. Donc vous pouvez faire quelque chose comme ça.

 myScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            Log.d("ScrollView","scrollX_"+scrollX+"_scrollY_"+scrollY+"_oldScrollX_"+oldScrollX+"_oldScrollY_"+oldScrollY);
            //Do something
        }
    });

21voto

ZaBlanc Points 2396

Voici un HorizontalScrollView dérivé que j'ai écrit pour gérer les notifications de défilement et de fin de défilement. Il gère correctement le fait qu'un utilisateur a cessé de faire défiler activement la page. et lorsqu'il décélère complètement après que l'utilisateur l'ait lâché :

public class ObservableHorizontalScrollView extends HorizontalScrollView {
    public interface OnScrollListener {
        public void onScrollChanged(ObservableHorizontalScrollView scrollView, int x, int y, int oldX, int oldY);
        public void onEndScroll(ObservableHorizontalScrollView scrollView);
    }

    private boolean mIsScrolling;
    private boolean mIsTouching;
    private Runnable mScrollingRunnable;
    private OnScrollListener mOnScrollListener;

    public ObservableHorizontalScrollView(Context context) {
        this(context, null, 0);
    }

    public ObservableHorizontalScrollView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();

        if (action == MotionEvent.ACTION_MOVE) {
            mIsTouching = true;
            mIsScrolling = true;
        } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
            if (mIsTouching && !mIsScrolling) {
                if (mOnScrollListener != null) {
                    mOnScrollListener.onEndScroll(this);
                }
            }

            mIsTouching = false;
        }

        return super.onTouchEvent(ev);
    }

    @Override
    protected void onScrollChanged(int x, int y, int oldX, int oldY) {
        super.onScrollChanged(x, y, oldX, oldY);

        if (Math.abs(oldX - x) > 0) {
            if (mScrollingRunnable != null) {
                removeCallbacks(mScrollingRunnable);
            }

            mScrollingRunnable = new Runnable() {
                public void run() {
                    if (mIsScrolling && !mIsTouching) {
                        if (mOnScrollListener != null) {
                            mOnScrollListener.onEndScroll(ObservableHorizontalScrollView.this);
                        }
                    }

                    mIsScrolling = false;
                    mScrollingRunnable = null;
                }
            };

            postDelayed(mScrollingRunnable, 200);
        }

        if (mOnScrollListener != null) {
            mOnScrollListener.onScrollChanged(this, x, y, oldX, oldY);
        }
    }

    public OnScrollListener getOnScrollListener() {
        return mOnScrollListener;
    }

    public void setOnScrollListener(OnScrollListener mOnEndScrollListener) {
        this.mOnScrollListener = mOnEndScrollListener;
    }

}

13voto

Cristan Points 398

Vous pouvez utiliser NestedScrollView au lieu de ScrollView . Cependant, si vous utilisez une Lambda Kotlin, elle ne saura pas que vous voulez que la fonction setOnScrollChangeListener au lieu de celui de View (qui est le niveau 23 de l'API). Vous pouvez résoudre ce problème en spécifiant le premier paramètre comme étant un NestedScrollView.

nestedScrollView.setOnScrollChangeListener { _: NestedScrollView, scrollX: Int, scrollY: Int, _: Int, _: Int ->
    Log.d("ScrollView", "Scrolled to $scrollX, $scrollY")
}

9voto

Keyhan Asghari Points 1502

Non, ScrollView ne fournit pas d'écouteur pour les événements de défilement, ni même de moyen de vérifier jusqu'où l'utilisateur a défilé. Vous devez donc créer une classe qui étend HorizontalScrollView et le modifier. ce lien peut vous aider.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X