You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

targetSdkVersion 30下RecyclerView adjustResize失效,EditText被IME遮挡

这是Android 11(API 30)调整了窗口Insets计算逻辑,和RecyclerView旧版本IME弹出适配逻辑缺陷共同导致的问题:当RecyclerView高度设为wrap_content且内容总高度超过屏幕高度时,adjustResize触发窗口高度变化后,RecyclerView不会主动调整滚动位置让获得焦点的EditText展示在IME上方,只有当内容完全可见时才会正常适配。

方案1:修改RecyclerView布局参数(最简单,优先使用)

把activity_main.xml中RecyclerView的layout_height属性从wrap_content改为match_parent即可解决绝大多数场景的问题,修改后的布局代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

原理:match_parent属性让RecyclerView的高度跟随父布局(也就是窗口可用高度)变化,adjustResize触发窗口高度缩减时,RecyclerView会同步重新测量自身高度,并且自动滚动到当前获得焦点的子控件位置。

方案2:升级RecyclerView依赖版本

如果方案1不符合业务需求(必须保留wrap_content属性),可以先尝试升级RecyclerView依赖到1.2.1及以上版本,该版本官方修复了多个API 30下的IME适配问题:

dependencies {
    implementation "androidx.recyclerview:recyclerview:1.3.2" // 替换为最新稳定版即可
}

方案3:手动监听IME变化滚动到目标位置

如果前两个方案都不适用,可以在Activity中手动监听窗口Insets变化,主动滚动RecyclerView到焦点EditText的位置,代码示例如下:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val myAdapter = MyAdapter()
        val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
        recyclerView.apply {
            adapter = myAdapter
            layoutManager = LinearLayoutManager(context)
        }

        // 监听窗口Insets变化处理IME弹出
        ViewCompat.setOnApplyWindowInsetsListener(window.decorView) { _, insets ->
            val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
            if (imeHeight > 0) { // IME弹出
                currentFocus?.let { focusView ->
                    if (focusView is AppCompatEditText) {
                        // 获取EditText对应的item位置
                        val itemPosition = recyclerView.getChildAdapterPosition(focusView.parent as View)
                        // 滚动到对应位置,可根据需求调整偏移量让EditText完全展示
                        (recyclerView.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(itemPosition, 0)
                    }
                }
            }
            insets
        }

        myAdapter.items.addAll(listOf(true, true, true))
        myAdapter.notifyDataSetChanged()
    }
}

使用该方案需要确保项目引入了core的兼容依赖,支持WindowInsetsCompat相关API。

内容的提问来源于stack exchange,提问作者sehee lee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 18:06:03