How to Create a Circular (Endless) Recyclerview

How do I create a circular (endless) RecyclerView?

There is no way of making it infinite, but there is a way to make it look like infinite.

  1. in your adapter override getCount() to return something big like Integer.MAX_VALUE:

    @Override
    public int getCount() {
    return Integer.MAX_VALUE;
    }
  2. in getItem() and getView() modulo divide (%) position by real item number:

    @Override
    public Fragment getItem(int position) {
    int positionInList = position % fragmentList.size();
    return fragmentList.get(positionInList);
    }
  3. at the end, set current item to something in the middle (or else, it would be endless only in downward direction).

    // scroll to middle item
    recyclerView.getLayoutManager().scrollToPosition(Integer.MAX_VALUE / 2);

how to create closed circular Recyclerview with custom Recycler adapter?

I looked in a little deep and found a working solution/hack here.I have tested it and it works well.I am closing this question. thanks!

How to implement endless list with RecyclerView?

Thanks to @Kushal and this is how I implemented it

private boolean loading = true;
int pastVisiblesItems, visibleItemCount, totalItemCount;

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) { //check for scroll down
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();

if (loading) {
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
loading = false;
Log.v("...", "Last Item Wow !");
// Do pagination.. i.e. fetch new data

loading = true;
}
}
}
}
});

Don't forget to add

LinearLayoutManager mLayoutManager;
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);

RecyclerView how to make cyclic

Please refer to the following question which answers a similar problem: How do I create a circular (endless) RecyclerView?

Endless RecyclerView, that repeat data when goes to the end

You are lucky, I did it a couple of days ago.

The trick in my solution was to override the getItemCount() of the adapter so that it works with Integer.MAX_VALUE value.

The getItemCount() is used by the recyclerview to determinate how many items there are in the list, and if it returns always MAX_VALUE, the list is pretty much infinite.

This is my example:

Activity

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mlayout);
RecyclerView myRv = findViewById(R.id.myRv);

ArrayList<MyObject> objectList = new ArrayList<>();
objectList = retrieveObjectList();
myRv.setLayoutManager(new SlowLayoutManager(myActivity.this));
MyAdapter myAdapter = new MyAdapter(objectList);
myRv.setAdapter(myAdapter);

}

Adapter

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

private ArrayList<MyObject> myObjects;

public MyAdapter(ArrayList<MyObject> myObjects) {
this.myObjects = myObjects;
}

//used to retrieve the effective item position in list
public int getActualItemCount() {
if (myObjects == null) {
myObjects = new ArrayList<>();
}
return myObjects.size();
}

@Override
public int getItemCount() {
return Integer.MAX_VALUE;
}

@NonNull
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new MyAdapter.MyViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_view, parent, false));
}

@Override
public void onBindViewHolder(@NonNull MessagesAdapter.MessagesViewHolder holder, int position) {
if (myObjects.size() == 0) {
holder.bind(null);
} else {
MyObject myObject = myObjects.get(position % myObjects.size());
holder.bind(SMSMessage);
}
}

class MyViewHolder extends RecyclerView.ViewHolder {

TextView myTv;

MessagesViewHolder(View itemView) {
super(itemView);
myTv = itemView.findViewById(R.id.myTv);
}

void bind(MyObject myObject) {
if (myObject != null) {
myTv.setText(myObject.getProperty());
} else {
myTv.setText("");
}
}
}
}

I use this way (obj I changed names so you can fill them with yours, since some of mine were similar to native ones).

If you have any question, ask freely

Implementing Endless RecyclerView

This could achieve your goal.

public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {
public static String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName();

private int previousTotal = 0; // The total number of items in the dataset after the last load
private boolean loading = true; // True if we are still waiting for the last set of data to load.
private int visibleThreshold = 5; // The minimum amount of items to have below your current scroll position before loading more.
int firstVisibleItem, visibleItemCount, totalItemCount;

private int current_page = 1;

private LinearLayoutManager mLinearLayoutManager;

public EndlessRecyclerOnScrollListener(LinearLayoutManager linearLayoutManager) {
this.mLinearLayoutManager = linearLayoutManager;
}

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

visibleItemCount = recyclerView.getChildCount();
totalItemCount = mLinearLayoutManager.getItemCount();
firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();

if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount)
<= (firstVisibleItem + visibleThreshold)) {
// End has been reached

// Do something
current_page++;

onLoadMore(current_page);

loading = true;
}
}

public abstract void onLoadMore(int current_page);
}

And sample activity

public class SampleActivity extends ActionBarActivity {

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

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.list);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setOnScrollListener(new EndlessRecyclerOnScrollListener(linearLayoutManager) {
@Override
public void onLoadMore(int current_page) {
// do something...
}
});
}
}

Edit: See here: Endless Scrolling with AdapterViews

How to make different views RecyclerView as endless loop?

So after extensive searching, found this solution.

So this is what I did

RecyclerViewAdapterClass

  fun initialize(scrollableData: ArrayList<ScrollableData>, activity: AppCompatActivity) {
this.scrollableData = scrollableData
this.activity = activity
list = /*listOf(scrollableData.last()) +*/ scrollableData + listOf(scrollableData.first()) //this is very important
}
...
override fun getItemViewType(position: Int): Int {
return list[position % list.size].index
}

HomeActivity#setupRecyclerView(...)

mainScreenAdapter.itemCount.takeIf { it > 1 }
?.apply {
onScrollListener = OnScrollListener(
mainScreenAdapter.itemCount,
linearLayoutManager
) {
//some code here
}
recycler_view.addOnScrollListener(onScrollListener)
recycler_view.scrollToPosition(0)
}

OnScrollListener

internal class OnScrollListener(val itemCount: Int, val layoutManager: LinearLayoutManager,
val stateChanged: (Int) -> Unit) : RecyclerView.OnScrollListener() {
var isLooping = false
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView!!, dx, dy)
val firstItemVisible = layoutManager.findFirstCompletelyVisibleItemPosition()

if (firstItemVisible > 0 && firstItemVisible % (itemCount - 1) == 0) {
// When position reaches end of the list, it sho uld go back to the beginning
isLooping = true
recyclerView?.scrollToPosition(0)
} /*else if (firstItemVisible == 0) {
// When position reaches beginning of the list, it should go back to the end
recyclerView?.scrollToPosition(itemCount-1)
}*/
}

override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView!!, newState)
var loop = newState
if (isLooping) {
loop = 100
isLooping = false
}
stateChanged(loop)
}
}

Ref: https://github.com/tomoima525/CirculerAutoScrollingRecyclerView

Creating horizontal RecyclerView with circular scroll

In your getItemCount function in Adapter class use return Integer.MAX_VALUE;

Also use position as below in bindviewholder function.

int positionInList = position % yourList.size();


Related Topics



Leave a reply



Submit