0Pricing
Android Academy · Урок

События нажатия в RecyclerView

Обрабатывайте нажатия и длительные нажатия на элементы в RecyclerView, передавайте обработчики нажатий адаптерам и переходите к экрану подробностей при выборе элемента.

«События нажатия в RecyclerView» — бесплатный урок Android Academy на CoddyKit. Это урок 3 из 6. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Android Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Android Academy содержит 6 уроков всего.

Добавление нажатий к элементам списка

У RecyclerView нет встроенного обработчика нажатий, как у ListView. Обработчики нажатий добавляются внутри адаптера.

Рекомендуемый подход: передайте лямбда-выражение (обратный вызов) в конструктор адаптера. При нажатии на элемент адаптер вызовет лямбда-выражение с выбранным элементом — Activity обработает дальнейшие действия.

Адаптер с обратным вызовом нажатия

Добавьте параметр-лямбда 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 с подробностями:

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:

  • Вычисляет минимальные различия между старым и новым списками
  • Анимирует только изменившиеся элементы
  • Повышает производительность и удобство использования

Современный способ — использовать ListAdapter, который автоматически применяет DiffUtil.

ListAdapter с DiffUtil

Расширьте 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

Долгое нажатие и контекстные меню

Вы также можете обрабатывать долгие нажатия, задавая setOnLongClickListener в onBindViewHolder:

  • Возвращайте true из обработчика, чтобы поглотить событие
  • Используйте его для показа диалога удаления или редактирования
  • Или реализуйте удаление свайпом с помощью ItemTouchHelper

Добавление разделителей элементов

Добавьте визуальные разделители между элементами списка с помощью DividerItemDecoration:

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

Быстрая проверка

Как рекомендуется обрабатывать нажатия на элементы в адаптере RecyclerView?

Итоги: нажатия в RecyclerView

Теперь вы умеете создавать интерактивные списки:

  • Передавайте лямбда-обратный вызов в конструктор адаптера
  • В onBindViewHolder вызывайте holder.itemView.setOnClickListener
  • Переходите на экран подробностей, передавая дополнительные данные через Intent
  • Используйте ListAdapter + DiffUtil для плавного обновления списка с анимацией
  • Вызывайте submitList() для обновления отображаемых данных

Далее: локальное сохранение данных с помощью SharedPreferences.

Часто задаваемые вопросы

Урок «События нажатия в RecyclerView» бесплатный?

Да — полный текст урока «События нажатия в RecyclerView» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Android Academy, подпишись на CoddyKit PRO. Курс Android Academy содержит 6 уроков всего.

Чему я научусь в уроке «События нажатия в RecyclerView»?

Обрабатывайте нажатия и длительные нажатия на элементы в RecyclerView, передавайте обработчики нажатий адаптерам и переходите к экрану подробностей при выборе элемента. Ты практикуешь Android Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Android Academy?

Предыдущий опыт не требуется. Android Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 6.

Сколько времени занимает урок «События нажатия в RecyclerView»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Android Academy?

Да. Каждый урок Android Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Коллекции Kotlin
  2. Основы RecyclerView
  3. События нажатия в RecyclerView
  4. SharedPreferences
  5. Настройки DataStore
  6. Адаптеры и DiffUtil
← Назад к Android Academy