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



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



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


Тогда 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.



632   0  

Comments

    Ничего не найдено.