我想把ListView改为RecyclerView。我想在RecyclerView中使用OnScrollListener的onScroll来确定用户是否滚动到列表的末尾。
我如何知道用户是否滚动到列表的末尾以便我可以从REST服务获取新数据?
我想把ListView改为RecyclerView。我想在RecyclerView中使用OnScrollListener的onScroll来确定用户是否滚动到列表的末尾。
我如何知道用户是否滚动到列表的末尾以便我可以从REST服务获取新数据?
当前回答
对我来说,这很简单:
private boolean mLoading = false;
mList.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int totalItem = mLinearLayoutManager.getItemCount();
int lastVisibleItem = mLinearLayoutManager.findLastVisibleItemPosition();
if (!mLoading && lastVisibleItem == totalItem - 1) {
mLoading = true;
// Scrolled to bottom. Do something here.
mLoading = false;
}
}
});
小心异步作业:mLoading必须在异步作业结束时更改。希望对大家有所帮助!
其他回答
我使用了recyclerview。adapter的onBindViewHolder方法。
适配器:
public interface OnViewHolderListener {
void onRequestedLastItem();
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
...
if (position == getItemCount() - 1) onViewHolderListener.onRequestedLastItem();
}
片段(或活动):
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
contentView = inflater.inflate(R.layout.comments_list, container, false);
recyclerView = (RecyclerView) mContentView.findViewById(R.id.my_recycler_view);
adapter = new Adapter();
recyclerView.setAdapter(adapter);
...
adapter.setOnViewHolderListener(new Adapter.OnViewHolderListener() {
@Override
public void onRequestedLastItem() {
//TODO fetch new data from webservice
}
});
return contentView;
}
我有一个关于如何使用RecyclerView进行分页的非常详细的示例。在高层次,我有一个设置PAGE_SIZE,让我们说30。所以我请求30个项目,如果我得到30个,我就请求下一页。如果我得到的条目少于30个,我就标记一个变量来指示已经到达最后一页,然后停止请求更多的页面。看看吧,告诉我你的想法。
https://medium.com/@etiennelawlor/pagination-with-recyclerview-1cb7e66a502b
大多数答案是假设RecyclerView使用LinearLayoutManager,或GridLayoutManager,甚至StaggeredGridLayoutManager,或假设滚动是垂直或水平的,但没有人张贴一个完全通用的答案。
使用ViewHolder的适配器显然不是一个好的解决方案。一个适配器可能有超过1个RecyclerView在使用它。它“改编”了它们的内容。它应该是RecyclerView(它是一个负责当前显示给用户的类,而不是适配器,它只负责向RecyclerView提供内容),它必须通知您的系统需要更多的项(加载)。
下面是我的解决方案,只使用了RecyclerView (RecycerView. view)的抽象类。LayoutManager和RecycerView.Adapter):
/**
* Listener to callback when the last item of the adpater is visible to the user.
* It should then be the time to load more items.
**/
public abstract class LastItemListener extends RecyclerView.OnScrollListener {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// init
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
RecyclerView.Adapter adapter = recyclerView.getAdapter();
if (layoutManager.getChildCount() > 0) {
// Calculations..
int indexOfLastItemViewVisible = layoutManager.getChildCount() -1;
View lastItemViewVisible = layoutManager.getChildAt(indexOfLastItemViewVisible);
int adapterPosition = layoutManager.getPosition(lastItemViewVisible);
boolean isLastItemVisible = (adapterPosition == adapter.getItemCount() -1);
// check
if (isLastItemVisible)
onLastItemVisible(); // callback
}
}
/**
* Here you should load more items because user is seeing the last item of the list.
* Advice: you should add a bollean value to the class
* so that the method {@link #onLastItemVisible()} will be triggered only once
* and not every time the user touch the screen ;)
**/
public abstract void onLastItemVisible();
}
// --- Exemple of use ---
myRecyclerView.setOnScrollListener(new LastItemListener() {
public void onLastItemVisible() {
// start to load more items here.
}
}
有一个易于使用的名为paginate的库。支持ListView和RecyclerView(线性布局,GridLayout和StaggeredGridLayout)。
这是该项目在Github上的链接
我会尝试扩展使用的LayoutManager(例如LinearLayoutManager)和覆盖scrollVerticallyBy()方法。首先,我会先调用super,然后检查返回的整数值。如果值等于0,则到达底部或顶部边界。然后我将使用findLastVisibleItemPosition()方法来找出到达哪个边界,并在需要时加载更多数据。只是一个想法。
此外,您甚至可以从该方法中返回您的值,允许滚动并显示“loading”指示器。