1

編集:匿名リスナー

私は、大規模なデータ・セットのいずれかのパフォーマンスの問題かどうかを引き起こすbindViewHolder方法で匿名リスナーの作成について知りたいです。

私はRecyclerViewアダプターを持っているとします。そしてbindViewHolderメソッドでは、私はすべてのリスナーを設定します。匿名でこれはパフォーマンス上の問題を引き起こしますか?ユーザーがRecyclerViewをスクロールすると、多数のAnonymousリスナーが作成され、それらをビューに設定するためです。

例:

view.setOnClickListener(new View.OnClickListener() 
{ 
    @Override 
    public void onClick(View v) 
    { 
    } 
}); 

または私は私のViewHolderクラスでOnClickListenerを実装し、ちょうどここでviews.Like

view.setOnClickListener(this); 

を追加することができます匿名リスナーの多くは作成されません。これは、大規模なデータセットのパフォーマンス計算において以前のものより優れていますか?

ありがとうございます。

+0

viewholder create listenerの内部でこれを試すことができます。パフォーマンスを向上させるthis.setIsRecyclable(false)というプロパティが1つあります。https://stackoverflow.com/questions/46095866/getting-android-recyclerview-to -update-view-inside-react-native-component/46313257#46313257 –

答えて

0

基本的にはRecyclerViewのすべての項目にOnClickListenerを設定し、ActivityまたはFragmentに「接続」します。この「接続」は重要なので、ActivityまたはFragmentの中にonItemClickメソッドを持ち、そのメンバーにアクセスすることができます。

最小限の実装は、(Fragmentに、しかし、あなたはまた、Activityを使用することができます)、次のようになります。

public class YourFragment extends Fragment implements RecyclerViewAdapter.ItemClickListener { 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
     super.onCreateView(inflater, container, savedInstanceState); 

     View view = inflater.inflate(R.layout.fragment_your, container, false); 

     RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview); 
     RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(activity); 
     recyclerViewAdapter.setClickListener(this); 
     recyclerView.setAdapter(recyclerViewAdapter); 

     return view; 
    } 

    @Override 
    public void onItemClick(View view, int position) { 
     // do something here 
    } 
} 

そしてAdapterクラス

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> { 
    private ItemClickListener itemClickListener; 

    void setClickListener(ItemClickListener itemClickListener) { 
     this.itemClickListener = itemClickListener; 
    } 

    interface ItemClickListener { 
    void onItemClick(View view, int position); 
    } 

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 
     // TextView is an example 
     final TextView textView; 

     ViewHolder(View itemView) { 
      super(itemView); 
      textView = (TextView) itemView.findViewById(R.id.text); 
      textView.setOnClickListener(this); 
     } 

     @Override 
     public void onClick(View view) { 
      if (itemClickListener != null) { 
       itemClickListener.onItemClick(view, getAdapterPosition()); 
      } 
     } 
    } 
} 
+0

私はここで解決策を求めているわけではありません。とりあえずありがとう。 –

1

RecyclerViewは、いくつかの項目のみ表示されます、 ViewHolderは、表示されているアイテムに対してのみ作成されるため、アダプタに1000sのアイテムがある場合でも、わずかな割合のViewHoldersが作成されます。

しかし、あなたはそれが唯一のリスナーの参照を保持して数ミリ秒、その後かからない項目は、リサイクルされたとき、あなたは何度も何度も同じリスナーを設定します最もsetListener方法のためaddListener方法と注意する必要があります実装。

ただし、addListenerを使用すると、古いリスナーを削除してから新しいリスナーを追加する必要があります。私は、コンパイラはちょうどフードの下、あなたの匿名クラスの無名のコンクリート版を作成し、かなり確信しているsetListener

例はsetClickListenerあるとaddListenerの例はaddTextWatcher

//.. part of adapter 

private TextWatcher textWatcher; 

public void bindViewHolder(DataViewHolder holder, int index){ 

    // no performance issue 
    holder.button.setClickListener(....); 

    // wrong, this is added everytime 
    holder.editText.addTextWatcher(....); 


    // this is safe... 
    if(textWatcher != null) 
     holder.editText.removeTextWatcher(textWatcher); 

    textWatcher = new TextWatcher(){ 
     // ... implementation 
    }; 
    holder.editText.addTextWatcher(textWatcher); 
} 
+1

あなたの答えをありがとう。実際に私はリスナーを匿名で設定することに重点を置いていました(私の質問を編集しました。申し訳ありません)。スクロールするとき。私が間違っていれば私を訂正してください。ありがとう –

0

です。これは、インターフェイスを実装し、具体的なリスナーとしてthisを提供することとほぼ同じです。現実的には、いずれかのパフォーマンスに問題はありません。

匿名クラスが外部クラスへの参照を保持していることに注意してください。それはメモリリークを引き起こすかもしれません(例:外部クラスがアクティビティの場合)、またはガベージコレクションが時間の経過と共に小さな断片の代わりに一気に行われるようにします。詳細は、オラクルのドキュメントのImplicit and Synthetic Parametersを参照してください。