package io.github.tonyshkurenko.endlessscrollingbothsides.pagesprovider; import android.support.annotation.NonNull; import android.support.v4.util.SparseArrayCompat; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.ViewGroup; import io.github.tonyshkurenko.endlessscrollingbothsides.BuildConfig; import io.github.tonyshkurenko.endlessscrollingbothsides.ViewHolder; import java.util.List; /** * Project: EndlessScrollingBothSides * Follow me: @tonyshkurenko * * Create pages after and before * * @author Anton Shkurenko * @since 3/23/18 */ public class PagesProviderRecyclerViewAdapter extends RecyclerView.Adapter { private static final String TAG = PagesProviderRecyclerViewAdapter.class.getSimpleName(); static final int PAGE_LIMIT = 5; private final SparseArrayCompat> pages = new SparseArrayCompat<>(); private int firstPage = 0; private int currentCount = 0; private boolean loading = true; @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new ViewHolder(LayoutInflater.from(parent.getContext()) .inflate(android.R.layout.simple_list_item_1, parent, false)); } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { holder.bind(getItem(position)); } @Override public int getItemCount() { return currentCount; } int getItem(int position) { int count = currentCount; for (int i = firstPage + pages.size() - 1; i >= firstPage; i--) { final List page = pages.get(i); final int pageSize = page.size(); if (position >= count - pageSize) { return page.get(pageSize - (count - position)); } else { count -= pageSize; } } throw new IllegalStateException("Wrong position"); } void initValues(List vals) { pages.append(this.firstPage, vals); currentCount += vals.size(); loading = false; notifyItemRangeInserted(0, currentCount); printPages(); } void appendValues(List ints) { if (BuildConfig.DEBUG) { Log.d(TAG, "appendValues() called (before), count: " + currentCount + ", bottom(): " + bottom()); printPages(); } if (pages.size() >= PAGE_LIMIT) { pages.remove(firstPage++); } pages.append(firstPage + pages.size(), ints); currentCount += ints.size(); if (BuildConfig.DEBUG) { Log.d(TAG, "Notify inserted: idx: " + (currentCount - ints.size()) + ", count: " + currentCount); } notifyItemRangeInserted(currentCount - ints.size(), ints.size()); if (BuildConfig.DEBUG) { Log.d(TAG, "appendValues() called (after), count: " + currentCount + ", bottom(): " + bottom()); printPages(); } } void removeValues(List ints) { if (BuildConfig.DEBUG) { Log.d(TAG, "removeValues() called (before), count: " + currentCount + ", top(): " + top()); printPages(); } if (pages.size() >= PAGE_LIMIT) { final int removedSize = pages.get(firstPage + pages.size() - 1).size(); pages.remove(firstPage + pages.size() - 1); currentCount -= removedSize; notifyItemRangeRemoved(currentCount, removedSize); } firstPage--; pages.append(firstPage, ints); if (BuildConfig.DEBUG) { Log.d(TAG, "Notify removed: idx: " + (currentCount) + ", count: " + currentCount); } if (BuildConfig.DEBUG) { Log.d(TAG, "removeValues() called (after), count: " + currentCount + ", top(): " + top()); printPages(); } } int bottom() { final int size = pages.size(); if (size > 2) { return currentCount - pages.get(firstPage + size - 1).size(); } else if (size > 0) { return currentCount - pages.get(firstPage).size() / 3; } else { return 0; } } int top() { final int size = pages.size(); if (size > 2) { int count = currentCount; for (int i = firstPage + pages.size() - 1; i > firstPage; i--) { final List page = pages.get(i); final int pageSize = page.size(); count -= pageSize; } return count; } else if (size > 0) { int count = currentCount; if (size > 1) { count -= pages.get(firstPage + 1).size(); } return count - (pages.get(firstPage).size() / 3 * 2); } else { return 0; } } void setLoading(boolean loading) { this.loading = loading; } boolean isLoading() { return loading; } int nextPage() { return firstPage + pages.size(); } int prevPage() { return firstPage - 1; } private void printPages() { for (int i = 0; i < pages.size(); i++) { final int pageNum = pages.keyAt(i); if (BuildConfig.DEBUG) { Log.v(TAG, "Page #" + pageNum + ": " + pages.get(pageNum).toString()); } } } }