在片段中更新 RecyclerView 时的 scrollToPosition()
scrollToPosition() when updating RecyclerView in a fragment
我制作了一个列表,它使用 LiveData
从房间数据库中获取项目。这个 liveData<List>
然后使用 BindingAdapter
绑定到 recyclerView
。
列表适配器是 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
都会回到顶部。
这里是 RecyclerView
和列表的 bindingAdapter
。
@BindingAdapter("listData")
fun bindRecyclerView(recyclerView: RecyclerView, data: List<Movie>?) {
val adapter = recyclerView.adapter as MovieListAdapter
//Log.d("listData binding", "${data}")
adapter.submitList(data)
}
我想我需要使用类似 的东西
更新发生后,不知道如何在更新发生时自动调用
首先不要使用ListAdapter
RecyclerView
有更优化的适配器here
在您的适配器中提供覆盖项目列表的功能并且您可以在其中通知数据更改
使用smoothScrollToPosition(lastVisiblePosition)
滚动到lastVisiblePosition = layoutManager.findFirstVisibleItemPosition()
的最后一个可见位置
在将新项目推送到适配器之前更新 lastVisiblePosition
notifyDatasetChanged()
步骤 2
fun updateList(newItems:List<Movie>) {
moviesList.addAll(newItems)
lastVisiblePosition = layoutManager.findFirstVisibleItemPosition()
notifyDataSetChanged()
}
从您的角度来看,当您调用 adapter.updateList(newItems)
时,只需调用 recyclerView.smoothScrollToPosition(adapter.lastVisiblePosition)
明白了。
我能找到的所有示例都使用活动,而不是片段。所以我所要做的就是将其弹出到相关 fragment.kt 文件中的 onCreateView() 函数中。
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" />
我制作了一个列表,它使用 LiveData
从房间数据库中获取项目。这个 liveData<List>
然后使用 BindingAdapter
绑定到 recyclerView
。
列表适配器是 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
都会回到顶部。
这里是 RecyclerView
和列表的 bindingAdapter
。
@BindingAdapter("listData")
fun bindRecyclerView(recyclerView: RecyclerView, data: List<Movie>?) {
val adapter = recyclerView.adapter as MovieListAdapter
//Log.d("listData binding", "${data}")
adapter.submitList(data)
}
我想我需要使用类似
首先不要使用
ListAdapter
RecyclerView
有更优化的适配器here在您的适配器中提供覆盖项目列表的功能并且您可以在其中通知数据更改
使用
smoothScrollToPosition(lastVisiblePosition)
滚动到lastVisiblePosition = layoutManager.findFirstVisibleItemPosition()
的最后一个可见位置
在将新项目推送到适配器之前更新
lastVisiblePosition
notifyDatasetChanged()
步骤 2
fun updateList(newItems:List<Movie>) {
moviesList.addAll(newItems)
lastVisiblePosition = layoutManager.findFirstVisibleItemPosition()
notifyDataSetChanged()
}
从您的角度来看,当您调用 adapter.updateList(newItems)
时,只需调用 recyclerView.smoothScrollToPosition(adapter.lastVisiblePosition)
明白了。 我能找到的所有示例都使用活动,而不是片段。所以我所要做的就是将其弹出到相关 fragment.kt 文件中的 onCreateView() 函数中。
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" />