我有一个带有自定义适配器和自定义ViewHolder的RecyclerView。
我知道onCreateViewHolder()方法是在RecyclerView用完ViewHolders来循环时调用的,需要一个新的方法。所以我只是在里面膨胀一个布局,然后把它传递给一个新的ViewHolder.
此外,onBindViewHolder()负责在ViewHolder创建或回收新的ViewHolder后立即将数据填充到RecyclerView中。所以,我在这里要做的是调用我的方法holder.setNode(),将一个数据对象传递给ViewHolder。
我看到的行为当活动第一次启动时,所有条目都是正确的。然而,当我添加新条目或删除现有条目时,事情开始变得有点滑稽。
title TextView。RecyclerView正在重用旧布局因此,我想知道:为什么这些值在视图被重用后不会在onBindViewHolder()中立即改变呢?或者如果我错了,随机转换布局的真正原因是什么?
TaskListAdapter
class TaskListAdapter extends RecyclerView.Adapter<TaskListAdapter.TaskViewHolder> {
private ArrayList<NodeHandler.DbNode> dbNodeList = new ArrayList<>();
...
@Override
public TaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.small_task_view, parent, false);
return new TaskViewHolder(v);
}
@Override
public void onBindViewHolder(TaskViewHolder holder, int position) {
final NodeHandler.DbNode dbNode = dbNodeList.get(position);
holder.setNode(dbNode);
holder.wrapper.findViewById(R.id.card_details).setVisibility(View.GONE);
}
...
public static class TaskViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {
private FrameLayout wrapper;
private TextView title;
private NodeHandler.DbNode dbNode;
public TaskViewHolder(View view) {
...
}
public void setTitle(String str) {
title.setText(str);
}
public void setMarkers(@IntRange(from = 1, to = Node.MAX_URGENCY) int urgency, @IntRange(from = 1, to = Node.MAX_IMPORTANCE) int importance) {
if(!dbNode.isAppointment()) {
wrapper.setBackgroundColor(ContextCompat.getColor(wrapper.getContext(), R.color.lightGray));
}
((QuadrantView) wrapper.findViewById(R.id.quadrant_view)).setDimensions(importance, urgency);
// setDimensions will invalidate the view
}
public void setNode(NodeHandler.DbNode dbNodeObject) {
this.dbNode = dbNodeObject;
setTitle(dbNode.toString());
setMarkers(dbNode.getUrgency(), dbNode.getImportance());
setTips();
}
}
}如果这里还有什么事请告诉我。我很乐意相应地更新这个问题。
发布于 2016-01-20 19:39:11
一旦视图被重用,onBindViewHolder中的值确实会被更改。
看似随机切换布局的真正原因是,onBindViewHolder目前的实现方式假定ViewHolder是新创建的,并且是第一次绑定。相反,onBindViewHolder的实现方式应该假定被绑定的ViewHolder被重用,所以它应该这样做:
ViewHolder的所有值重置为默认值,然后再将其设置为其他值或onBindViewHolder内部设置的,这样就不能确定它以前是绑定到其他东西上的。随机背景色变化:
您正确地怀疑,随机背景颜色问题是由RecyclerView重用ViewHolders引起的。
之所以会发生这种情况,是因为以下代码:
if(!dbNode.isAppointment()) {
wrapper.setBackgroundColor(ContextCompat.getColor(wrapper.getContext(), R.color.lightGray));
}它只在ViewHolder不是约会时设置背景。因此,如果被重用的ViewHolder以前不是用于约会,而是当前用于约会,那么它的背景色将是不合适的。
若要解决此问题,请执行以下任何操作:
ViewHolder的背景色设置为某种默认颜色(如上面提到的解决方案1所示):
wrapper.setBackgroundColor(ContextCompat.getColor(wrapper.getContext(),wrapper.setBackgroundColor(/*默认背景色*/);if(!dbNode.isAppointment()) {dbNode.isAppointment R.color.lightGray);}ViewHolder的背景色设置为适当的颜色(如上面提到的解决方案2所示)
if(!dbNode.isAppointment()) {dbNode.isAppointment R.color.lightGray);} wrapper.setBackgroundColor(/*约会背景色*/);}RecyclerView.Adapter的getItemViewType以基于dbNode.isAppointment()返回不同的视图类型,并创建用于显示每个视图的不同的ViewHolder子类。附注:我不知道定制views...sorry会有什么问题
https://stackoverflow.com/questions/34908061
复制相似问题