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

0md85ypi  于 2023-04-10  发布在  Android
关注(0)|答案(3)|浏览(149)

谢谢你过来
不久前,有人向我解释说你不应该在ViewHolder中存储数据,我明白为什么。
我想删除一个行,如果用户点击行内的按钮。所以我需要访问适配器。但我不能将其存储在ViewHolder。什么方法?

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

这是我的项目和绑定:

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);
        }
    }

}

我的适配器:

private ArrayList<Data> rowDataArrayList;

    MyPVPViewAdapter(ArrayList<Data> rowDataArrayList) {
        this.rowDataArrayList = rowDataArrayList;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int itemType) {                    
    return new ItemViewMail(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.profile_item_edit_email, viewGroup ,false));
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder myViewHolder, int position) {
          ((ItemViewMail) myViewHolder).bind((Data) rowDataArrayList.get(position).getData(), onClickListener);
    }

    @Override
    public int getItemViewType(int position) {
        return rowDataArrayList.get(position).getType();
    }

    @Override
    public int getItemCount() {
        return rowDataArrayList.size();
    }

    View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Data data = (Data) v.getTag();
        }
    };

}
yfwxisqw

yfwxisqw1#

您可以从适配器中删除该项,并通知它已删除的行,它将随着删除而顺利更新。同时从数据源中删除该项,尽管看起来您已经在这样做了。

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

ui7jx7zq2#

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])
    }

}

现在你可以在你的activity/fragment/etc中创建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()
        })
    }
}
tv6aics1

tv6aics13#

我想删除一个行,如果用户点击行内的按钮。所以我需要访问适配器。但我不能将其存储在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实现都明确地利用了ViewHolder是一个保存数据的好地方的事实。

相关问题