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

EditText嵌套TextInputLayout在API25报错:getTextBeforeCursor异常

TextInputLayout嵌套EditText在API 25上焦点丢失并报InputConnection错误

问题现象

  • 在API 28及上下2个版本(API 26-30)中运行正常
  • 在API 25版本中,EditText会突然失去焦点,焦点切换至android.viewpager2.widget.ViewPager2$RecyclerViewImpl{738f416 VFED..... .F...... 0,0-1028,846 #1}
  • 同时Logcat输出以下警告日志:
W/IInputConnectionWrapper: getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper: getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
W/IInputConnectionWrapper: getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper: getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper: finishComposingText on inactive InputConnection

可能的解决方案

1. 阻止ViewPager2的RecyclerView自动获取焦点

在ViewPager2的布局中添加android:descendantFocusability="blocksDescendants"属性,阻止内部RecyclerView自动抢夺焦点:

<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/viewPager2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:descendantFocusability="blocksDescendants" />

或者直接在RecyclerView布局中禁用焦点获取:

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusable="false"
    android:focusableInTouchMode="false" />

2. 自定义EditText修复InputConnection兼容性问题

API 25的输入法框架对InputConnection管理存在兼容缺陷,自定义EditText重写onCreateInputConnection方法,确保连接状态判断逻辑正确:

class FixedEditText @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.editTextStyle
) : androidx.appcompat.widget.AppCompatEditText(context, attrs, defStyleAttr) {

    override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? {
        val inputConnection = super.onCreateInputConnection(outAttrs)
        return inputConnection?.let { ActiveInputConnectionWrapper(it, this) }
    }

    private class ActiveInputConnectionWrapper(
        target: InputConnection,
        private val editText: EditText
    ) : InputConnectionWrapper(target, true) {

        override fun finishComposingText(): Boolean {
            return if (editText.isInputMethodTarget) super.finishComposingText() else false
        }

        override fun getTextBeforeCursor(length: Int, flags: Int): CharSequence? {
            return if (editText.isInputMethodTarget) super.getTextBeforeCursor(length, flags) else ""
        }
    }
}

布局中替换为该自定义EditText:

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/textInputLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <your.package.name.FixedEditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入内容" />

</com.google.android.material.textfield.TextInputLayout>

3. 手动控制EditText焦点

监听EditText焦点变化,强制保持焦点并唤起输入法:

editText.setOnFocusChangeListener { v, hasFocus ->
    if (hasFocus) {
        v.post {
            v.requestFocus()
            val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            imm.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT)
        }
    }
}

同时在页面生命周期中补充焦点恢复逻辑:

override fun onWindowFocusChanged(hasFocus: Boolean) {
    super.onWindowFocusChanged(hasFocus)
    if (hasFocus && editText != null && !editText.hasFocus()) {
        editText.requestFocus()
    }
}

4. 调整TextInputLayout焦点属性

确保TextInputLayout和EditText都配置正确的焦点属性:

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/textInputLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:focusable="true"
    android:focusableInTouchMode="true">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:hint="输入内容" />

</com.google.android.material.textfield.TextInputLayout>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:10:43