Skip to content

ДЗ RecyclerView #2#57

Open
xeniamlkh wants to merge 6 commits intoAndroid-Developer-Basic:masterfrom
xeniamlkh:master
Open

ДЗ RecyclerView #2#57
xeniamlkh wants to merge 6 commits intoAndroid-Developer-Basic:masterfrom
xeniamlkh:master

Conversation

@xeniamlkh
Copy link

No description provided.

import androidx.recyclerview.widget.DiffUtil

class MessagesDiffCallback: DiffUtil.ItemCallback<Chat>() {
override fun areItemsTheSame(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нужно сравнивать по уникальному идентификатору (id), чтобы DiffUtil понимал, что это один и тот же элемент. А в areContentsTheSame сравнивайте все поля, чтобы понять, изменилось ли содержимое элемента.

Сейчас логика перепутана местами:
если два элемента с разными id имеют одинаковые поля, areItemsTheSame вернет false, и DiffUtil решит, что это разные элементы
если у элемента изменилось содержимое, но id тот же, areContentsTheSame вернет true, и DiffUtil не обновит ViewHolder

updateRecyclerView(messagesList)

val scrollListener = ScrollListener(layoutManager) {
loadMoreMessages()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onLoadFinished() вызывается сразу после создания listener, хотя загрузка еще не началась. Логичнее вызывать его после завершения загрузки данных в loadMoreMessages(), чтобы правильно управлять флагом isLoading


private fun updateRecyclerView(messagesList: List<Chat>) {
messagesAdapter.submitList(messagesList)
recycleView.adapter = messagesAdapter

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Адаптер нужно устанавливать один раз в onCreate(), а не при каждом обновлении списка. submitList() уже обновляет данные в адаптере, повторное присваивание не требуется

import androidx.recyclerview.widget.RecyclerView

class MessageViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
private val title: TextView by lazy { view.findViewById(R.id.title) }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lazy здесь не нужен. View уже создан в конструкторе, поэтому findViewById можно вызвать сразу. lazy добавляет лишние накладные расходы и вызывается при каждом обращении

val totalItemCount = layoutManager.itemCount
val lastVisibleItem = layoutManager.findLastVisibleItemPosition()

val isAtEnd = lastVisibleItem >= totalItemCount - 3

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Может срабатывать слишком рано. Обычно пагинацию запускают при достижении последнего видимого элемента, поэтому лучше использовать >= totalItemCount - 1

}

private fun loadMoreMessages() {
messagesList.addAll(messagesListDataSource)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Каждый раз добавляются все элементы из messagesListDataSource, что приводит к дублированию при повторных вызовах

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Сейчас в onCreate загружаются все 10 элементов сразу, а при пагинации добавляются те же элементы снова, что приводит к дублированию. Для правильной пагинации нужно загружать данные порциями: сначала загрузить часть данных (например, первые 5 элементов), а при достижении конца списка загружать следующие порции. Так каждый раз будут добавляться новые элементы, которые еще не были загружены.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants