Найти в Дзене
Nuances of programming

Kotlin-реализация RecyclerView на Android

Источник: Nuances of Programming У вас есть большой список данных для показа пользователям вашего приложения? Ищете гибкий, удобный для разработчиков и пользователей способ отображения данных? Тогда RecyclerView  —  именно то, что вам нужно. RecyclerView  —  это расширенная версия ListView, только более мощная и гибкая. RecyclerView относится к семейству ViewGroup, которое является оптимизированным преемником ListView и GridView. Как следует из названия, RecyclerView перезапускает верхние элементы списка, которые, уходя за пределы с экрана, становятся невидимыми для пользователя. Например, если пользователь прокрутит список вниз до пункта 6 или 7, то элементы в позиции 1, 2 или 3 будут удалены из памяти. В результате сокращается расход памяти. Предварительные условия: Компоненты, необходимые для настройки RecyclerView: Пошаговое погружение в процесс написания кода Создание нового проекта: Создание Model Код для нашего класса моделей такой: data class FoodItem(val name:String, val price
Оглавление

Источник: Nuances of Programming

У вас есть большой список данных для показа пользователям вашего приложения? Ищете гибкий, удобный для разработчиков и пользователей способ отображения данных?

Тогда RecyclerView  —  именно то, что вам нужно.

RecyclerView  —  это расширенная версия ListView, только более мощная и гибкая.

RecyclerView относится к семейству ViewGroup, которое является оптимизированным преемником ListView и GridView.

Как следует из названия, RecyclerView перезапускает верхние элементы списка, которые, уходя за пределы с экрана, становятся невидимыми для пользователя. Например, если пользователь прокрутит список вниз до пункта 6 или 7, то элементы в позиции 1, 2 или 3 будут удалены из памяти. В результате сокращается расход памяти.

Предварительные условия:

  • Базовые знания xml и kotlin;
  • Свободное обращение с классами и объектами;
  • Навыки использования ViewBinding.

Компоненты, необходимые для настройки RecyclerView:

  • Модель  —  для доступа к данным, которые должны быть показаны пользователю.
  • XML-шаблон — для отображения данных пользователю.
  • Adapter (Адаптер)  —  для привязки данных к RecyclerView.
  • ViewHolder — для получения ссылки на View-элементы, которые должны быть динамически изменены во время выполнения программы.

Пошаговое погружение в процесс написания кода

Создание нового проекта:

  • Перейдите в раздел File > New > New Project.
  • Выберите Empty Activity и нажмите кнопку Next.
  • Дайте проекту подходящее имя и введите имя пакета (или оставьте его по умолчанию).
  • Выберите Kotlin в качестве языка и минимальный SDK-пакет (получить помощь можно по ссылке Help me choose.
  • Нажмите кнопку Finish.
  • Дождитесь, когда появится главное окно Android Studio.

Создание Model

  • Создайте новый класс KotlinЩелкните правой кнопкой мыши на пакет в окне проекта.
    Выберите
    New>Kotlin Class/File.
    Выберите Data Class из параметров типа класс.
    Введите имя
    FoodItem и нажмите Enter.
  • Не беспокойтесь об ошибке в скобках класса данных.
  • Заполните поля (укажите наименование и цену продуктов) для своей модели.

Код для нашего класса моделей такой:

data class FoodItem(val name:String, val price:Float)

Создание XML-шаблона для элементов

  • Щелкните правой кнопкой мыши res/layout и выберите New>Layout Resource File.
  • Присвойте файлу имя food_item_layout и нажмите кнопку ОК.
  • Скопируйте и вставьте этот код в файл:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#0000FF"
android:layout_margin="6dp"
xmlns:app="http://schemas.android.com/apk/res-auto">

<TextView
android:id="@+id/foodItemNameTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="#FFF"
android:text="Food Item 1"
android:layout_margin="10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>

<TextView
android:id="@+id/foodItemPriceTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFF"
android:text="Rs. 200"
android:layout_marginEnd="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/foodItemNameTV"
app:layout_constraintBottom_toBottomOf="@id/foodItemNameTV"/>

</androidx.constraintlayout.widget.ConstraintLayout>

  • В activity_main.xml добавьте этот код, чтобы установить шаблон для RecyclerView в MainActivity:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/foodItemsRV"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Инициализация ViewBinding

  • Откройте файл уровня build.gradle.
  • В разделе android добавьте этот код:

buildFeatures{
viewBinding true
}

  • Нажмите Sync Now и дождитесь завершения процесса сборки.

Настройка Adapter для RecyclerView

Чтобы обеспечить привязку ваших данных к элементам списка, выполните следующие действия:

  • Сначала создайте новый класс Kotlin и назовите его FoodItemAdapter с параметрами Contextи MutableList<FoodItem>
  • Затем создайте внутренний класс FoodItemViewHolder— ViewHolder для RecyclerView.
  • Запишите код для внутреннего класса:

class FoodItemViewHolder(foodItemLayoutBinding: FoodItemLayoutBinding)
: RecyclerView.ViewHolder(foodItemLayoutBinding.root){

}

  • Расширьте FoodItemAdapterс помощью RecyclerView.Adapter<FoodItemAdapter.FoodItemViewHolder>()
  • Наведите курсор на ошибку в классе адаптера, нажмите Alt+Enter и выберите Implement members, чтобы реализовать элементы базового класса адаптера.
  • Когда откроется окно, выберите все элементы из списка и нажмите кнопку ОК.

Элемент-функции:

onCreateViewHolder() — метод для создания ViewHolder.

onBindViewHolder() — метод для привязки данных к элементам списка.

getItemCount() — метод для определения количества элементов, которые надо отобразить.

  • Добавьте этот код в onCreateViewHolder:

val binding = FoodItemLayoutBinding.inflate(LayoutInflater.from(context),parent,false)
return FoodItemViewHolder(binding)

  • Создайте функцию bind(foodItem: FoodItem) в FoodItemViewHolder и привяжите данные к элементам списка.
  • Вот код:

private val binding = foodItemLayoutBinding

fun bind(foodItem: FoodItem){
binding.foodItemNameTV.text = foodItem.name
binding.foodItemPriceTV.text = "Rs. ${foodItem.price}"
}

  • Теперь добавьте в элемент-функцию onBindViewHolder этот код:

val foodItem = foodItemList[position]
holder.bind(foodItem)

  • В getItemCount просто добавьте строку return foodItemList.size

Вот полный код для адаптера:

class FoodItemAdapter(private val context: Context, private val foodItemList:MutableList<FoodItem>)
: RecyclerView.Adapter<FoodItemAdapter.FoodItemViewHolder>() {


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FoodItemViewHolder {
val binding = FoodItemLayoutBinding.inflate(LayoutInflater.from(context),parent,false)
return FoodItemViewHolder(binding)
}

override fun onBindViewHolder(holder: FoodItemViewHolder, position: Int) {
val foodItem = foodItemList[position]
holder.bind(foodItem)
}

override fun getItemCount(): Int {
return foodItemList.size
}


class FoodItemViewHolder(foodItemLayoutBinding: FoodItemLayoutBinding)
: RecyclerView.ViewHolder(foodItemLayoutBinding.root){

private val binding = foodItemLayoutBinding

fun bind(foodItem: FoodItem){
binding.foodItemNameTV.text = foodItem.name
binding.foodItemPriceTV.text = "Rs. ${foodItem.price}"
}

}
}

Инициализация адаптера в классе MainActivity

1. Заполните список продуктов питания, которые будут отображаться в окне RecyclerView:

  • Создайте свойство foodItemsList как MutableList<FoodItem> и инициализируйте список.
  • Создайте функцию populateList() и вызовите ее в onCreate() класса activity после setContentView().
  • Добавьте в функцию этот код:

for (i in 1..15){
val name = "Food Item $i"
val price = (100 * i).toFloat()

val foodItem = FoodItem(name = name, price = price)

foodItemsList.add(foodItem)
}

2. Инициализируйте адаптер и менеджер разбивки:

  • Создайте свойство adapter как FoodItemAdapter и сделайте его lateinit.
  • Создайте функцию setUpAdapter() и вызовите ее после populateList().
  • Добавьте в эту функцию код:

adapter = FoodItemAdapter(this,foodItemsList)
b.foodItemsRV.adapter = adapter
b.foodItemsRV.layoutManager = LinearLayoutManager(this)

  • Поскольку размещение элементов в RecyclerView по умолчанию вертикальное, можете изменить его на горизонтальное с помощью опции:

b.foodItemsRV.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)

  • Если хотите добавить разделительную линию между view-элементами, воспользуйтесь опцией:

b.foodItemsRV.addItemDecoration(DividerItemDecoration(this,DividerItemDecoration.VERTICAL))

Совет: чтобы добавить, удалить или отредактировать элементы из данных, выполните следующие действия:

  • Сначала обновите foodItemsList, а затем уведомите адаптер об изменении, внесенном вами в список в определенной позиции.

Для удаления элемента:

В списке  —  foodItemList.removeAt(position)

Уведомление адаптеру  —  notifyItemRemoved(position)

Для добавления элемента:

В списке  —  foodItemList.add(position, foodItem)

Уведомление адаптеру  —  notifyItemInserted(position)

Для редактирования элемента:

В списке  —  сначала удалите элемент foodItemList.removeAt(position), затем добавьте новый элемент foodItemList.add(position,newFoodItem)

Уведомление адаптеру  —  notifyItemChanged(position)

Примечание: чтобы уведомить адаптер за пределами класса адаптера, используйте экземпляр адаптера  —  adapter.notifyItemInserted(position)

Пришло время запустить приложение. Не знаете, как запустить приложение? Посмотрите документацию.

Исходный код приложения доступен на github.

В RecyclerView есть гораздо больше возможностей, чем описано в этой статье. Но с помощью нашего краткого обзора вы сможете легко создать свой собственный пользовательский RecyclerView.

Читайте также:

Читайте нас в Telegram, VK

Перевод статьи Hrithik Sharma: Implement RecyclerView in android with kotlin