Kotlin如何实现ScrollView内EditText仅在获焦时可滚动
实现方案
核心是通过触摸事件分发逻辑控制事件消费方,不需要修改外层ScrollView的代码,自定义EditText即可实现需求。
逻辑规则
- EditText未获取焦点时,所有触摸事件不做拦截,直接交由外层ScrollView消费,此时触摸EditText区域可以正常滚动外层容器
- EditText获取焦点后,主动请求父容器禁止拦截触摸事件,保证自身内部的垂直滚动、文本选择、光标定位等操作正常响应
代码实现
- 自定义支持滚动逻辑判断的EditText
class SmartScrollEditText @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.editTextStyle ) : AppCompatEditText(context, attrs, defStyleAttr) { override fun onTouchEvent(e: MotionEvent): Boolean { // 未聚焦状态下不消费事件,抛给父容器处理 if (!isFocused) return false // 聚焦状态下阻断父容器的事件拦截,保障自身滚动生效 when (e.actionMasked) { MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> { parent?.requestDisallowInterceptTouchEvent(true) } MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { parent?.requestDisallowInterceptTouchEvent(false) } } return super.onTouchEvent(e) } }
- 布局中替换原生EditText使用,注意配置多行属性和固定高度
<ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!-- 其余页面内容 --> <com.your.packagename.SmartScrollEditText android:layout_width="match_parent" android:layout_height="220dp" android:padding="12dp" android:gravity="top|start" android:scrollbars="vertical" android:inputType="textMultiLine" android:hint="请输入多行内容"/> <!-- 其余页面内容 --> </LinearLayout> </ScrollView>
补充配置
如果需要实现「点击EditText外部区域自动失去焦点」的交互,给外层ScrollView加如下配置即可:
// 配置ScrollView可获取焦点 scrollView.apply { isFocusable = true isFocusableInTouchMode = true setOnClickListener { currentFocus?.clearFocus() } }
注意:必须给EditText设置明确的固定高度/最大高度,同时配置
textMultiLine属性,否则EditText会自动撑开适配所有文本高度,自身不会产生滚动效果。
内容的提问来源于stack exchange,提问作者ivan14
相关产品推荐
相关产品推荐

