SortedList
通过Callback
处理与回收器适配器的通信。
SortedList
和List
之间的一个区别可以在下面示例中的addAll
帮助方法中看到。
public void addAll(List<Page> items) {
mPages.beginBatchedUpdates();
for (Page item : items) {
mPages.add(item);
}
mPages.endBatchedUpdates();
}
- 保留最新添加的项目
假设我有10个缓存项目需要在我的回收站列表填充时立即加载。同时,我查询网络以获取相同的10个项目,因为它们可能已经改变了。我可以调用相同的addAll
方法,而SortedList
会在幕后用获取的项目替换缓存项目(始终保留最新添加的项目)。
// After creating adapter
myAdapter.addAll(cachedItems)
// Network callback
myAdapter.addAll(fetchedItems)
在一个普通的
List
中,我将拥有所有项目的重复副本(列表大小为20)。而对于
SortedList
,它使用回调函数的
areItemsTheSame
替换相同的项目。
- 它会智能地在适当的时候更新视图
当添加 fetchedItems 时,仅当一个或多个
Page
的标题更改时,
onChange
才会被调用。您可以自定义 Callback 的
areContentsTheSame
以决定
SortedList
查找什么内容。
- 它是高效的
如果要向 SortedList 添加多个项,则 BatchedCallback 将把单个的 onInserted(index,1) 调用转换为一次 onInserted(index,N) 调用,如果项目添加到连续索引中。这种更改可以帮助 RecyclerView 更轻松地解析更改。
示例
您可以在适配器上设置一个 getter 用于您的 SortedList
,但我决定向我的适配器添加 helper 方法。
适配器类:
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private SortedList<Page> mPages;
public MyAdapter() {
mPages = new SortedList<Page>(Page.class, new SortedList.Callback<Page>() {
@Override
public int compare(Page o1, Page o2) {
return o1.getTitle().compareTo(o2.getTitle());
}
@Override
public void onInserted(int position, int count) {
notifyItemRangeInserted(position, count);
}
@Override
public void onRemoved(int position, int count) {
notifyItemRangeRemoved(position, count);
}
@Override
public void onMoved(int fromPosition, int toPosition) {
notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onChanged(int position, int count) {
notifyItemRangeChanged(position, count);
}
@Override
public boolean areContentsTheSame(Page oldItem, Page newItem) {
return oldItem.getTitle().equals(newItem.getTitle());
}
@Override
public boolean areItemsTheSame(Page item1, Page item2) {
return item1.getId() == item2.getId();
}
});
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.viewholder_page, parent, false);
return new PageViewHolder(view);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
PageViewHolder pageViewHolder = (PageViewHolder) holder;
Page page = mPages.get(position);
pageViewHolder.textView.setText(page.getTitle());
}
@Override
public int getItemCount() {
return mPages.size();
}
public Page get(int position) {
return mPages.get(position);
}
public int add(Page item) {
return mPages.add(item);
}
public int indexOf(Page item) {
return mPages.indexOf(item);
}
public void updateItemAt(int index, Page item) {
mPages.updateItemAt(index, item);
}
public void addAll(List<Page> items) {
mPages.beginBatchedUpdates();
for (Page item : items) {
mPages.add(item);
}
mPages.endBatchedUpdates();
}
public void addAll(Page[] items) {
addAll(Arrays.asList(items));
}
public boolean remove(Page item) {
return mPages.remove(item);
}
public Page removeItemAt(int index) {
return mPages.removeItemAt(index);
}
public void clear() {
mPages.beginBatchedUpdates();
while (mPages.size() > 0) {
mPages.removeItemAt(mPages.size() - 1);
}
mPages.endBatchedUpdates();
}
}
页面类:
public class Page {
private String title;
private long id;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
视图持有者 XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/text_view"
style="@style/TextStyle.Primary.SingleLine"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
视图持有者类:
public class PageViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public PageViewHolder(View itemView) {
super(itemView);
textView = (TextView)item.findViewById(R.id.text_view);
}
}
RecyclerView.Adapter
一起使用?有人写过相关示例吗? - SilentKnight