[英]Getting an adapter instance from a ViewHolder
I'm trying to create a contextual floating menu with the information (position,id,etc) of the selected menu to be accessible inside the overridden method onContextItemSelected
in my Fragment.我正在尝试创建一个上下文浮动菜单,其中包含可在我的 Fragment 中的重写方法onContextItemSelected
中访问的所选菜单的信息(位置、ID 等)。
So I have a custom adapter extending from RecyclerView.Adapter<ViewHolder>
and a custom ViewHolder
class in separate file.所以我有一个从RecyclerView.Adapter<ViewHolder>
扩展的自定义适配器和一个单独文件中的自定义ViewHolder
类。 I registered my click listener and provided its handler inside the custom ViewHolder
class.我注册了我的点击监听器并在自定义ViewHolder
类中提供了它的处理程序。
Since I need to send the ViewHolder
information back to my Fragment when the event is fired, I need to have a reference to my Adapter because my fragment has the adapter object reference
but not viewholder object reference
.由于我需要在触发事件时将ViewHolder
信息发送回我的 Fragment,因此我需要对我的 Adapter 进行引用,因为我的片段具有adapter object reference
但没有viewholder object reference
。 So in instantiation stage of the custom ViewHolder
(because there is no method to get Adapter reference from ViewHolder
class), I pass the adapter reference to constructor of the custom ViewHolder
for the use in its handler so I can call this reference inside the ViewHolder
class to pass the information to Adapter
from ViewHolder
, and finally from Adapter
to Fragment
.因此,在自定义ViewHolder
实例化阶段(因为没有从ViewHolder
类获取适配器引用的方法),我将适配器引用传递给自定义ViewHolder
构造函数以在其处理程序中使用,因此我可以在ViewHolder
类中调用此引用将信息从ViewHolder
传递给Adapter
,最后从Adapter
传递给Fragment
。
My question is, is there a better practice or a general approach by still keeping the handler inside the ViewHolder
?我的问题是,将处理程序保留在ViewHolder
是否有更好的做法或通用方法? In my case, I notice every ViewHolder instance will have to keep a reference to adapter, which consumes memory.就我而言,我注意到每个 ViewHolder 实例都必须保留对适配器的引用,这会消耗内存。 Is there any conflict that may arise in the future by doing it the way I listed above?如果按照我上面列出的方式进行操作,将来是否会出现任何冲突?
Maybe I'm not understanding well your pattern, but the reference you are looking for, it is already there.也许我不太了解您的模式,但是您正在寻找的参考资料已经存在。
The fragmens knows the adapter reference, and the adapter knows your viewholder. Fragmen 知道适配器引用,而适配器知道您的查看器。 Use getAdapterPosition() to get that reference to your Object使用getAdapterPosition()获取对您的对象的引用
Suppose to have a ArrayList<String>
named list in your RecyclerView.Adapter<ViewHolder>
: this code, for example, shows a Toast in the Fragment with the value of the clicked String假设在您的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();
}
});
}
Stumbled upon the same problem.偶然发现了同样的问题。 The two variants give the same result, without using static references:这两个变体给出了相同的结果,不使用静态引用:
Suppose you have an ItemObjects class with name, price, address etc variables假设您有一个带有名称、价格、地址等变量的 ItemObjects 类
In the Adapter, attach the ArrayList as Tag to the layoutView :在 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);
}
}
Then, in the ViewHolder:然后,在 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());
}
}
Move the ViewHolder back as inner class into the Adapter.将 ViewHolder 作为内部类移回适配器中。 This way you can access the ArrayList directly :这样您就可以直接访问 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)); } } }
In my case, i start an Activity onClick and both variants work.就我而言,我启动了一个 Activity onClick 并且两个变体都有效。 In your case it would be better to use an inner class and access it through MyRecyclerViewAdapter.MyViewHolders在您的情况下,最好使用内部类并通过 MyRecyclerViewAdapter.MyViewHolders 访问它
Pass the adapter in the constructor of the view holder在视图持有者的构造函数中传递适配器
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);
}
You may pass the adapter in the view holder constructor as Blake mentioned.您可以在 Blake 提到的视图持有者构造函数中传递适配器。 However, if the view holder class is an inner class of the Adapter you may access methods of the adapter directly without needing to pass a reference.但是,如果视图持有者类是适配器的内部类,则您可以直接访问适配器的方法而无需传递引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.