![](/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.