gpt4 book ai didi

android - RecyclerView 适配器的位置与其数据集的索引有何关系?

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:53:57 26 4
gpt4 key购买 nike

我以为他们是一样的,但他们不是。当我尝试访问我的数据集的“位置”索引时,以下代码给出了 indexOutOfBounds 异常,在本例中是我创建的名为 Task 的模型列表:

public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.TaskViewHolder>   {

private List<Task> taskList;
private TaskAdapter thisAdapter = this;

// cache of views to reduce number of findViewById calls
public static class TaskViewHolder extends RecyclerView.ViewHolder {
protected TextView taskTV;
protected ImageView closeBtn;

public TaskViewHolder(View v) {
super(v);
taskTV = (TextView)v.findViewById(R.id.taskDesc);
closeBtn = (ImageView)v.findViewById(R.id.xImg);
}
}


public TaskAdapter(List<Task> tasks) {
if(tasks == null)
throw new IllegalArgumentException("tasks cannot be null");
taskList = tasks;
}


// onBindViewHolder binds a model to a viewholder
@Override
public void onBindViewHolder(TaskViewHolder taskViewHolder, int pos) {
final int position = pos;
Task currTask = taskList.get(pos);
taskViewHolder.taskTV.setText(currTask.getDescription());

**taskViewHolder.closeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("TRACE", "Closing task at position " + position);
// delete from SQLite DB
Task taskToDel = taskList.get(position);
taskToDel.delete();
// updating UI
taskList.remove(position);
thisAdapter.notifyItemRemoved(position);
}
});**
}

@Override
public int getItemCount() {
//Log.d("TRACE", taskList.size() + " tasks in DB");
return taskList.size();
}


// inflates row to create a viewHolder
@Override
public TaskViewHolder onCreateViewHolder(ViewGroup parent, int pos) {
View itemView = LayoutInflater.from(parent.getContext()).
inflate(R.layout.list_item, parent, false);
Task currTask = taskList.get(pos);

//itemView.setBackgroundColor(Color.parseColor(currTask.getColor()));
return new TaskViewHolder(itemView);
}
}

从我的回收站 View 中删除有时会产生意想不到的结果。有时被点击的元素前面的元素被删除,有时在“taskList.get(position)”处发生 indexOutOfBounds 异常。

阅读 https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.htmlhttps://developer.android.com/training/material/lists-cards.html没有让我更深入地了解为什么会发生这种情况以及如何解决它。

看起来 RecyclerView 回收了行,但我不希望 indexoutofbounds 异常使用较小的数字子集来索引我的列表。

最佳答案

RecyclerView 在位置改变时不会重新绑定(bind) View (出于明显的性能原因)。例如,如果您的数据集如下所示:

A B C D

然后您通过

添加项目 X
mItems.add(1, X);
notifyItemInserted(1, 1);

得到

A X B C D

RecyclerView 只会绑定(bind) X 并运行动画。

ViewHolder 中有一个 getPosition 方法,但如果您在动画中间调用它,它可能与适配器位置不匹配。

如果您需要适配器位置,最安全的选择是从适配器获取位置。

评论更新

将任务字段添加到 ViewHolder。

如下更改 onCreateViewHolder 以避免在每次重新绑定(bind)时创建监听器对象。

// inflates row to create a viewHolder
@Override
public TaskViewHolder onCreateViewHolder(ViewGroup parent, int type) {
View itemView = LayoutInflater.from(parent.getContext()).
inflate(R.layout.list_item, parent, false);

final TaskViewHolder vh = new TaskViewHolder(itemView);
taskViewHolder.closeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// delete from SQLite DB
Task taskToDel = vh.getTask();
final int pos = taskList.indexOf(taskToDel);
if (pos == -1) return;
taskToDel.delete();
// updating UI
taskList.remove(pos);
thisAdapter.notifyItemRemoved(pos);
}
});
}

所以在你的绑定(bind)方法中,你做

// onBindViewHolder binds a model to a viewholder
@Override
public void onBindViewHolder(TaskViewHolder taskViewHolder, int pos) {
Task currTask = taskList.get(pos);
taskViewHolder.setTask(currTask);
taskViewHolder.taskTV.setText(currTask.getDescription());
}

关于android - RecyclerView 适配器的位置与其数据集的索引有何关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26695229/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com