Моя проблема в том, что я не могу прокрутить вниз до последнего элемента. после отправки сообщения. Когда я пытаюсь использовать recyclerView.smoothScrollToPosition(lastPosition), список прокручивается до последнего элемента на странице Paging3.
Инициализация адаптера
Код: Выделить всё
linearLayoutManager.reverseLayout = true
binding.messageRecycler.layoutManager = linearLayoutManager
binding.messageRecycler.adapter = messagePagingAdapter
binding.layoutQuickMessages.visible = false
viewModel.readMessages(sessionId).observe(viewLifecycleOwner) { data ->
messagePagingAdapter.submitData(viewLifecycleOwner.lifecycle, data)
Код: Выделить всё
class MessageListPagingAdapter(
private val onRichMessageStart: (Message.ExerciseType) -> Unit,
) : PagingDataAdapter(MessageDiffUtilItemCallback()) {
private lateinit var mRecyclerView: RecyclerView
override fun onBindViewHolder(
holder: RecyclerView.ViewHolder,
position: Int,
) {
val item = getItem(position)
if (item != null) {
when (item.type) {
Message.Type.RICH -> {
if (holder is MessageListAdapter.RichMessageViewHolder) {
holder.bind(item)
}
}
Message.Type.RECEIVED -> {
if (holder is MessageListAdapter.ReceivedMessageViewHolder) {
holder.bind(item)
}
}
Message.Type.SENT -> {
if (holder is MessageListAdapter.SentMessageViewHolder) {
holder.bind(item)
}
}
}
}
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int,
): RecyclerView.ViewHolder =
when (viewType) {
Message.Type.RECEIVED.ordinal -> {
val binding =
ItemMessageReceivedBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false,
)
MessageListAdapter.ReceivedMessageViewHolder(binding)
}
Message.Type.SENT.ordinal -> {
val binding =
ItemMessageSentBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false,
)
MessageListAdapter.SentMessageViewHolder(binding)
}
Message.Type.RICH.ordinal -> {
val binding =
ItemRichMessageBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false,
)
MessageListAdapter.RichMessageViewHolder(binding, onRichMessageStart)
}
else -> {
val binding =
ItemMessageSentBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false,
)
MessageListAdapter.SentMessageViewHolder(binding)
}
}
override fun getItemViewType(position: Int): Int =
when (getItem(position)?.type) {
Message.Type.RECEIVED -> Message.Type.RECEIVED.ordinal
Message.Type.SENT -> Message.Type.SENT.ordinal
else -> Message.Type.RICH.ordinal
}
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
mRecyclerView = recyclerView
}
}
Код: Выделить всё
fun readMessages(sessionId: String): LiveData
> =
repository.readMessages(sessionId).asLiveData().cachedIn(viewModelScope)
Код: Выделить всё
fun readMessages(sessionId: String): Flow
> {
val pageConfig = PagingConfig(
pageSize = 20,
enablePlaceholders = false,
prefetchDistance = 10,
)
return Pager(
config = pageConfig,
pagingSourceFactory = { SelfTestHistoryPagingSource(sessionId, therapyDao) },
).flow.flowOn(Dispatchers.IO)
}
Код: Выделить всё
class SelfTestHistoryPagingSource(
private val sessionId: String,
private val dao: TherapyDao,
) : PagingSource() {
override suspend fun load(params: LoadParams): LoadResult {
val position = params.key ?: 0
return try {
val response = dao.readMessages(sessionId, 20, position * params.loadSize)
LoadResult.Page(
data = response,
prevKey = if (position == 0) null else position - 1,
nextKey = if (response.isEmpty()) null else position + 1,
)
} catch (e: Exception) {
LoadResult.Error(e)
}
}
override fun getRefreshKey(state: PagingState): Int? =
state.anchorPosition?.let { anchorPosition ->
val anchorPage = state.closestPageToPosition(anchorPosition)
anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1)
}
}
Подробнее здесь: https://stackoverflow.com/questions/786 ... in-paging3