RecyclerView中EditText设置InputType后获焦滚动至顶部问题求助
解决RecyclerView中EditText设置InputType后获焦滚动到位置0的问题
我刚好遇到过这个问题,折腾了一会儿找到了解决方案!原因在于当你给EditText设置InputType后,系统在它获取焦点时会自动尝试将其滚动到可视区域,但RecyclerView的布局管理器在这里出现了误判,直接跳转到了列表的第0项。下面分享几个有效的解决办法:
方法一:自定义LinearLayoutManager(适配线性布局场景)
如果你的RecyclerView用的是LinearLayoutManager,可以自定义一个子类,重写滚动相关方法来避免强制跳转:
class CustomLinearLayoutManager(context: Context) : LinearLayoutManager(context) { private var allowScroll = true override fun scrollToPositionWithOffset(position: Int, offset: Int) { // 仅在主动触发滚动时执行默认逻辑,拦截EditText获焦带来的意外滚动 if (allowScroll) { super.scrollToPositionWithOffset(position, offset) } allowScroll = true } // 提供开关控制滚动权限 fun setAllowScroll(enabled: Boolean) { allowScroll = enabled } }
接着在Adapter中给EditText添加焦点监听,获焦时暂时禁用滚动:
et_name.setOnFocusChangeListener { _, hasFocus -> val layoutManager = recyclerView.layoutManager as? CustomLinearLayoutManager layoutManager?.setAllowScroll(!hasFocus) }
方法二:禁用EditText的自动滚动行为
直接通过属性阻止系统强制滚动EditText到可视区域,在XML中添加:
android:imeOptions="flagNoExtractUi" android:importantForAutofill="no"
或者在代码中设置:
et_name.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI et_name.importantForAutofill = View.IMPORTANT_FOR_AUTOFILL_NO
这个属性会让EditText获焦时保持在原有位置,不会触发RecyclerView的异常滚动。
方法三:调整RecyclerView的焦点优先级
给RecyclerView添加以下属性,让它优先获取焦点,避免EditText获焦时触发的滚动逻辑:
android:focusable="true" android:focusableInTouchMode="true"
代码中也可以直接设置:
recyclerView.isFocusable = true recyclerView.isFocusableInTouchMode = true
另外还要排查下Adapter代码,有没有在EditText获焦时意外调用了notifyDataSetChanged()或者scrollToPosition(0),这些操作也会导致列表跳转到头部哦!
内容的提问来源于stack exchange,提问作者SAurabh
相关产品推荐
相关产品推荐

