![](/img/trans.png)
[英]Unable to call method in Adapter from ViewHolder (RecyclerView)
[英]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 类
在 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());
}
}
将 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.