我想把ListView改为RecyclerView。我想在RecyclerView中使用OnScrollListener的onScroll来确定用户是否滚动到列表的末尾。
我如何知道用户是否滚动到列表的末尾以便我可以从REST服务获取新数据?
我想把ListView改为RecyclerView。我想在RecyclerView中使用OnScrollListener的onScroll来确定用户是否滚动到列表的末尾。
我如何知道用户是否滚动到列表的末尾以便我可以从REST服务获取新数据?
当前回答
if (layoutManager.findLastCompletelyVisibleItemPosition() ==
recyclerAdapter.getItemCount() - 1) {
//load more items.
}
公平而简单。 这是可行的。
其他回答
检查的每一件事都有详细的解释: 使用RecyclerView从A到Z分页
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView,
int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = mLayoutManager.getChildCount();
int totalItemCount = mLayoutManager.getItemCount();
int firstVisibleItemPosition = mLayoutManager.findFirstVisibleItemPosition();
if (!mIsLoading && !mIsLastPage) {
if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount
&& firstVisibleItemPosition >= 0) {
loadMoreItems();
}
}
}
})
loadMoreItems ():
private void loadMoreItems() {
mAdapter.removeLoading();
//load data here from the server
// in case of success
mAdapter.addData(data);
// if there might be more data
mAdapter.addLoading();
}
在MyAdapter中:
private boolean mIsLoadingFooterAdded = false;
public void addLoading() {
if (!mIsLoadingFooterAdded) {
mIsLoadingFooterAdded = true;
mLineItemList.add(new LineItem());
notifyItemInserted(mLineItemList.size() - 1);
}
}
public void removeLoading() {
if (mIsLoadingFooterAdded) {
mIsLoadingFooterAdded = false;
int position = mLineItemList.size() - 1;
LineItem item = mLineItemList.get(position);
if (item != null) {
mLineItemList.remove(position);
notifyItemRemoved(position);
}
}
}
public void addData(List<YourDataClass> data) {
for (int i = 0; i < data.size(); i++) {
YourDataClass yourDataObject = data.get(i);
mLineItemList.add(new LineItem(yourDataObject));
notifyItemInserted(mLineItemList.size() - 1);
}
}
也可以在没有滚动侦听器的情况下实现,只使用数据模型的纯逻辑。滚动视图需要按位置获取项目以及最大项目计数。模型可以具有后台逻辑,以块的形式获取所需的项,而不是一个一个地获取,并在后台线程中执行此操作,在数据准备就绪时通知视图。
这种方法允许获取队列优先选择最近请求的(所以当前可见)项而不是旧的(很可能已经滚动了)提交,控制使用的并行线程的数量等等。这个方法的完整源代码(演示应用程序和可重用库)可以在这里找到。
我会尝试扩展使用的LayoutManager(例如LinearLayoutManager)和覆盖scrollVerticallyBy()方法。首先,我会先调用super,然后检查返回的整数值。如果值等于0,则到达底部或顶部边界。然后我将使用findLastVisibleItemPosition()方法来找出到达哪个边界,并在需要时加载更多数据。只是一个想法。
此外,您甚至可以从该方法中返回您的值,允许滚动并显示“loading”指示器。
下面是一个简单实现无尽滚动RecyclerView的例子,使用一个从各种来源编译的简单库。
在build.gradle中添加这一行
implementation 'com.hereshem.lib:awesomelib:2.0.1'
在活动中创建RecyclerView布局
<com.hereshem.lib.recycler.MyRecyclerView
android:id="@+id/recycler"
app:layoutManager="LinearLayoutManager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
通过传递ViewHolder支持的类来创建一个ViewHolder
public static class EVHolder extends MyViewHolder<Events> {
TextView date, title, summary;
public EVHolder(View v) {
super(v);
date = v.findViewById(R.id.date);
title = v.findViewById(R.id.title);
summary = v.findViewById(R.id.summary);
}
@Override
public void bindView(Events c) {
date.setText(c.date);
title.setText(c.title);
summary.setText(c.summary);
}
}
通过在适配器中传递项目、类和布局来创建项目列表变量和很少行的适配器
List<Events> items = new ArrayList<>();
MyRecyclerView recycler = findViewById(R.id.recycler);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(this, items, EVHolder.class, R.layout.row_event);
recycler.setAdapter(adapter);
ClickListener和LoadMore Listener可以通过以下几行添加
recycler.setOnItemClickListener(new MyRecyclerView.OnItemClickListener() {
@Override
public void onItemClick(int position) {
Toast.makeText(MainActivity.this, "Recycler Item Clicked " + position, Toast.LENGTH_SHORT).show();
}
});
recycler.setOnLoadMoreListener(new MyRecyclerView.OnLoadMoreListener() {
@Override
public void onLoadMore() {
loadData();
}
});
loadData();
数据加载后必须调用此函数
recycler.loadComplete();
当不需要LoadMore时,可以通过调用LoadMore来隐藏布局
recycler.hideLoadMore();
更多的例子可以在这里找到
希望这对你有所帮助。
对于那些只想在最后一项完全显示时得到通知的人,可以使用view . canscrollvertical()。
这是我的实现:
public abstract class OnVerticalScrollListener
extends RecyclerView.OnScrollListener {
@Override
public final void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (!recyclerView.canScrollVertically(-1)) {
onScrolledToTop();
} else if (!recyclerView.canScrollVertically(1)) {
onScrolledToBottom();
} else if (dy < 0) {
onScrolledUp();
} else if (dy > 0) {
onScrolledDown();
}
}
public void onScrolledUp() {}
public void onScrolledDown() {}
public void onScrolledToTop() {}
public void onScrolledToBottom() {}
}
注意:如果你想支持API < 14,你可以使用recyclerView.getLayoutManager(). canscrollvertical()。