如何在没有 TextField 的情况下监听 Jetpack Compose 中的键盘事件?

blu*_*oid 3 android android-jetpack-compose

我正在做一个我不能使用的文本输入TextField。我需要 不支持的文本转换TextField

如何获取软件/屏幕键盘事件?

Modifier.onKeyEvent()不适合我,因为由于某种原因它只适用于硬件键盘。

这应该很容易,对吧?我还没有找到解决办法。

ngl*_*ber 5

我找到了一种方法......也许不是最优雅的,但它有效......

首先,在您的活动中,捕获关键事件并通过广播发送。

override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
    LocalBroadcastManager.getInstance(this).sendBroadcast(
        Intent("key_up").apply {
            putExtra("event", event)
        }
    )
    return super.onKeyUp(keyCode, event)
}
Run Code Online (Sandbox Code Playgroud)

然后声明下面的函数(无论您想要在哪里)。它负责打开键盘。

suspend fun openKeyboard(context: Context) {
    val myView = (context as Activity).findViewById<View>(android.R.id.content)
    val inputMethodManager = 
        context.getSystemService(INPUT_METHOD_SERVICE) as? InputMethodManager
    delay(500) // it didn't work without the delay...
    inputMethodManager?.toggleSoftInputFromWindow(
        myView.applicationWindowToken,
        InputMethodManager.SHOW_FORCED,
        0
    )
}
Run Code Online (Sandbox Code Playgroud)

最后,这是可组合的。

@ExperimentalComposeUiApi
@Composable
fun FakeInput() {
    var keyCode by remember { // last key pressed
        mutableStateOf("")
    }
    val ctx = LocalContext.current
    LaunchedEffect(Unit) {
        openKeyboard(ctx)
    }
    DisposableEffect(Unit) {
        val lbm = LocalBroadcastManager.getInstance(ctx)
        // Receiver for key events 
        val receiver = object : BroadcastReceiver() {
            override fun onReceive(ctx: Context?, intent: Intent?) {
                intent?.getParcelableExtra<KeyEvent>("event")?.let { keyEvent ->
                    keyCode = keyEvent.displayLabel.toString()
                }
            }
        }
        // registering the receiver
        lbm.registerReceiver(receiver, IntentFilter("key_up"))
        onDispose {
            // unregistering when the composable is disposed
            lbm.unregisterReceiver(receiver)
        }
    }
    Box(Modifier.fillMaxSize()) {
        Text(text = keyCode, Modifier.align(Alignment.Center))
    }
}
Run Code Online (Sandbox Code Playgroud)

结果如下:

在此输入图像描述