繁体   English   中英

从 ViewHolder 获取适配器实例

[英]Getting an adapter instance from a ViewHolder

我正在尝试创建一个上下文浮动菜单,其中包含可在我的 Fragment 中的重写方法onContextItemSelected中访问的所选菜单的信息(位置、ID 等)。

所以我有一个从RecyclerView.Adapter<ViewHolder>扩展的自定义适配器和一个单独文件中的自定义ViewHolder类。 我注册了我的点击监听器并在自定义ViewHolder类中提供了它的处理程序。

由于我需要在触发事件时将ViewHolder信息发送回我的 Fragment,因此我需要对我的 Adapter 进行引用,因为我的片段具有adapter object reference但没有viewholder object reference 因此,在自定义ViewHolder实例化阶段(因为没有从ViewHolder类获取适配器引用的方法),我将适配器引用传递给自定义ViewHolder构造函数以在其处理程序中使用,因此我可以在ViewHolder类中调用此引用将信息从ViewHolder传递给Adapter ,最后从Adapter传递给Fragment

我的问题是,将处理程序保留在ViewHolder是否有更好的做法或通用方法? 就我而言,我注意到每个 ViewHolder 实例都必须保留对适配器的引用,这会消耗内存。 如果按照我上面列出的方式进行操作,将来是否会出现任何冲突?

也许我不太了解您的模式,但是您正在寻找的参考资料已经存在。

Fragmen 知道适配器引用,而适配器知道您的查看器。 使用getAdapterPosition()获取对您的对象的引用

假设在您的RecyclerView.Adapter<ViewHolder>有一个ArrayList<String>命名列表:例如,此代码在 Fragment 中显示了一个 Toast,其中包含单击的 String 的值

public ViewHolder( View itemView) {

    super(itemView);

    itemView.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            String myValue = list.get( getAdapterPosition() ); // your object 
            Toast.makeText(activity, myValue, Toast.LENGTH_SHORT).show();
        }
    });

}

偶然发现了同样的问题。 这两个变体给出了相同的结果,不使用静态引用:

假设您有一个带有名称、价格、地址等变量的 ItemObjects 类

  1. ViewHolder 作为外部类:

在 Adapter 中,将 ArrayList 作为 Tag 附加到 layoutView :

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyViewHolders> {

private List<ItemObjects> itemList;
private Context context;

public MyRecyclerViewAdapter(Context context, List<ItemObjects> itemList) {
    this.itemList = itemList;
    this.context = context;
}

@Override
public MyViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {

    View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_list_cell, parent, false);
    layoutView.setTag(itemList);
    return new MyViewHolders(layoutView);
}
}

然后,在 ViewHolder 中:

public class MyViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener {

public MyViewHolders(View itemView) {
    super(itemView);
    itemView.setOnClickListener(this);
    //................
 }

@Override
public void onClick(View view) {

    Log.d(TAG, "onClick: itemName " + ((ArrayList<ItemObjects>) itemView.getTag())
            .get(getAdapterPosition()).getItemName());
 }
}
  1. 将 ViewHolder 作为内部类移回适配器中。 这样您就可以直接访问 ArrayList :

     public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolders> { private static List<ItemObjects> itemList; //........................ public static class MyViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener { //....................... @Override public void onClick(View view) { Intent intent = new Intent(view.getContext(), DetailActivity.class); Log.d(TAG, "onClick: itemName " + itemList.get(getAdapterPosition()).getItemName()); view.getContext().startActivity( new Intent(view.getContext(), DetailActivity.class)); } } }

    就我而言,我启动了一个 Activity onClick 并且两个变体都有效。 在您的情况下,最好使用内部类并通过 MyRecyclerViewAdapter.MyViewHolders 访问它

在视图持有者的构造函数中传递适配器

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_layout, parent, false);
    return new MyViewHolder(this, view);
}

您可以在 Blake 提到的视图持有者构造函数中传递适配器。 但是,如果视图持有者类是适配器的内部类,则您可以直接访问适配器的方法而无需传递引用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM