2

I have Scrollview cover many element inside. And I want to check if scrollview is scroll to the bottom of scrool. How to implement that. please any one recomment me. Thanks.

<ScrollView
    android:id="@+id/scrollview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true" >

        <LinearLayout
            android:id="@+id/layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:showDividers="end|middle" >
                <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="
                 text.......
               " />
               <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="
                  text.......
              " />
        </LinearLayout>
    </ScrollView>
Ashwani Kumar
  • 1,402
  • 1
  • 19
  • 26
Angkor Empire
  • 221
  • 2
  • 5
  • 11

3 Answers3

3

Create a custom scrollview as follow:

public class CustomScrollView extends ScrollView { OnBottomReachedListener mListener;

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

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

    public CustomScrollView(Context context) {
    super(context);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    View view = getChildAt(getChildCount() - 1);
    int diff = (view.getBottom() - (getHeight() + getScrollY())) -  view.getPaddingBottom();

    if (diff <= 0 && mListener != null) {
        mListener.onBottomReached();
    }

    super.onScrollChanged(l, t, oldl, oldt);
    }

    // Getters & Setters

    public OnBottomReachedListener getOnBottomReachedListener() {
    return mListener;
    }

    public void setOnBottomReachedListener(
        OnBottomReachedListener onBottomReachedListener) {
    mListener = onBottomReachedListener;
    }

    //Event listener.

    public interface OnBottomReachedListener {
    public void onBottomReached();
    }
}

In your main activity:

CustomScrollView scrollView = (CustomScrollView) findViewById(R.id.scrollView);

scrollView.setOnBottomReachedListener(new CustomScrollView.OnBottomReachedListener() {

        @Override
        public void onBottomReached() {
            // ScrollView Reached bottom
        }
    });

In your xml file:

    <CustomScrollView 
        android:id="@+id/scrollView" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" >

    </CustomScrollView>
Fernando Barbosa
  • 321
  • 4
  • 20
Patrick R
  • 6,621
  • 1
  • 24
  • 27
  • error activity ComponentInfo{kh.com.iknow.scrolllistener/kh.com.iknow.scrolllistener.MainActivity}: android.view.InflateException: Binary XML file line #13: Error inflating class CustomScrollView – Angkor Empire Dec 05 '16 at 02:34
  • In your xml you have to put the full path of your CustomScrollView. For example; i have put my CustomScrollView in com.mysample.customviews package then i have to write – Patrick R Dec 05 '16 at 06:15
0

You can do this by comparing the height of ScrollView and your LinearLayout:

ScrollView scrollView = (ScrollView) findViewById(R.id.scrollview);
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.layout);

if(linearLayout.getMeasuredHeight() <= scrollView.getScrollY() +
       scrollView.getHeight()) {
    //scroll view is at the very bottom
}
else {
    //scroll view is in somewhere middle
}
Ashwani Kumar
  • 1,402
  • 1
  • 19
  • 26
0

Not saying mine is perfect but it is quick, dirty and it works. It is based on the fact that once you slow down, the recycler state will go to 'settling' but this by itself is not good enough as this will fire anytime a scroll ends. Thus we add the 500 ms check because once you hit the bottom, the 'onScrolled' function stops firing as you are technically not scrolling and will stop updating the time.

        generic_list_frag_recycler_view.addOnScrollListener(object : RecyclerView.OnScrollListener(){
        private var lastPositiveScroll: Long = SystemClock.uptimeMillis()
        // This was implemented to take out the possibility of scrolling up and stopping at the top (negative dy value)
        private var lastScrollWasPositive = false
        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            super.onScrolled(recyclerView, dx, dy)
            Timber.d("Scrolled dy: $dy")
            if(dy > 0){
                lastPositiveScroll = SystemClock.uptimeMillis()
                lastScrollWasPositive = true
            }else{
                lastScrollWasPositive = false
            }
        }

        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)
            if(lastScrollWasPositive && newState == RecyclerView.SCROLL_STATE_SETTLING && (SystemClock.uptimeMillis() - lastPositiveScroll > 500)){
                Timber.d("User reached bottom of list!")
                onUserScrollToBottom.invoke()
            }
        }
    })
Derwrecked
  • 771
  • 1
  • 6
  • 17