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

Android:滚动多行EditText时移除焦点的实现方案咨询

解决方案:多行EditText滚动时移除焦点

嘿,我来帮你搞定这个需求!要实现滚动多行EditText时自动移除焦点,核心思路就是监听EditText的滚动行为,一旦检测到滚动就触发焦点清除操作。下面给你两种实用的方案,你可以根据自己的场景选择:

方案一:利用ViewTreeObserver监听滚动变化

原生EditText没有直接暴露滚动监听,但我们可以通过ViewTreeObserver来捕获它的滚动状态变化。这种方案不需要修改自定义EditText的代码,快速上手:

Kotlin 代码示例

val mNoteEditText = findViewById<com.mnotes.view.TextField>(R.id.mNoteEditText)
mNoteEditText.viewTreeObserver.addOnScrollChangedListener {
    // 只有当EditText当前有焦点时,才执行移除操作
    if (mNoteEditText.hasFocus()) {
        mNoteEditText.clearFocus()
        // 可选:同时隐藏软键盘,提升用户体验
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(mNoteEditText.windowToken, 0)
    }
}

Java 代码示例

com.mnotes.view.TextField mNoteEditText = findViewById(R.id.mNoteEditText);
mNoteEditText.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
    @Override
    public void onScrollChanged() {
        if (mNoteEditText.hasFocus()) {
            mNoteEditText.clearFocus();
            // 可选:隐藏软键盘
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(mNoteEditText.getWindowToken(), 0);
        }
    }
});

方案二:自定义EditText重写滚动回调

如果方案一在快速滚动等场景下响应不够灵敏,你可以自定义一个继承自com.mnotes.view.TextField的EditText,直接重写滚动回调方法,逻辑更直接:

自定义EditText代码(Kotlin)

class ScrollAwareEditText @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.editTextStyle
) : com.mnotes.view.TextField(context, attrs, defStyleAttr) {

    override fun onScrollChanged(horizontalScroll: Int, verticalScroll: Int, oldHorizontalScroll: Int, oldVerticalScroll: Int) {
        super.onScrollChanged(horizontalScroll, verticalScroll, oldHorizontalScroll, oldVerticalScroll)
        // 只要滚动位置发生变化,且当前有焦点,就移除焦点
        if (hasFocus() && (horizontalScroll != oldHorizontalScroll || verticalScroll != oldVerticalScroll)) {
            clearFocus()
            // 可选:隐藏软键盘
            val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            imm.hideSoftInputFromWindow(windowToken, 0)
        }
    }
}

修改布局文件

把原来的com.mnotes.view.TextField替换成你自定义的EditText:

<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
    <com.yourpackage.ScrollAwareEditText 
        android:id="@+id/mNoteEditText" 
        android:layout_width="match_parent" 
        android:layout_height="match_parent" 
        android:background="@null" 
        android:gravity="top|start" 
        android:inputType="textMultiLine"/>
</LinearLayout>

注意事项

  • 加入hasFocus()判断是为了避免无意义的焦点移除操作,比如用户没在编辑时滚动EditText,不会触发不必要的状态变化。
  • 隐藏软键盘是可选操作,如果你希望用户滚动后仍保留键盘(只是失去焦点),可以去掉这部分代码。
  • 如果你的com.mnotes.view.TextField已经重写了onScrollChanged方法,一定要记得调用super.onScrollChanged(),保证原有滚动逻辑正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:53:39