NestedScrollView setOnScrollChangeListener api 21
Asked Answered
K

4

12

Hello folks I'm trying to handle an onScrolled event in my recyclerView, that's inside a NestedScrollView.

So far, I have found setOnScrollChangeListener, however this method is API 23, and I'm targeting API 21, any idea to handle this issue back in API 21?

Kessia answered 14/4, 2018 at 13:37 Comment(0)
K
3

After some time I got an idea, I've stopped listening to scroll on RecyclerView and started listening to NestedScrollView onScroll event.

I managed to make my loadOnDemand recyclerView using this snippet

    nsv_posts_timeline.setOnScrollChangeListener(
            NestedScrollView.OnScrollChangeListener {
                                _, scrollX, scrollY, _, oldScrollY ->

        if(scrollY > oldScrollY){
            val totalItens = timelineAdapter.itemCount

            val currentView = rv_timeline.findChildViewUnder(scrollX.toFloat(), scrollY.toFloat())
            val childPosition = rv_timeline.getChildAdapterPosition(currentView)

            if((totalItens/2) - (stepSize/2) <= childPosition && !isLoading){
                isLoading = true
                                          //skip , take
                timelinePresenter.loadMore(totalItens, 5)
            }
        }
    })

isLoading is a class property that I change to false when my callback returns from server

Kessia answered 14/4, 2018 at 22:28 Comment(0)
G
26

I think you are using setOnChangeScrollListener with View.OnScrollChangeListener. Please use NestedScrollView.OnScrollChangeListener like that:

 scvProduct.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
        @Override
        public void onScrollChange(NestedScrollView nestedScrollView,int scrollX, int scrollY, int oldScrollX, int oldScrollY) {

            Log.e("ProductFragment","position button " + topPositionButton + " scrollY " + scrollY);
            if(scrollY > oldScrollY){
                Log.e("ProductFragment","down");
            }
            else{
                Log.e("ProductFragment","up");
            }
        }
    });

image compare NestedScrollview and View OnScrollChangeListener

Gulfweed answered 21/4, 2019 at 4:17 Comment(0)
R
3

You can achieve that using ViewTreeObserver#addOnScrollChangedListener() below api 23:

mRecylerview.getViewTreeObserver().addOnScrollChangedListener(
    new ViewTreeObserver.OnScrollChangedListener() {
      @Override public void onScrollChanged() {
          int x = toolbar.getScrollX();
          int y = toolbar.getScrollY();
      }
    });
Ronnaronnholm answered 14/4, 2018 at 15:21 Comment(1)
I'm inside a fragment, any idea how to get Y from fragment?Kessia
K
3

After some time I got an idea, I've stopped listening to scroll on RecyclerView and started listening to NestedScrollView onScroll event.

I managed to make my loadOnDemand recyclerView using this snippet

    nsv_posts_timeline.setOnScrollChangeListener(
            NestedScrollView.OnScrollChangeListener {
                                _, scrollX, scrollY, _, oldScrollY ->

        if(scrollY > oldScrollY){
            val totalItens = timelineAdapter.itemCount

            val currentView = rv_timeline.findChildViewUnder(scrollX.toFloat(), scrollY.toFloat())
            val childPosition = rv_timeline.getChildAdapterPosition(currentView)

            if((totalItens/2) - (stepSize/2) <= childPosition && !isLoading){
                isLoading = true
                                          //skip , take
                timelinePresenter.loadMore(totalItens, 5)
            }
        }
    })

isLoading is a class property that I change to false when my callback returns from server

Kessia answered 14/4, 2018 at 22:28 Comment(0)
A
0

Thanks to @NhatVM in Kotlin:

scrollView.setOnScrollChangeListener(
    NestedScrollView.OnScrollChangeListener { nestedScrollView, scrollX, scrollY, oldScrollX, oldScrollY ->
        // ...
    }
)
Adjectival answered 19/10, 2021 at 15:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.