簡體   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