为何RecyclerView的LinearLayoutManager.findFirstVisibleItemPosition()始终返回0?
解决RecyclerView的findFirstVisibleItemPosition()始终返回0的问题
我帮你梳理下这个问题的可能原因和对应的解决方案:
1. 显式初始化LinearLayoutManager
你的代码里没有主动给RecyclerView绑定LayoutManager,即便XML中配置了,也推荐在代码里显式初始化,这样能确保你后续调用方法时拿到的是正确的LinearLayoutManager实例,避免隐式初始化带来的异常:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val view= inflater.inflate(R.layout.fragment_contents, container, false) progressBar=view.findViewById<ProgressBar>(R.id.progressLine) recyclerView=view.findViewById<RecyclerView>(R.id.recyclerView) // 显式创建并绑定LinearLayoutManager val layoutManager = LinearLayoutManager(context) recyclerView.layoutManager = layoutManager recyclerView.setHasFixedSize(true) recyclerView.itemAnimator= DefaultItemAnimator() // 后续观察数据的代码保持不变 viewModel.findContentsByID(category_id).observe(this, Observer<List<ContentWithCategory>>{ arrayList=it adapter=ContentsAdapter(context!!,arrayList,this) recyclerView.adapter = adapter if(category_id != 0){ for(i in 0..arrayList.size-1){ val item = arrayList.get(i) if(item.id==last_content_id){ layoutManager.scrollToPositionWithOffset(i, 0) // 这里修正偏移量为0,确保滚动到item顶部 break } } } }) return view }
2. 不要在onDestroy()中获取可见项位置
onDestroy()是Fragment生命周期的最后阶段,此时RecyclerView已经从视图树中移除,视图状态已被销毁,调用findFirstVisibleItemPosition()根本拿不到真实的当前可见位置,大概率会返回默认值0。
你应该在更早的生命周期方法中保存位置,比如onStop()或onPause(),这时候RecyclerView的视图状态仍然有效:
override fun onStop() { super.onStop() val layoutManager = recyclerView.layoutManager as LinearLayoutManager val position = layoutManager.findFirstVisibleItemPosition() // 先判断位置是否有效,避免数组越界 if (position != RecyclerView.NO_POSITION && arrayList.isNotEmpty()) { val data = arrayList[position] last_content_id = data.id ViewModelProviders.of(this).get(CategoryViewModel::class.java).setHistory(data.id, data.category_id) } }
3. 修正滚动偏移参数
你之前用view.getTop()作为滚动偏移量,这里的view是Fragment的根视图,它的top值并不是你需要的item顶部偏移,改成0就能确保滚动到目标item的顶部,避免滚动位置异常影响后续的位置判断。
内容的提问来源于stack exchange,提问作者ABDUAHAD
相关产品推荐
相关产品推荐

