5

I need help with the onscroll method...So Iwe tried a couple of things I found on stackoverflow but most of them work for linearlayout etc. Would be mighty helpful if you could point me in the right direction...

Im using the instagram api to load pictures. it sends 20 pictures at a time so i need to load more as i get to the bottom of the page

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

        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
        //configViews();
//        mLayoutManager = new GridLayoutManager(this, 2);
//        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {


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



            }
        });

....
}
Hasan Nagaria
  • 253
  • 6
  • 16

4 Answers4

9

Add this in OnScrolled.This is the basic idea.You can modify it as per your requirement

if(dy > 0){ // only when scrolling up

    final int visibleThreshold = 2;

    GridLayoutManager layoutManager = (GridLayoutManager)recyclerview.getLayoutManager();
    int lastItem  = layoutManager.findLastCompletelyVisibleItemPosition();
    int currentTotalCount = layoutManager.getItemCount();

    if(currentTotalCount <= lastItem + visibleThreshold){
        //show your loading view 
        // load content in background

    }
}
Ravi Theja
  • 3,371
  • 1
  • 22
  • 34
  • This seems to be working pretty well and it might work as a temp but it seems a little jerky. Like as soon as I get to the bottom...I really was hoping for a slower transition instead as per the code obviously...i get completely new data filled in all the grids. – Hasan Nagaria Feb 27 '16 at 19:59
  • I have one more question...Im new with recyclerview and android in general so at what point in the code am I reusing or recycling my views? – Hasan Nagaria Feb 27 '16 at 20:00
  • Also...one more thing... I have these two lines of code at the top of my oncreate mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView); mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2)); – Hasan Nagaria Feb 27 '16 at 20:06
  • so is it wise for me to have another layout manager inside the on scroll? – Hasan Nagaria Feb 27 '16 at 20:06
  • As i said you need to make some changes as per your requirement.The layout manager in onscroll is not a new object..it is reference to previously set layout manager.so it is ok to use it in Onscroll.if this solved the problem feel free to accept the solution :p – Ravi Theja Feb 27 '16 at 21:11
1

The logic of infinite scroll can be in the adaptor. Like that:

  • Return size + 1 in your adaptor (for loading view)
  • When the last position are asked, return a view that indicate loading
  • Run a background task that will download next elements and change data in the adaptor

You can load next elements before last element are showed too.

Kevin Robatel
  • 8,025
  • 3
  • 44
  • 57
0

Kevin Robatel got it right. Better way to handle infinite scrolling is in the adapter.See this answer Sabeer Mohammed. Try this out:

In the adapter create an interface as such

  public interface OnLoadMoreListener {
    void onLoadMore();
}

Implement this interface in the activity where data is being fetched and override onLoadMore().

@Override
public void onLoadMore() {
   //fetch data here
}

Back in the adapter in onBindViewHolder(). Write this condition.

// this checks that the last item in the recyclerView has been reached
// if so, calls onLoadMore()
if ((position >= getItemCount() - 1)) {
         loadMoreListener.onLoadMore();
}

But this solution has a problem and that is because the recyclerView has been scrolled down therefore the condition in onBindViewHolder() will always be met until scrolled up manually. So onLoadMore() will keep getting called. Also all previous data will be lost.

To avoid that keep your data in a List in the adapter. Try something like this:

public void setResultList(List<String> resultList) {
    this.resultList.addAll(resultList);
    notifyDataSetChanged();
}

Here use the addAll() to add the new List to the previous one. This will not only retain the previous data but also add the new one.

Remember to call setResultList() in the activity when new data is recived. Something like this: (Here i'm using a Loader)

@Override
public void onLoadFinished(Loader<String> loader, String data) {
    if (data != null) {
        someAdapter.setResultList(someModel.getResultsList());
    }
}

Hope this helped!

will
  • 399
  • 1
  • 11
0
 boolean is_loading = false;

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

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

                    final int visibleThreshold = 2;

                    GridLayoutManager layoutManager = (GridLayoutManager) recyclerView.getLayoutManager();
                    int lastItem = layoutManager.findLastCompletelyVisibleItemPosition();
                    int currentTotalCount = layoutManager.getItemCount();

                    if (currentTotalCount <= lastItem + visibleThreshold && is_loading == false) {
                        is_loading = true;
                        //Put you code here        
                    }
                }
            });
}
Fakhriddin Abdullaev
  • 4,169
  • 2
  • 35
  • 37