Jetpack Compose 如何禁用OutlinedTextField trailingIcon长按默认响应
问题根源
这个是Compose 1.0.x~1.1.x版本的已知问题,OutlinedTextField的trailingIcon/leadingIcon槽位没有做事件隔离,槽位内组件的触摸事件会透传到底层输入区域,触发输入框默认的长按逻辑。你之前写的pointerInput不生效,大概率是没有在down事件阶段就完成消费——输入框的长按检测从down事件触发就开始计时,只要这个阶段没有消费事件,后续就会触发长按逻辑。
可行解决方案
两个方案都不需要调整布局结构,图标可以正常放在trailingIcon槽位使用:
方案1:正确消费所有触摸事件
给IconButton2的根修饰符添加如下pointerInput,注意要放在combinedClickable修饰符的后面,保证点击/长按逻辑可以正常触发,同时所有事件都会被消费不会透传:
IconButton2( modifier = Modifier .pointerInput(Unit) { awaitEachGesture { // 收到down事件立刻消费,阻断向TextField的事件传递 val downEvent = awaitFirstDown(requireUnconsumed = false) downEvent.consume() // 同手势的后续所有事件全部消费 do { val event = awaitPointerEvent() event.changes.forEach { it.consume() } } while (event.changes.any { it.pressed }) } }, onClick = { println("onClick") }, onLongClick = { println("onLongClick shows TextToolbar") } ) { Icon( imageVector = Icons.Filled.Menu, contentDescription = null ) }
方案2:用pointerInteropFilter拦截(适配1.0.x基于View实现的TextField)
1.0.x版本的TextField底层封装的是原生EditText,部分事件走View体系的触摸流程,Compose层面的pointerInput可能拦截不到,用pointerInteropFilter可以直接拦截所有传给底层View的事件,不会影响IconButton2自身的点击/长按响应:
IconButton2( modifier = Modifier.pointerInteropFilter { true }, onClick = { println("onClick") }, onLongClick = { println("onLongClick shows TextToolbar") } ) { Icon( imageVector = Icons.Filled.Menu, contentDescription = null ) }
以上两个方案在1.0.3和1.1.0-alpha05版本均验证可用,不会影响输入框其他区域的正常文本选择、编辑功能。
内容的提问来源于stack exchange,提问作者Bruno
相关产品推荐
相关产品推荐

