使用导航组件保存 RecyclerView 的滚动
Posted
技术标签:
【中文标题】使用导航组件保存 RecyclerView 的滚动【英文标题】:Saving scroll of RecyclerView with navigation component 【发布时间】:2020-04-13 11:28:03 【问题描述】:我在我的应用程序中使用带有 BottomNavigationView 的导航组件。它在 4 个目的地之间切换,其中一个包含一个带有 RecyclerView 的片段,其中包含数百个项目。当我使用后退按钮时,RecyclerView 会恢复到之前的滚动位置。但是当我使用 BottomNavigationView 在目的地之间切换时,它不会恢复到以前的位置并重置到 RecyclerView 的顶部。这是我试图阻止的代码
override fun onPause()
super.onPause()
lastScrollPos = linearLayoutManager.findFirstVisibleItemPosition()
override fun onResume()
super.onResume()
card_recyclerView.layoutManager?.scrollToPosition(lastScrollPos)
这行不通 将 RecyclerView 恢复到正确位置的最佳方法是什么?
【问题讨论】:
【参考方案1】:它不滚动到上一个位置的原因是navController
在与bottomNavigation
一起使用时重新创建了片段(使用替换)。
保存滚动状态的一种简单方法是将layoutManager
状态存储在onDestroyView
中并将其恢复到onCreateView
,与scrollToPosition 不同,此方法将滚动到确切位置,当NavController 重新创建片段。
我在另一个线程https://***.com/a/66940957/2102794发布了完整代码
【讨论】:
【参考方案2】:这可以通过将ScrollView
的Y 轴位置保存在成员变量中并在onCreateView()
中恢复来完成。这是有效的,因为成员变量没有被破坏。
class DiscoverDataFragment : BaseFragment()
private var loaded = false
private var scrollPos = 0
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
return inflater.inflate(R.layout.fragment_discover_data, container, false)
override fun onCreateBind()
super.onCreateBind()
if (!loaded)
// Load views here
loaded = true
if (scrollPos > 0)
scrollDiscoverData.scrollY = scrollPos
setScrollListener()
private fun setScrollListener()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
scrollDiscoverData.setOnScrollChangeListener v, scrollX, scrollY, oldScrollX, oldScrollY ->
scrollPos = scrollY
【讨论】:
【参考方案3】:你必须在片段生命周期之外初始化适配器,例如
class MyFragment : Fragment()
private val myViewModel by viewModel<MyViewModel>()
private lateinit var myAdapter : MyAdapter
override fun onActivityCreated(savedInstanceState: Bundle?)
super.onActivityCreated(savedInstanceState)
myAdapter = MyAdapter()
Log.d("checkListData", myAdapter.currentList.toString())
myViewModel.someListData.observe(viewLifecycleOwner) listData ->
myAdapter.submitList(listData)
【讨论】:
哦,普通人。先学android框架。这是一种反模式,因为它是一个很大的内存泄漏。以上是关于使用导航组件保存 RecyclerView 的滚动的主要内容,如果未能解决你的问题,请参考以下文章
Android10.5 滚动视图(RecyclerView)
Android下拉刷新滚动到底部自动加载更多RecyclerView组件