Разбивка на страницы с помощью staggeredGridLayoutManager и recyclerView
Здравствуйте, мне нужно сделать бесконечную прокрутку (разбиение на страницы) с помощью просмотрщика, используя staggeredGridLayoutManager. Нумерация страниц работает, но проблема в том, что onLoadMore()
функция вызывается так много раз во время прокрутки, что вызывает проблемы, вот мой код:
newSearchAdapter = new NewSearchAdapter(getActivity(), gridData);
StaggeredGridLayoutManager mLayoutManager;
mLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
mLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
rv_NewProfilesGrid.setLayoutManager(mLayoutManager);
rv_NewProfilesGrid.setAdapter(newSearchAdapter);
rv_NewProfilesGrid.addOnScrollListener(new EndlessRecyclerOnScrollListenerStaggeredLayoutmanager(mLayoutManager) {
@Override
public void onLoadMore(int current_page) {
//calling the api
}
});
и вот мой список прокрутки
Я думаю, что проблема здесь с getFirstVisibleItems()
функция, потому что с GridLayoutManger или LinearLayoutManager возвращает целое число, а с StaggeredLayout возвращает массив int, поэтому я сделал следующее:
public abstract class EndlessRecyclerOnScrollListenerStaggeredLayoutmanager extends RecyclerView.OnScrollListener {
public static String TAG = EndlessRecyclerOnScrollListenerStaggeredLayoutmanager.class.getSimpleName();
private int scrolledDistance = 0;
private boolean controlsVisible = false;
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.
public static boolean loadOneTime = false;
private int pastVisibleItems, visibleItemCount, totalItemCount,previousTotal;
private int current_page = 1;
private StaggeredGridLayoutManager mStaggeredGridLayoutManager;
public EndlessRecyclerOnScrollListenerStaggeredLayoutmanager(StaggeredGridLayoutManager staggeredGridLayoutManager) {
this.mStaggeredGridLayoutManager = staggeredGridLayoutManager;
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = recyclerView.getChildCount();
totalItemCount = mStaggeredGridLayoutManager.getItemCount();
int[] firstVisibleItems = null;
firstVisibleItems = mStaggeredGridLayoutManager.findFirstVisibleItemPositions(firstVisibleItems);
if (firstVisibleItems != null && firstVisibleItems.length > 0) {
pastVisibleItems = firstVisibleItems[0];
}
if (loading) {
if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount)
<= (pastVisibleItems + visibleThreshold)) {
// End has been reached
// Do something
current_page++;
loadOneTime=false;
onLoadMore(current_page);
loading = true;
}
if (scrolledDistance > 1 && controlsVisible) {
controlsVisible = false;
scrolledDistance = 0;
} else if (scrolledDistance < -1 && !controlsVisible) {
controlsVisible = true;
scrolledDistance = 0;
}
if ((controlsVisible && dy > 0) || (!controlsVisible && dy < 0)) {
scrolledDistance += dy;
}
}
public abstract void onLoadMore(int current_page);
}
0 ответов
Попробуй это. Я позаимствовал его из ответа о переполнении стека и позаимствовал другой ответ и объединил их, я наконец решил его.
import android.util.Log
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
abstract class PaginationScrollListener constructor() :
RecyclerView.OnScrollListener() {
private lateinit var mLayoutManager: RecyclerView.LayoutManager
constructor(layoutManager: GridLayoutManager) : this() {
this.mLayoutManager = layoutManager
}
constructor(layoutManager: StaggeredGridLayoutManager) : this() {
this.mLayoutManager = layoutManager
}
constructor(layoutManager: LinearLayoutManager) : this() {
this.mLayoutManager = layoutManager
}
/*
Method gets callback when user scroll the search list
*/
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val visibleItemCount = mLayoutManager.childCount
val totalItemCount = mLayoutManager.itemCount
var firstVisibleItemPosition = 0
when (mLayoutManager) {
is StaggeredGridLayoutManager -> {
val firstVisibleItemPositions =
(mLayoutManager as StaggeredGridLayoutManager).findFirstVisibleItemPositions(null)
// get maximum element within the list
firstVisibleItemPosition = firstVisibleItemPositions[0]
}
is GridLayoutManager -> {
firstVisibleItemPosition =
(mLayoutManager as GridLayoutManager).findFirstVisibleItemPosition()
}
is LinearLayoutManager -> {
firstVisibleItemPosition =
(mLayoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
}
}
if (!isLoading && !isLastPage) {
if (visibleItemCount + firstVisibleItemPosition >= totalItemCount
&& firstVisibleItemPosition >= 0
) {
Log.i(TAG, "Loading more items")
loadMoreItems()
}
}
}
protected abstract fun loadMoreItems()
abstract val isLastPage: Boolean
abstract val isLoading: Boolean
companion object {
private val TAG = PaginationScrollListener::class.java.simpleName
}
}
И используйте это в своем представлении ресайклера таким образом
rvCategoryProducts.addOnScrollListener(object :
PaginationScrollListener(layoutManager) {
override fun loadMoreItems() {
vm.isLoading = true
vm.currentPage++
GlobalScope.launch {
vm.getCategoryProductByCatId(vm.id, vm.currentPage)
}
}
override val isLastPage: Boolean
get() = vm.isLastPage
override val isLoading: Boolean
get() = vm.isLoading
})