我想把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必须在异步作业结束时更改。希望对大家有所帮助!
其他回答
有一个易于使用的名为paginate的库。支持ListView和RecyclerView(线性布局,GridLayout和StaggeredGridLayout)。
这是该项目在Github上的链接
有一个方法public void setOnScrollListener (RecyclerView。OnScrollListener监听器)在https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#setOnScrollListener%28android.support.v7.widget.RecyclerView.OnScrollListener%29。使用这个
编辑:
在onScrollListener中重写onScrollStateChanged方法并执行此操作
boolean loadMore = firstVisibleItem + visibleItemCount >= totalItemCount;
//loading is used to see if its already loading, you have to manually manipulate this boolean variable
if (loadMore && !loading) {
//end of list reached
}
我的答案是一个改良版的努尔。我从一个ListView,在那里我有EndlessScrollListener(你可以很容易地在SO上找到许多答案)到一个RecyclerView,所以我想要一个endlessrecyscrolllistener轻松地更新我过去的监听器。
下面是代码,希望能有所帮助:
public abstract class EndlessScrollRecyclListener extends RecyclerView.OnScrollListener
{
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
private boolean loading = true;
private int visibleThreshold = 5;
int firstVisibleItem, visibleItemCount, totalItemCount;
private int startingPageIndex = 0;
private int currentPage = 0;
@Override
public void onScrolled(RecyclerView mRecyclerView, int dx, int dy)
{
super.onScrolled(mRecyclerView, dx, dy);
LinearLayoutManager mLayoutManager = (LinearLayoutManager) mRecyclerView
.getLayoutManager();
visibleItemCount = mRecyclerView.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
onScroll(firstVisibleItem, visibleItemCount, totalItemCount);
}
public void onScroll(int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount)
{
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0)
{
this.loading = true;
}
}
// If it’s still loading, we check to see if the dataset count has
// changed, if so we conclude it has finished loading and update the current page
// number and total item count.
if (loading && (totalItemCount > previousTotalItemCount))
{
loading = false;
previousTotalItemCount = totalItemCount;
currentPage++;
}
// If it isn’t currently loading, we check to see if we have breached
// the visibleThreshold and need to reload more data.
// If we do need to reload some more data, we execute onLoadMore to fetch the data.
if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem +
visibleThreshold))
{
onLoadMore(currentPage + 1, totalItemCount);
loading = true;
}
}
// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page, int totalItemsCount);
}
我使用了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;
}
我会尝试扩展使用的LayoutManager(例如LinearLayoutManager)和覆盖scrollVerticallyBy()方法。首先,我会先调用super,然后检查返回的整数值。如果值等于0,则到达底部或顶部边界。然后我将使用findLastVisibleItemPosition()方法来找出到达哪个边界,并在需要时加载更多数据。只是一个想法。
此外,您甚至可以从该方法中返回您的值,允许滚动并显示“loading”指示器。