0Pricing
Android Academy · レッスン

RecyclerViewのクリックイベント

RecyclerViewで項目のクリックや長押しを処理し、クリックリスナーをアダプターに渡して、項目のタップ時に詳細画面へ遷移する方法を学びます。

「RecyclerViewのクリックイベント」はCoddyKit上の無料Android Academyレッスンです。 これはレッスン3/6です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAndroid Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Android Academyコースには全6レッスンが含まれています。

リスト項目をクリック可能にする

RecyclerViewには、ListView のような組み込みのクリックリスナーはありません。Adapter内にクリックリスナーを追加します。

推奨されるパターンは、Adapterのコンストラクタにラムダ(コールバック)を渡す方法です。項目がタップされると、Adapterが選択された項目を引数としてラムダを呼び出し、Activityが次の処理を担当します。

クリックコールバック付きAdapter

Adapterに onItemClick ラムダパラメータを追加します。

class FruitAdapter(
    private val fruits: List<Fruit>,
    private val onItemClick: (Fruit) -> Unit
) : RecyclerView.Adapter<FruitAdapter.ViewHolder>() {

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val tvName: TextView = view.findViewById(R.id.tvName)
        val tvCalories: TextView = view.findViewById(R.id.tvCalories)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_fruit, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val fruit = fruits[position]
        holder.tvName.text = fruit.name
        holder.tvCalories.text = "${fruit.calories} kcal"
        // Set click listener on the whole item
        holder.itemView.setOnClickListener {
            onItemClick(fruit)
        }
    }

    override fun getItemCount() = fruits.size
}

Activityでのクリック処理

Activityで、詳細画面へ遷移するラムダを渡します。

val adapter = FruitAdapter(fruits) { fruit ->
    // Called when user taps a fruit
    val intent = Intent(this, FruitDetailActivity::class.java)
    intent.putExtra("FRUIT_NAME", fruit.name)
    intent.putExtra("FRUIT_CALORIES", fruit.calories)
    startActivity(intent)
}

binding.recyclerView.apply {
    this.adapter = adapter
    layoutManager = LinearLayoutManager(this@MainActivity)
}

詳細画面でのデータ受け取り

詳細Activityでextraを読み取ります。

class FruitDetailActivity : AppCompatActivity() {

    private lateinit var binding: ActivityFruitDetailBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityFruitDetailBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val name = intent.getStringExtra("FRUIT_NAME") ?: "Unknown"
        val calories = intent.getIntExtra("FRUIT_CALORIES", 0)

        binding.tvDetailName.text = name
        binding.tvDetailCalories.text = "$calories kcal"
    }
}

効率的な更新のためのDiffUtil

リストのデータが変わったときに notifyDataSetChanged() を呼び出してはいけません。すべてを再描画してしまいます。代わりに DiffUtil を使います。

  • 変更前と変更後のリストの最小差分を計算する
  • 変更された項目だけをアニメーション表示する
  • パフォーマンスとUXが向上する

現在の推奨方法は、DiffUtilを自動的に使用する ListAdapter です。

DiffUtil付きListAdapter

ListAdapter を継承して、リストを自動的かつアニメーション付きで更新します。

class FruitAdapter(
    private val onItemClick: (Fruit) -> Unit
) : ListAdapter<Fruit, FruitAdapter.ViewHolder>(DIFF_CALLBACK) {

    companion object {
        val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Fruit>() {
            override fun areItemsTheSame(old: Fruit, new: Fruit) =
                old.name == new.name
            override fun areContentsTheSame(old: Fruit, new: Fruit) =
                old == new  // data class equals()
        }
    }

    // ... ViewHolder and onCreateViewHolder same as before ...

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val fruit = getItem(position)  // use getItem(), not fruits[position]
        holder.tvName.text = fruit.name
        holder.itemView.setOnClickListener { onItemClick(fruit) }
    }
}

新しいリストの送信

ListAdapter では、submitList() を呼び出してリストを更新します。DiffUtilが自動的にアニメーションを処理します。

// In Activity:
val adapter = FruitAdapter { fruit ->
    // handle click
}
binding.recyclerView.adapter = adapter

// Initial data
adapter.submitList(fruits)

// Later, update with new data (e.g. after filtering):
val filtered = fruits.filter { it.calories < 100 }
adapter.submitList(filtered)  // DiffUtil animates the change

長押しとコンテキストメニュー

onBindViewHolder で setOnLongClickListener を設定すると、長押しにも対応できます。

  • イベントを消費するには、リスナーから true を返す
  • 削除/編集ダイアログの表示に使用する
  • または ItemTouchHelper でスワイプ削除を実装する

項目の装飾を追加する

DividerItemDecoration を使って、リスト項目の間に視覚的な区切りを追加します。

binding.recyclerView.apply {
    adapter = fruitAdapter
    layoutManager = LinearLayoutManager(this@MainActivity)
    addItemDecoration(
        DividerItemDecoration(
            this@MainActivity,
            DividerItemDecoration.VERTICAL
        )
    )
}

クイックチェック

RecyclerView Adapterで項目のクリックを処理する推奨方法は何ですか?

まとめ:RecyclerViewのクリック処理

操作可能なリストを作成できるようになりました。

  • Adapterのコンストラクタにラムダコールバックを渡す
  • onBindViewHolder で holder.itemView.setOnClickListener を呼び出す
  • Intent経由でextraを渡して詳細画面へ遷移する
  • ListAdapter と DiffUtil を使って、滑らかでアニメーション付きの更新を行う
  • submitList() を呼び出して表示データを更新する

次は、SharedPreferencesを使ってデータをローカルに永続化します。

よくある質問

「RecyclerViewのクリックイベント」レッスンは無料ですか?

はい。「RecyclerViewのクリックイベント」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Android Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Android Academyコースには全6レッスンが含まれています。

「RecyclerViewのクリックイベント」で何を学びますか?

RecyclerViewで項目のクリックや長押しを処理し、クリックリスナーをアダプターに渡して、項目のタップ時に詳細画面へ遷移する方法を学びます。 ブラウザで直接実行するハンズオンコードでAndroid Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Android Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのAndroid Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/6です。

「RecyclerViewのクリックイベント」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このAndroid Academyレッスンでコードを書いて実行できますか?

はい。すべてのAndroid Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Kotlinコレクション
  2. RecyclerViewの基礎
  3. RecyclerViewのクリックイベント
  4. SharedPreferences
  5. DataStore Preferences
  6. AdaptersとDiffUtil
← Android Academyに戻る