Android RecyclerView 保存状态信息
Android RecyclerView Saving State Information
我有一个 RecyclerView,其适配器包含我无法修改的对象的 SortedList。
我在 RecyclerView 中的卡片在展开时应该 expand/collapse 在点击时显示附加信息。问题是,自从 ViewHolder 被回收以来,似乎没有办法存储卡片是展开还是折叠的信息。
为了让事情变得更加困难,在我的适配器的开头和结尾添加了新项目,所以位置一直在变化。尽管新卡片应该显示为折叠状态,但当扩展卡片的 ViewHolder 为新卡片回收时,它们有时会显示为展开状态。这是我尝试直接在 ViewHolder 中保存 expand/collapse 信息的时候。
正确的解决方案似乎是使用具有两个属性的包装器对象:原始(不可修改的)对象和一个指示项目是展开还是折叠的布尔值。
然后在 RecyclerView 适配器的 onBindViewHolder() 方法中,您必须根据包装对象的状态将视图设置为展开或折叠。
@Override
public void onBindViewHolder(final ViewHolder ui, int position) {
if(wrapper_objects.get(position).expanded) {
expandView(ui);
} else {
collapseView(ui);
}
// expand/collapse on click
ui.expand.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(wrapper_objects.get(position).expanded) {
collapseView(ui);
wrapper_objects.get(position).expanded = false;
} else {
expandView(ui);
wrapper_objects.get(position).expanded = true;
}
}
});
}
另一个但罕见的问题可能是 API 有时 returns 与 SortedList 中已有的相同对象。在这种情况下,它们会覆盖包装对象中的 expand/collapse 状态。我为此找到的一个骇人听闻的解决方案是这样做的:
private SortedList<WrapperObject> wrapper_objects = new SortedList<>(WrapperObject.class, new SortedList.Callback<WrapperObject>(){
@Override
public boolean areContentsTheSame(WrapperObject old, WrapperObject new) {
// keep state in new wrapper object
new.expanded = old.expanded;
return old.object.equals(new.object);
}
}
我有一个 RecyclerView,其适配器包含我无法修改的对象的 SortedList。
我在 RecyclerView 中的卡片在展开时应该 expand/collapse 在点击时显示附加信息。问题是,自从 ViewHolder 被回收以来,似乎没有办法存储卡片是展开还是折叠的信息。
为了让事情变得更加困难,在我的适配器的开头和结尾添加了新项目,所以位置一直在变化。尽管新卡片应该显示为折叠状态,但当扩展卡片的 ViewHolder 为新卡片回收时,它们有时会显示为展开状态。这是我尝试直接在 ViewHolder 中保存 expand/collapse 信息的时候。
正确的解决方案似乎是使用具有两个属性的包装器对象:原始(不可修改的)对象和一个指示项目是展开还是折叠的布尔值。
然后在 RecyclerView 适配器的 onBindViewHolder() 方法中,您必须根据包装对象的状态将视图设置为展开或折叠。
@Override
public void onBindViewHolder(final ViewHolder ui, int position) {
if(wrapper_objects.get(position).expanded) {
expandView(ui);
} else {
collapseView(ui);
}
// expand/collapse on click
ui.expand.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(wrapper_objects.get(position).expanded) {
collapseView(ui);
wrapper_objects.get(position).expanded = false;
} else {
expandView(ui);
wrapper_objects.get(position).expanded = true;
}
}
});
}
另一个但罕见的问题可能是 API 有时 returns 与 SortedList 中已有的相同对象。在这种情况下,它们会覆盖包装对象中的 expand/collapse 状态。我为此找到的一个骇人听闻的解决方案是这样做的:
private SortedList<WrapperObject> wrapper_objects = new SortedList<>(WrapperObject.class, new SortedList.Callback<WrapperObject>(){
@Override
public boolean areContentsTheSame(WrapperObject old, WrapperObject new) {
// keep state in new wrapper object
new.expanded = old.expanded;
return old.object.equals(new.object);
}
}