1

I'm creating a breaking news app and i want to infinite scroll recyclerview but its end after its list size is done so how it is possible to auto scroll recyclerview.

By this method the autoscroll is done but it not scroll infinite

 public void autoScrollAnother() {
    scrollCount = 0;
    final int speedScroll = 1200;
    final Handler handler = new Handler();
    final Runnable runnable = new Runnable() {
        @Override
        public void run() {
            if(scrollCount == breakingNewAdapter.getItemCount()){

                breakingNewAdapter.notifyDataSetChanged();
            }
            brakingNews.smoothScrollToPosition((scrollCount++));
            handler.postDelayed(this, speedScroll);
        }
    };
    handler.postDelayed(runnable, speedScroll);
}

And set in recyclerview like this

  layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
    brakingNews.setLayoutManager(layoutManager);
    brakingNews.setHasFixedSize(true);
    brakingNews.setItemViewCacheSize(10);
    brakingNews.setDrawingCacheEnabled(true);
    brakingNews.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_LOW);
    brakingNews.setAdapter(breakingNewAdapter);

Any help it will more help full

MustafaShaikh
  • 152
  • 2
  • 11
  • Are you looking for a native api for this scroll..?? I think your implementation is fine.. Except that when you have multiple news models send to the set method of your adapter and your recyclerview will all of a sudden scroll to the last news.. isn't it?? – Kannan_SJD Jul 10 '19 at 11:22
  • I suggest you implement paging library – coroutineDispatcher Jul 10 '19 at 12:38

1 Answers1

1

Here is a solution without any listeners or programmatic scrollings.

Increase the getItemCount returned value as the user reach the end of your list. It doesn't really matter what your actual list size is, only that you'll direct every call to onBindViewHolder to a specific item.

Try this code:

public class BreakingNewsAdapter {

    private List<BreakingNews> news;
    private int adapterSize = 0;

    public void setNews(List<BreakingNews> news) {
        this.news = news;
        this.adapterSize = news.size(); // some initialization
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        if (this.news != null)
            return this.adapterSize;
        return 0;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        BreakingNews item = news.get(position % news.size()); // the '%' will ensure you'll always have data to bind to the view holder
        
        if (position == this.adapterSize - 1) {
            this.adapterSize += news.size(); // do whatever you want here, just make sure to increment this.adapterSize's value 
            new Handler().postDelayed(() -> notifyItemInserted(position + 1), 100); // Can't notify directly from this method, so we use a Handler. May change the delay value for what works best for you.
            // notifyItemInserted will animate insertion of one item to your list. You may call to notifyDataSetChanged or notifyItemRangeInserted if you don't want the animation

            //new Handler().postDelayed(() -> notifyItemRangeInserted(position + 1, this.adapterSize - news.size()), 100);
            //new Handler().postDelayed(this::notifyDataSetChanged, 100);
        }
    }
}

You might notice that the scroll will stop when you reach the end of the list, and you'll need to scroll again.

If you don't want the scrolling to stop at all, you can initialize adapterSize with a very large number, the downside is that the scrollbar won't move.

Another option is to check for a value before this.adapterSize - 1.
this.adapterSize - (news.size() / 2) for example. That way, the scroll will stop for a moment and will continue automatically.

There are a lot of options here, so you can play with the numbers (maybe initialize adapterSize to be twice the input's size etc.) but the main rule is to detect a specific event in onBindViewHilder and increase the adapter's size.

See also h22's answer.

Found some article (in kotlin) that implements a different approach, if you're interested.

Community
  • 1
  • 1
ronginat
  • 1,910
  • 1
  • 12
  • 23