Search code examples
androidandroid-recyclerviewswiperefreshlayoutandroid-overscoll

Overscroll effect from bottom not appearing when using RecyclerView inside SwipeRefreshLayout


I am trying to make a list with the nice pull to refresh feature but when I have a RecyclerView inside an SwipeRefreshLayout the overscroll effect only works when it is refreshing. Even for the bottom of the list. What happens is that the user don't have that visual cue that the list has ended.

Here's my XML:

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipe_refresh"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_vew"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</android.support.v4.widget.SwipeRefreshLayout>

And the Class from the Fragment:

public class MyListFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
    private SwipeRefreshLayout swipeRefreshLayout;
    private RecyclerView recyclerView;


    static final String[] lines = new String[]{
        "this is line #1",
        "this is line #2"
        "this is line #3"
        "this is line #4"
        "this is line #5"
        "this is line #6"
        "this is line #7"
    };

    @Override
    public void onRefresh() {
        Log.i("QUESTION_LIST_REFRESH", "onRefresh called from SwipeRefreshLayout");
        new Handler().postDelayed(new Runnable() {
            @Override public void run() {
                swipeRefreshLayout.setRefreshing(false);
            }
        }, 4000);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        recyclerView = (RecyclerView) view.findViewById(R.id.questions_list);

        swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_question_list);
        swipeRefreshLayout.setOnRefreshListener(this);
        swipeRefreshLayout.setColorSchemeColors(
                ContextCompat.getColor(getContext(),R.color.colorPrimaryDark),
                ContextCompat.getColor(getContext(),R.color.colorAccent));

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_list, container, false);

        recyclerView = (RecyclerView) view.findViewById(R.id.recycler_vew);
        recyclerView.setHasFixedSize(true);

        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(layoutManager);


        recyclerView.setAdapter(new MyListAdapter(lines));

        return view;
    }
}

Solution

  • you can enable the refreshing when the recyclerview has reached to its top position. Will this solve your problem?

        rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
    
    
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
    
                try {
    
                    LinearLayoutManager layoutManager = ((LinearLayoutManager) rv.getLayoutManager());
                    int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();
    
    
                    Log.e("refresh", "State - " + newState + " : firstVisiblePosition" + firstVisiblePosition);
                    if (firstVisiblePosition == 0)
                        pullToRefresh.setEnabled(true);
                    else
                        pullToRefresh.setEnabled(false);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    });