【问题标题】:How can I show a composable on top of the visible Keyboard?如何在可见键盘上显示可组合项?
【发布时间】:2022-08-23 18:14:02
【问题描述】:

由于我们有不同的屏幕尺寸和分辨率,我想在展开的键盘上放置一个 Composable:

键盘(见上图)是可见的,我想在几秒钟内显示其他可组合(红色方块)之类的消息。

使用 Jetpack Compose 放置红色可组合物的简单方法是什么?

    标签: android-jetpack-compose android-jetpack


    【解决方案1】:

    这个问题可以使用WindowInsets.isImeVisible 来解决,但是要返回正确的值,您应该设置

        WindowCompat.setDecorFitsSystemWindows(window, false)
    

    我在setContent{}之前的活动中设置了这个

    使用WindowInsets.isImeVisible 检查键盘是否打开。

    我们需要在键盘打开时显示消息所以

    val offsetY = WindowInsets.ime.getBottom(density)
    var previousOffset by remember { mutableStateOf(0) }
    
    val isKeyboardGoingDown by remember(offsetY) {
        derivedStateOf {
            val isGoingDown = previousOffset - offsetY > 0
            previousOffset = offsetY
            isGoingDown
        }
    }
    

    用于通过 LaunchedEffect 跟踪键盘是向上还是向下

    LaunchedEffect(key1 = isImeVisible, key2 = isKeyboardGoingDown) {
    
        if (isImeVisible && !isKeyboardGoingDown) {
            showMessage = true
            delay(1000)
            showMessage = false
        } else {
            showMessage = false
    
        }
    }
    

    全面实施

    @OptIn(ExperimentalLayoutApi::class)
    @Composable
    private fun TimedMessageLayout() {
    
        val isImeVisible = WindowInsets.isImeVisible
        var showMessage by remember { mutableStateOf(false) }
        val density = LocalDensity.current
        val offsetY = WindowInsets.ime.getBottom(density)
        var previousOffset by remember { mutableStateOf(0) }
        
        val isKeyboardGoingDown by remember(offsetY) {
            derivedStateOf {
                val isGoingDown = previousOffset - offsetY > 0
                previousOffset = offsetY
                isGoingDown
            }
        }
    
        LaunchedEffect(key1 = isImeVisible, key2 = isKeyboardGoingDown) {
    
            if (isImeVisible && !isKeyboardGoingDown) {
                showMessage = true
                delay(1000)
                showMessage = false
            } else {
                showMessage = false
    
            }
        }
    
        Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.BottomStart) {
    
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(WindowInsets.systemBars.asPaddingValues())
                    .border(2.dp, Color.Green)
            ) {
                Image(
                    modifier = Modifier
                        .fillMaxWidth()
                        .aspectRatio(4 / 3f),
                    painter = painterResource(id = R.drawable.landscape1),
                    contentDescription = null
                )
    
                var text by remember { mutableStateOf("") }
    
                Text(
                    "Ime visible: ${WindowInsets.isImeVisible}, isKeyboardGoingDown: $isKeyboardGoingDown\n" +
                            "ime bottom: ${WindowInsets.ime.getBottom(density)}\n"
                )
                Spacer(modifier = Modifier.weight(1f))
                TextField(
                    value = text,
                    onValueChange = { text = it }
                )
            }
    
            if (showMessage && !isKeyboardGoingDown && offsetY != 0) {
                Box(modifier = Modifier
                    .offset {
                        IntOffset(0, -offsetY)
                    }
                    .fillMaxWidth()
                    .height(200.dp)
                    .border(3.dp, Color.Red))
            }
        }
    }
    

    结果

    【讨论】:

    • val offsetY = WindowInsets.ime.getTop(LocalDensity.current) 始终为 0
    • 我知道。但我找到了为什么它总是返回 0。我回答了here。我现在用正确的值检查你的问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    相关资源
    最近更新 更多