scrollToPosition () при обновлении RecyclerView во фрагменте - PullRequest
1 голос
/ 30 мая 2020

Я составил список, который получает элементы из базы данных комнат, используя LiveData. Затем этот liveData<List> привязывается к recyclerView, используя BindingAdapter. Адаптер списков - listAdapter, а не `RecyclerView.Adapter.

Мне нужна помощь, удерживая состояние прокрутки или каким-то образом возвращаясь к индексу прокрутки, в котором я был до перезагрузки recyclerView:

//In ViewModel
    val movieList = moviesRepository.movies

..

//in Repo
  val movies: LiveData<List<Movie>> =
    Transformations.map(database.movieDao.getMovies()) {
        it.asDomainModel()
    }

Каждый раз, когда БД обновляется, recyclerView возвращается наверх.

А вот bindingAdapter для RecyclerView и списка.

@BindingAdapter("listData")
fun bindRecyclerView(recyclerView: RecyclerView, data: List<Movie>?) {
    val adapter = recyclerView.adapter as MovieListAdapter
    //Log.d("listData binding", "${data}")
    adapter.submitList(data)
}

Думаю, мне нужно использовать что-то вроде recyclerView.smoothScrollToPosition(la.getItemCount()); после обновления произошло, но я не знаю, как автоматически вызвать его при обновлении

Project Repo

Ответы [ 2 ]

1 голос
/ 01 июня 2020
  1. Прежде всего не используйте ListAdapter RecyclerView имеет более оптимизированный адаптер здесь

  2. в вашем адаптере предоставьте функция, которая отменяет список элементов , и здесь вы уведомляете об изменении данных

  3. Используйте smoothScrollToPosition(lastVisiblePosition) для прокрутки до последней видимой позиции, где lastVisiblePosition = layoutManager.findFirstVisibleItemPosition()

  4. Обновление lastVisiblePosition перед поставкой sh новых элементов в адаптер notifyDatasetChanged()

Шаг 2

fun updateList(newItems:List<Movie>) {
    moviesList.addAll(newItems)
    lastVisiblePosition = layoutManager.findFirstVisibleItemPosition()
    notifyDataSetChanged()
}

с вашего взгляда, когда вы звоните adapter.updateList(newItems) просто звоните recyclerView.smoothScrollToPosition(adapter.lastVisiblePosition)

0 голосов
/ 04 июня 2020

разобрался. Все примеры, которые я смог найти, использовали Activity, а не фрагменты. Итак, все, что мне нужно было сделать, это вставить это в функцию onCreateView () в соответствующем файле fragment.kt.

    binding.movieList.layoutManager =
        object : LinearLayoutManager(getActivity(), VERTICAL, false) {
            override fun onLayoutCompleted(state: RecyclerView.State) {
                super.onLayoutCompleted(state)
                val lastVisibleItemPosition = findLastVisibleItemPosition()
                val count = (binding.movieList.adapter as MovieListAdapter).itemCount

                    //speed the scroll up a bit, but make it look smooth at the end
                    binding.movieList.scrollToPosition(count - 5)
                    binding.movieList.smoothScrollToPosition(count)

            }
        }

здесь binding.movieList относится к этому xml элементу

 <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/movie_list"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintBottom_toTopOf="@+id/load_more_button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:listData="@{viewModel.movieList}"
        tools:listitem="@layout/movie_list_item" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...