我有一个 Recyclerview 和一个包含 5000 个项目的列表,但我只想一次加载 100 个项目
I have a Recyclerview and a list with 5000 items but I only want to load 100 items at a time
我已经在我的测试应用中实现了 Recyclerview
。目前,我将大约 5000 项数据提取到一个模型中,并使用此列表加载我的视图。一切都很好,性能也很好,但我并不是特别想加载所有 5000 个项目。我更愿意加载 100 个项目,一旦用户到达底部,加载下一个 100 个项目,并且基本上使它成为一个不断增长的列表。
我可以针对 Recyclerview
实施 onScrollListener
来检测我何时到达终点,但我的问题(听起来很简单)是,什么是最好的方法告诉 Recyclerview
在我说之前只加载 100?
我的适配器:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<ImageFeed> mFeedList;
public MyAdapter(List<ImageFeed> feedList) {
this.mFeedList = feedList;
}
public void setFeedList(List<ImageFeed> feedList) {
mFeedList = feedList;
}
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup vGroup, int i) {
View v = LayoutInflater.from(vGroup.getContext()).inflate(R.layout.recycler_list, vGroup, false);
return new MyAdapter.ViewHolder(v);
}
@Override
public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, int i) {
String mTitle = mFeedList.get(i).getTitle();
...//Do other stuff
}
@Override
public int getItemCount() {
return mFeedList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
protected ImageView mImageView;
protected TextView mTitle;
protected ProgressBar mLoader;
private int mItemId;
public ViewHolder(View itemView) {
super(itemView);
this.mImageView = (ImageView) itemView.findViewById(R.id.imgItem);
this.mTitle = (TextView) itemView.findViewById(R.id.txtTitle);
this.mLoader = (ProgressBar) itemView.findViewById(R.id.mLoaderProgress);
this.mImageView.setOnClickListener(this);
itemView.setOnClickListener(this);
}
public void setItem(int item) {
this.mItemId = item;
}
@Override
public void onClick(View v) {
if (v instanceof ImageView) {
Toast.makeText(v.getContext(), "Image view clicked: " + this.mItemId, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(v.getContext(), this.mItemId + " ", Toast.LENGTH_SHORT).show();
}
}
}
}
考虑到这个场景,我原以为传递一个较小的列表是可能的,但感觉并不完全正确。
好吧,毕竟这并不是特别困难 - 我认为我的主要问题是过度思考场景...
所以我做的第一件事就是获取适当的数据(在本例中是通过 JSON)并将其存储在 JSON 数组中以供稍后操作 - 目前我仍在获取完整数据设置(即 5000),但这很容易改变。
这是通过带有不确定进度条的 AsyncTask 完成的。完成后,我只将 JSON 解析为 20 个元素并将其加载到适配器中。
一旦完成,我就有了我的 Recyclerview.onScrollListener.....
mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
mOnScreenItems = mRecyclerView.getChildCount();
mTotalItemsInList = llm.getItemCount();
mFirstVisibleItem = llm.findFirstVisibleItemPosition();
if (mLoadingItems) {
if (mTotalItemsInList > mPreviousTotal) {
mLoadingItems = false;
mPreviousTotal = mTotalItemsInList;
}
}
if (!mLoadingItems && (mTotalItemsInList - mOnScreenItems) <= (mFirstVisibleItem + mVisibleThreshold)) {
new AsyncLoadTask().execute();
mLoadingItems = true;
}
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
});
当它接近尾声或到达底部时,将启动一个新的 AsynTask 以将其他项目加载到列表中。 onPostExecute()
然后通过其 mMyAdapter.notifyDataSetChanged();
方法更新适配器,从而实现非常流畅的更新。有很多清理工作要做,但基础知识已经准备就绪。
谢谢各位指点!
我已经在我的测试应用中实现了 Recyclerview
。目前,我将大约 5000 项数据提取到一个模型中,并使用此列表加载我的视图。一切都很好,性能也很好,但我并不是特别想加载所有 5000 个项目。我更愿意加载 100 个项目,一旦用户到达底部,加载下一个 100 个项目,并且基本上使它成为一个不断增长的列表。
我可以针对 Recyclerview
实施 onScrollListener
来检测我何时到达终点,但我的问题(听起来很简单)是,什么是最好的方法告诉 Recyclerview
在我说之前只加载 100?
我的适配器:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<ImageFeed> mFeedList;
public MyAdapter(List<ImageFeed> feedList) {
this.mFeedList = feedList;
}
public void setFeedList(List<ImageFeed> feedList) {
mFeedList = feedList;
}
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup vGroup, int i) {
View v = LayoutInflater.from(vGroup.getContext()).inflate(R.layout.recycler_list, vGroup, false);
return new MyAdapter.ViewHolder(v);
}
@Override
public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, int i) {
String mTitle = mFeedList.get(i).getTitle();
...//Do other stuff
}
@Override
public int getItemCount() {
return mFeedList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
protected ImageView mImageView;
protected TextView mTitle;
protected ProgressBar mLoader;
private int mItemId;
public ViewHolder(View itemView) {
super(itemView);
this.mImageView = (ImageView) itemView.findViewById(R.id.imgItem);
this.mTitle = (TextView) itemView.findViewById(R.id.txtTitle);
this.mLoader = (ProgressBar) itemView.findViewById(R.id.mLoaderProgress);
this.mImageView.setOnClickListener(this);
itemView.setOnClickListener(this);
}
public void setItem(int item) {
this.mItemId = item;
}
@Override
public void onClick(View v) {
if (v instanceof ImageView) {
Toast.makeText(v.getContext(), "Image view clicked: " + this.mItemId, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(v.getContext(), this.mItemId + " ", Toast.LENGTH_SHORT).show();
}
}
}
}
考虑到这个场景,我原以为传递一个较小的列表是可能的,但感觉并不完全正确。
好吧,毕竟这并不是特别困难 - 我认为我的主要问题是过度思考场景...
所以我做的第一件事就是获取适当的数据(在本例中是通过 JSON)并将其存储在 JSON 数组中以供稍后操作 - 目前我仍在获取完整数据设置(即 5000),但这很容易改变。
这是通过带有不确定进度条的 AsyncTask 完成的。完成后,我只将 JSON 解析为 20 个元素并将其加载到适配器中。
一旦完成,我就有了我的 Recyclerview.onScrollListener.....
mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
mOnScreenItems = mRecyclerView.getChildCount();
mTotalItemsInList = llm.getItemCount();
mFirstVisibleItem = llm.findFirstVisibleItemPosition();
if (mLoadingItems) {
if (mTotalItemsInList > mPreviousTotal) {
mLoadingItems = false;
mPreviousTotal = mTotalItemsInList;
}
}
if (!mLoadingItems && (mTotalItemsInList - mOnScreenItems) <= (mFirstVisibleItem + mVisibleThreshold)) {
new AsyncLoadTask().execute();
mLoadingItems = true;
}
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
});
当它接近尾声或到达底部时,将启动一个新的 AsynTask 以将其他项目加载到列表中。 onPostExecute()
然后通过其 mMyAdapter.notifyDataSetChanged();
方法更新适配器,从而实现非常流畅的更新。有很多清理工作要做,但基础知识已经准备就绪。
谢谢各位指点!