0

内部RecyclerView項目に取り組んでいない私のアプリケーションは、以下の構造を使用しています:クリックして、フラグメント

Activity > ViewPager > FragmentStatePagerAdapter > Fragment > RecyclerView 

を私は過去にかなり楽にRecyclerViewsを使用してきたが、いくつかの理由のために私はクリックを登録するには私のRecyclerViewアイテムを取得することはできませんフラグメント内に配置されたイベント私のViewHolderは次のとおりです:

// ViewHolder Class for ExhibitAdapter 
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 
     public TextView itemTitleTextView; 
     public TextView itemDescriptionTextView; 
     public NetworkImageView itemCoverPhoto; 

     public ViewHolder(View itemView) { 
      super(itemView); 
      itemCoverPhoto = (NetworkImageView) itemView.findViewById(R.id.exhibitThumbnailNIV); 
      itemTitleTextView = (TextView) itemView.findViewById(R.id.exhibitNameTV); 
      itemDescriptionTextView = (TextView) itemView.findViewById(R.id.exhibitDescriptionTV); 
      itemView.setOnClickListener(this); 
     } 


     @Override 
     public void onClick(View view) { 
      try { 
       Log.d(TAG, "Exhibit clicked"); 
       Exhibit currentExhibit = exhibits.get(getAdapterPosition()); 
       intent.putExtra(ExhibitContentActivity.EXHIBIT_ID , currentExhibit.getId()); 
       intent.putExtra(ExhibitContentActivity.EXHIBIT_COVER_URL , currentExhibit.getCoverPhotoUrl()); 

       ActivityOptionsCompat options = ActivityOptionsCompat. 
         makeSceneTransitionAnimation((Activity) adapterContext, itemView.findViewById(R.id.exhibitThumbnailNIV), "profile"); 

       Log.i(TAG, "Attempting to launch detail activity with exhibit id: " + currentExhibit.getId()); 

       adapterContext.startActivity(intent, options.toBundle()); 

      } 
      catch(IndexOutOfBoundsException e) { 
       Log.e(TAG, "* Error: Adapter position exceeded the no. of items."); 
      } 
     } 

    } 

助けてください。フラグメントインタラクションリスナーを作成するにはhttps://guides.codepath.com/android/Creating-and-Using-Fragments#fragment-listenerの手順に従ってみましたが、RecyclerViewのアダプタ内でこれをどのように実装するのか分かりません。前もって感謝します!

+0

あなたはこれに対する解決策を見つけましたか? –

+1

@MichaelA。ええ、問題は単純に1でした。私のアイテムのレイアウトは、描画には時間がかかりすぎていました.2私はViewHolderクラス内でonClickロジックを処理していました。私はフラグメント内にリスナー・インターフェースを作成し、そのリスナーのonMyItemClickメソッドをViewHolderのonClickで呼び出し、メイン・アクティビティーでそのリスナーを実装することで解決しました。これにより、アイテムがクリックされたときに何をすべきかを定義し、クリックイベントを主なアクティビティに効率的にバブリングすることができました。 –

答えて

1

ViewHolderではなく、RecyclerViewアダプタのonBindViewHolderメソッドでonClickListenerを設定する必要があります。問題は、ViewHoldersは実際のビューではない(つまり、クリックすることはできません)、ビューにバインドするホルダーであり、複数のリスト項目に対してそれらのビューを再利用できるため、アプリケーションのメモリ占有量を削減できます。

RecyclerView.Adapter実装

public MyAdapter extends RecyclerView.Adapter<YourViewHolderClass> { 
    . 
    . 
    . 
    @Override 
    public void onBindViewHolder(final YourViewHolderClass holder, int position) { 
     holder.itemView.setOnClickListener (new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       // Do something! 
      } 
     }); 
     // Do you other view binding operations 
    } 
    . 
    . 
    . 
} 

はあなたのリスト項目のコンテナにOnClickListenerをバインドすることができるように、あなたのビューホルダーでローカルitemViewのコピーを保管してください。

RecyclerView.ViewHolder実装

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 
    public TextView itemTitleTextView; 
    public TextView itemDescriptionTextView; 
    public NetworkImageView itemCoverPhoto; 
    public View itemView; 

    public ViewHolder(View itemView) { 
     super(itemView); 
     this.itemView = itemView; 
     itemCoverPhoto = (NetworkImageView) itemView.findViewById(R.id.exhibitThumbnailNIV); 
     itemTitleTextView = (TextView) itemView.findViewById(R.id.exhibitNameTV); 
     itemDescriptionTextView = (TextView) itemView.findViewById(R.id.exhibitDescriptionTV); 
    } 

}

が、私はこのことができます願っています!

-tom

+0

Thanks Tomですが、onBindViewHolderの中にonClickListenerがない理由は、毎回新しいView.OnClickListenerを作成し、RecyclerViewを使用することによるパフォーマンスのメリットを奪うからです。 ViewHolderは一度作成されるので、onClickListenerを添付するのが標準的な方法です。この方法では、必要なだけonBindView内のデータが変更され、onClick機能も使用されます。問題は、フラグメント内でクリックが機能しないことです。だから私はクリックが自分の活動までバブリングされる必要があると思っています。 –

関連する問題