从ViewHolder获取适配器实例

时间:2016-06-06 07:46:22

标签: java android android-fragments

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

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

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

我的问题是,通过将处理程序保留在Fragment内,是否有更好的做法或一般方法?在我的例子中,我注意到每个ViewHolder实例都必须保留对适配器的引用,这会消耗内存。通过我上面列出的方式,将来是否会出现任何冲突?

4 个答案:

答案 0 :(得分:0)

也许我不能很好地理解你的模式,但你正在寻找的参考,它已经存在。

fragmens知道适配器引用,并且适配器知道您的视图。 使用getAdapterPosition()获取对象的引用

假设在ArrayList<String>中有RecyclerView.Adapter<ViewHolder>名为的列表:例如,此代码在片段中显示Toast,其中包含所点击字符串的值

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

}

答案 1 :(得分:0)

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

假设您有一个包含名称,价格,地址等变量的ItemObjects类

  1. ViewHolder作为外部类:
  2. 在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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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