如何删除RecycleViewAdapter中的ViewHolder



你好,这是我关于stackoverflow的第一个问题。我见过这个问题,但他们的解决方案都没有真正帮助我

如何更新RecyclerView适配器数据?

  1. 我的问题是,我想删除视图支架,而不是回收它。当按下删除按钮时,视图支架不会被删除,而是被回收,这意味着计数器不会用"1〃;,但具有旧的价值观。例如,如果我删除了计数器为7的第一个项目,并在空的回收器视图中添加了一个新项目,那么计数器将用7而不是1初始化。

  2. 当删除带有items.remove(position); notifyItemRemoved(position);的视图时,我必须使用notifyItemRangeChanged(position, items.size());,因为位置不会更新。例如:删除第一个元素时,位置为0的回收视图的第一个元素将被删除。当再次删除回收视图的第一个项目时,第二个项目将在位置1处删除。所以我必须使用notifyItemRangeChanged(position, items.size());。但是,有没有更干净的方式来通知我的适配器物品在回收器视图中的正确位置?

公共类ItemsRecViewAdapter扩展了RecyclerView。适配器<ItemsRecViewAdapter。ViewHolder>{

private Context context;
private ArrayList<Item> items;
public ItemsRecViewAdapter(Context context) {
this.context = context;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recycler_view_item,parent,false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.groceryItem.setText(items.get(position).getName());
holder.parent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, items.get(position).getName()+" selected.", Toast.LENGTH_SHORT).show();
}
});
holder.plusButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int counter = Integer.parseInt(holder.counter.getText().toString());
counter++;
holder.counter.setText(String.valueOf(counter));
notifyDataSetChanged();
}
});
holder.minusButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int counter = Integer.parseInt(holder.counter.getText().toString());
if (counter == 1){
Toast.makeText(context, items.get(position).getName()+" deleted.", Toast.LENGTH_SHORT).show();
items.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, items.size());
}
else{
counter--;
holder.counter.setText(String.valueOf(counter));
notifyDataSetChanged();
}
}
});
holder.deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, items.get(position).getName()+" deleted.", Toast.LENGTH_SHORT).show();
items.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, items.size());
}
});
}
@Override
public int getItemCount() {
return items.size();
}
public void setItems(ArrayList<Item> items) {
this.items = items;
notifyDataSetChanged();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView groceryItem, counter;
private LinearLayout parent;
private ImageButton plusButton, minusButton, deleteButton;
public ViewHolder(@NonNull View itemView) {
super(itemView);
groceryItem = itemView.findViewById(R.id.groceryItem);
counter = itemView.findViewById(R.id.counter);
plusButton = itemView.findViewById(R.id.plusButton);
minusButton = itemView.findViewById(R.id.minusButton);
deleteButton = itemView.findViewById(R.id.deleteButton);
parent = itemView.findViewById(R.id.parent);
}
}

}

这是我的主要活动类:

public class MainActivity extends AppCompatActivity {
private EditText mEditText;
private Button mAddButton;
private RecyclerView mRecView;

private ImageButton mPlusButton;
private TextView mCounter;
private ArrayList<Item> items;
ItemsRecViewAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditText = findViewById(R.id.item_editText);
mAddButton = findViewById(R.id.add_button);
adapter = new ItemsRecViewAdapter(MainActivity.this);
mRecView = findViewById(R.id.itemsRecyclerView);
mRecView.setAdapter(adapter);
mRecView.setLayoutManager(new LinearLayoutManager(MainActivity.this,RecyclerView.VERTICAL,false));
items = new ArrayList<>();
adapter.setItems(items);

mAddButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!mEditText.getText().toString().equals("")) {
Item item = new Item(mEditText.getText().toString());
items.add(item);
adapter.setItems(items);
if (mEditText.length() > 0) {
TextKeyListener.clear(mEditText.getText());
}
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.deleteAllBtn:
items.clear();
adapter.notifyDataSetChanged();
Toast.makeText(this, "All items deleted...",Toast.LENGTH_SHORT).show();
break;
}
return true;
}

}

我很享受这一切,如果能给我任何提示,我将不胜感激。

ViewHolders不适合存储任何数据,因为它们是不稳定的,并且在不同的项之间重复使用。试图";删除";viewholder是试图修复糟糕实现的一种扭曲方式。

您应该将counter作为您可以修改的Item中的字段,或者保存一个可以与项目匹配的计数器阵列。然后您需要在onBindViewHolder期间使用该数据。更改一个字段后也不需要调用notifyDatasetChanged,因为您没有更改列表的结构。

您也犯了在侦听器中存储对position参数的硬引用的错误——您应该使用返回当前项位置的holder.getBindingAdapterPosition(),这样您就不需要再通知项范围更改了——而且您也不需要每次绑定viewholder时都实例化它们,在这种情况下,它们只能创建一次。

这就是通过将counter字段添加到Item:来清理适配器的方法

public class ItemsRecViewAdapter extends RecyclerView.Adapter<ItemsRecViewAdapter.ViewHolder> {
private Context context;
private ArrayList<Item> items;
public ItemsRecViewAdapter(Context context) {
this.context = context;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recycler_view_item,parent,false);
ViewHolder holder = new ViewHolder(view);
holder.parent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, items.get(holder.getBindingAdapterPosition()).getName()+" selected.", Toast.LENGTH_SHORT).show();
}
});
holder.plusButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Item item = items.get(holder.getBindingAdapterPosition());
item.setCounter(item.getCounter()+1);
holder.counter.setText(String.valueOf(item.getCounter()));
}
});
holder.minusButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Item item = items.get(holder.getBindingAdapterPosition());
if (item.getCounter() == 1){
Toast.makeText(context, item.getName()+" deleted.", Toast.LENGTH_SHORT).show();
items.remove(holder.getBindingAdapterPosition());
notifyItemRemoved(holder.getBindingAdapterPosition());
}
else{
item.setCounter(item.getCounter()-1);
holder.counter.setText(String.valueOf(item.getCounter()));
}
}
});
holder.deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Item item = items.get(holder.getBindingAdapterPosition());
Toast.makeText(context, item.getName()+" deleted.", Toast.LENGTH_SHORT).show();
items.remove(holder.getBindingAdapterPosition());
notifyItemRemoved(holder.getBindingAdapterPosition());
}
});
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Item item = items.get(position);
holder.groceryItem.setText(item.getName());
holder.counter.setText(String.valueOf(item.getCounter()));
}
@Override
public int getItemCount() {
return items.size();
}
public void setItems(ArrayList<Item> items) {
this.items = items;
notifyDataSetChanged();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView groceryItem, counter;
private LinearLayout parent;
private ImageButton plusButton, minusButton, deleteButton;
public ViewHolder(@NonNull View itemView) {
super(itemView);
groceryItem = itemView.findViewById(R.id.groceryItem);
counter = itemView.findViewById(R.id.counter);
plusButton = itemView.findViewById(R.id.plusButton);
minusButton = itemView.findViewById(R.id.minusButton);
deleteButton = itemView.findViewById(R.id.deleteButton);
parent = itemView.findViewById(R.id.parent);
}
}
}

相关内容

  • 没有找到相关文章

最新更新