背景
项目中需要监听输入框(也就是TextField组件)的粘贴事件,Compose的TextField
不像android.view的EditText
中一样,重写onTextContextMenuItem
方法就可以做到监听,Compose中而是使用改变provider来实现。
实现
1. 获取本地TextToolbar
kotlin
val defaultTextToolbar = LocalTextToolbar.current
2. 重写TextToolbar
kotlin
val pasteListeningTextToolbar = remember{
object : TextToolbar {
override fun hide() {
defaultTextToolbar.hide()
}
override val status: TextToolbarStatus
get() = defaultTextToolbar.status
override fun showMenu(
rect: Rect,
onCopyRequested: (() -> Unit)?,
onPasteRequested: (() -> Unit)?,
onCutRequested: (() -> Unit)?,
onSelectAllRequested: (() -> Unit)?
) {
val wrappedPasteCallback = {
onPasteRequested?.invoke()
println("paste event happen")
}
defaultTextToolbar.showMenu(
rect,
onCopyRequested,
wrappedPasteCallback,
onCutRequested,
onSelectAllRequested,
)
}
}
}
关键点
只拦截粘贴事件,其他保持不变
kotlin
val wrappedPasteCallback = {
onPasteRequested?.invoke() // 保持原始粘帖功能
// 添加自定义逻辑,也可以加自定义的callback,我这里直接输入
println("paste event happen")
}
其后,再把其他功能回调原封不动的传递给默认TextToolbar
kotlin
defaultTextToolbar.showMenu(
rect,
onCopyRequested, // 原始复制功能
wrappedPasteCallback, // 包装后的粘贴
onCutRequested, // 原始剪切功能
onSelectAllRequested // 原始全选功能
)
3. 替换默认的TextToolbar
替换原有的TextToolbar,为自定义的TextToolbar
kotlin
CompositionLocalProvider(LocalTextToolbar providers pasteListeningTextToolbar){
TextField(
value = text,
onValueChange = { text = id },
)
}
完整Composeable代码
kotlin
@Composable
fun TextFieldWithPasteCallback(
) {
var text by remember { mutableStateOf("") }
var state = rememberTextFieldState()
var defaultTextToolbar = LocalTextToolbar.current
var pasteListeningToolbar = remember {
object : TextToolbar {
override fun hide() {
defaultTextToolbar.hide()
}
override val status: TextToolbarStatus
get() = defaultTextToolbar.status
override fun showMenu(
rect: Rect,
onCopyRequested: (() -> Unit)?,
onPasteRequested: (() -> Unit)?,
onCutRequested: (() -> Unit)?,
onSelectAllRequested: (() -> Unit)?
) {
val wrappedPasteCallback = {
onPasteRequested?.invoke()
println("paste event happen")
}
defaultTextToolbar.showMenu(
rect,
onCopyRequested,
wrappedPasteCallback,
onCutRequested,
onSelectAllRequested,
)
}
}
}
CompositionLocalProvider(LocalTextToolbar provides pasteListeningToolbar) {
TextField(
placeholder = {
Text("input placeholder")
},
value = text,
onValueChange = {
println("text:$it")
text = it
}
)
}
}