1. ホーム
  2. java

RecyclerView.AdapterのonBindViewHolder内にOnClickListenerを追加することは、なぜ悪い習慣と考えられているのでしょうか?

2023-08-01 10:15:41

質問

私は以下のコードを RecyclerView.Adapter クラスで、それはうまく動作します。

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.Viewholder> {

    private List<Information> items;
    private int itemLayout;

    public MyAdapter(List<Information> items, int itemLayout){
        this.items = items;
        this.itemLayout = itemLayout;
    }

    @Override
    public Viewholder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(itemLayout, parent, false);
        return new Viewholder(v);
    }

    @Override
    public void onBindViewHolder(Viewholder holder, final int position) {
        Information item = items.get(position);
        holder.textView1.setText(item.Title);
        holder.textView2.setText(item.Date);

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(view.getContext(), "Recycle Click" + position, Toast.LENGTH_SHORT).show();
            }
        });

       holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
       @Override
       public boolean onLongClick(View v) {
          Toast.makeText(v.getContext(), "Recycle Click" + position, Toast.LENGTH_SHORT).show();
           return true;
       }
});
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    public class Viewholder extends RecyclerView.ViewHolder {
        public  TextView textView1;
        public TextView textView2;

        public Viewholder(View itemView) {
            super(itemView);
            textView1=(TextView) itemView.findViewById(R.id.text1);
            textView2 = (TextView) itemView.findViewById(R.id.date_row);

        }
    }
}

しかし、OnClickListenerを実装するのはバッドプラクティスであると私は考えています。 onBindViewHolder メソッドに実装するのは良くないと思います。なぜこれがバッドプラクティスなのか、また、より良い代替案は何でしょうか?

どのように解決するのですか?

ViewHolderの内部でクリックロジックを処理した方が良い理由は、より明示的なクリックリスナーを使用できるためです。コモンズウェアの本で表現されている通りです。

ListView の行にある RatingBar のようなクリック可能なウィジェットは、行自体のクリックイベントと長い間衝突していました。クリックできる行を取得し、行の内容もクリックできるようにすることは、時に少し厄介です。RecyclerViewでは、この種のものがどのように処理されるかをより明確に制御することができます... なぜなら、クリック処理ロジックのすべてを設定するのはあなた自身だからです。

ViewHolderモデルを使用することで、RecyclerViewでのクリック処理のために、以前のListViewよりも多くの利点を得ることができます。これについては、違いを比較したブログ記事で書きました。 https://androidessence.com/recyclerview-vs-listview

なぜ、ViewHolderの中ではなく onBindViewHolder() の中ではなく、ビューホルダーの中が良い理由については、それは onBindViewHolder() が各項目ごとに呼び出されるためで、クリックリスナーを設定することは、ViewHolder コンストラクタで一度呼び出すことができれば、繰り返す必要がないオプションです。次に、クリックの応答がクリックされた項目の位置に依存する場合、単に getAdapterPosition() を ViewHolder 内から呼び出すだけです。 ここで をどのように使うかを示す別の回答です。 OnClickListener をViewHolderクラス内から使用する方法を示しています。