Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I detect OverScroll in android RecyclerView?

I have tried to overwrite onOverScrolled() but it is not triggered:

public class MyRecyclerView extends RecyclerView {
    public MyRecyclerView(@NonNull Context context) {
        super(context);
    }

    public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
        Toast.makeText(getContext(), "overScrolled", Toast.LENGTH_SHORT).show();
    }
}

My RecyclerView has recyclerView.setOverScrollMode(View.OVER_SCROLL_ALWAYS);

like image 491
Ivan Avatar asked May 30 '19 13:05

Ivan


2 Answers

Try this to find bottom overscroll and top overscroll

Find bottom overscroll and top overscroll Using LayoutManager

import android.os.Bundle;
import java.util.ArrayList;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

public class MainActivity extends AppCompatActivity {

    RecyclerView myRecyclerView;
    ArrayList<String> arrayList = new ArrayList<>();
    DataAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        myRecyclerView = findViewById(R.id.myRecyclerView);

        LinearLayoutManager linearLayoutManager= new LinearLayoutManager(this){
            @Override
            public int scrollVerticallyBy ( int dx, RecyclerView.Recycler recycler, RecyclerView.State state ) {
                int scrollRange = super.scrollVerticallyBy(dx, recycler, state);
                int overScroll = dx - scrollRange;
                if (overScroll > 0) {
                    Utils.printLog("NILU_PILU :-> BOTTOM OVERSCROLL");
                } else if (overScroll < 0) {
                    Utils.printLog("NILU_PILU :-> TOP OVERSCROLL");
                }
                return scrollRange;
            }
        };
        myRecyclerView.setLayoutManager(linearLayoutManager);
        myRecyclerView.setHasFixedSize(true);

        addDataToList();

        adapter = new DataAdapter(this, arrayList);
        myRecyclerView.setAdapter(adapter);

    }

    private void addDataToList() {
        for (int i = 0; i < 50; i++) {
            arrayList.add("NILU_PILU :-> " + i);
        }
    }

}

Find bottom overscroll Using RecyclerView.addOnScrollListener()

 myRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);

            if (dy > 0) {

                int pos = linearLayoutManager.findLastVisibleItemPosition();
                int numItems = myRecyclerView.getAdapter().getItemCount();

                if (pos >= numItems - 1 ) {
                    Utils.printLog("NILU_PILU :-> BOTTOM OVERSCROLL");
                }
            }
        }
    });
like image 59
AskNilesh Avatar answered Oct 11 '22 14:10

AskNilesh


Here is a solution I found on reddit:

Instead of a custom recyclerview, you create a custom LinearLayoutManager and just overwrite your layout managers scrollVerticallyBy() method and check if dx/dy minus the value returned by the super implementation is != 0. Then overscroll has occured.

@Override
public int scrollVerticallyBy ( int dx, RecyclerView.Recycler recycler, 
RecyclerView.State state ) {
    int scrollRange = super.scrollVerticallyBy(dx, recycler, state);
    int overscroll = dx - scrollRange;
    if (overscroll > 0) {
        // bottom overscroll
    } else if (overscroll < 0) {
        // top overscroll
    }
    return scrollRange;
}
like image 28
Ridcully Avatar answered Oct 11 '22 13:10

Ridcully