Kotlin中Activity加载后自动选中RecyclerView首项的问题及解决
解决Activity启动时自动选中RecyclerView首项的问题
我太懂这种差一步就完成的纠结了——手动点FAB能顺利选中第一项,可启动时用代码自动触发就没反应,还找不到Activity里像FragmentonViewCreated()那样的合适时机,对吧?
其实核心原因是RecyclerView的布局渲染晚于Activity的生命周期方法,你在onCreate/onStart/onResume里直接调用选中逻辑时,RecyclerView可能还没把第一项的布局计算完成,自然不会生效。
你的延迟递归方案解析
你用Handler.postDelayed()结合isComputingLayout()检查的思路是完全可行的,既避开了布局未完成的阶段,还能在布局还在计算时重试。这里是你优化后的代码,我帮你格式化好了:
protected fun postAndNotifyAdapter(handler: Handler, recyclerView: RecyclerView) { trackLog(this, "postAndNotifyAdapter() ${State.selectedListItemUniqueId}") if (twoPane && State.selectedListItemUniqueId == null) { Handler().postDelayed({ if (!recyclerView.isComputingLayout) { trackLog(this, "postAndNotifyAdapter() !recyclerView.isComputingLayout ${State.selectedListItemUniqueId}") selectFirstOnList() } else { // 布局还在计算,递归调用重试 postAndNotifyAdapter(handler, recyclerView) } }, 1000) } }
更精准的替代方案(可选)
如果不想用硬编码的延迟时间,还有个更优雅的方式:监听RecyclerView的布局完成事件。这种方式会在布局真正完成后触发,不需要猜延迟时长:
recyclerView.addOnLayoutChangeListener(object : View.OnLayoutChangeListener { override fun onLayoutChange( v: View?, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int ) { // 只执行一次,记得移除监听器 recyclerView.removeOnLayoutChangeListener(this) if (twoPane && State.selectedListItemUniqueId == null) { selectFirstOnList() } } })
最后说两句
Activity的"完全加载"不是单一的生命周期事件,而是要等整个视图树的布局、测量都完成。你的思路本身没毛病,只是需要找对RecyclerView布局就绪的时机——不管是延迟重试还是布局监听器,都能解决问题,看你更偏向哪种风格啦。
内容的提问来源于stack exchange,提问作者JaymeisterJay
相关产品推荐
相关产品推荐

