如何从ViewHolder删除一行回收器视图

时间:2018-08-22 16:06:36

标签: android android-recyclerview android-viewholder

谢谢您的光临。

不久前,有人向我解释说您不应将数据存储在ViewHolder中,我明白了为什么。但这会使事情复杂化。

如果用户单击行内的button,我想删除行。因此,我需要访问adapter。但是我无法将其存储在ViewHolder上。怎么回事?

我也在寻找您所知道的最好的recyclerview文章,因为它看起来像人们不知道他们在大多数堆栈溢出中谈论的内容并给出了错误的建议(将数据存储在{{1 }})

编辑:我正在尝试一种解决方案,但是当我在适配器中时,getTag返回我为空

这是我的物品和装订物:

ViewHolder

我的适配器:

public final class ItemViewMail extends RecyclerView.ViewHolder {

    private AppCompatImageButton cancelButton;


    public ItemViewMail(View itemView) {
        super(itemView);
        this.cancelButton = itemView.findViewById(R.id.profile_item_edit_email_cancel_image_button);
    }

    public void bind(Data data, View.OnClickListener deleteOnClickListener) {
        this.itemView.setTag(data);

        if (cancelButton != null) {
            cancelButton.setOnClickListener(deleteOnClickListener);
        }
    }

}

3 个答案:

答案 0 :(得分:0)

您可以从适配器中删除该项目,并通知它有关已删除的行的信息,该条目将随着删除的内容而平稳更新。还要从数据源中删除该项目,好像您已经在做那样。

mAdapter.getItems().remove(mPosition);
mAdapter.notifyItemRemoved(mPosition);

答案 1 :(得分:0)

data class MyItem(val name: String)

class MyViewHolder(itemView: View,
                   private val onRemoveClickListener: View.OnClickListener) : RecyclerView.ViewHolder(itemView) {

    fun bind(item: MyItem) {
        itemView.setOnClickListener(onRemoveClickListener)
        itemView.setTag(item)
        //todo: eg. itemView.name.setText(item.name)
    }
}

class MyRecyclerViewAdapter(private val onRemoveClickListener: View.OnClickListener): RecyclerView.Adapter<MyViewHolder>() {

    var items = listOf<MyItem>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.viewholder_my)
        return MyViewHolder(view, onRemoveClickListener)
    }

    override fun getItemCount(): Int {
        return items.size
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.bind(items[position])
    }

}

现在,您可以在活动/片段/等内部创建MyRecyclerViewAdapter并将onClickListener用作参数。

class MyActivity: AppCompatActivity() {

    private lateinit var adapter: MyRecyclerViewAdapter 

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        adapter = MyRecyclerViewAdapter(View.OnClickListener { view ->
            val clickedItem = view.getTag() as MyItem
            adapter.items.remove(clickedItem)
            adapter.notifyDataSetChanged()
        })
    }
}

答案 2 :(得分:0)

  

如果用户单击行内的按钮,我想删除行。所以我需要访问适配器。但是我无法将其存储在ViewHolder上。怎么回事?

RecyclerView.ViewHolder的基本实现提供了两种在需要访问位置信息时可以调用的方法:getAdapterPosition()getLayoutPosition()。就您而言,这听起来像您想要第一个。

这使您可以编写如下代码:

public void soSomethingOnClick() {
    int position = getAdapterPosition();

    if (position != RecyclerView.NO_POSITION) {
        myDataStructure.removeItemAt(position);
        myAdapter.notifyItemRemoved(position);
    }
}
  

不久前,有人向我解释说您不应该将数据存储在ViewHolder中,我知道为什么。但这会使事情复杂化。

我不确定您听到了什么,但是将信息存储在ViewHolder中完全可以。您必须非常小心,以确保始终更新要存储的任何数据,以便在回收ViewHolder时不会使数据不同步,但是很多ViewHolder实现都充分利用了ViewHolders是保存数据的好地方。