繁体   English   中英

使用 Jetpack Compose 构建软件键盘 - 使用 Jetpack Compose 的 IME 输入法

[英]Build Software Keyboard with Jetpack Compose - IME Input Method with Jetpack Compose

在 Jetpack Compose 中构建一个简单的键盘相当简单明了。 我使用这个构建了一个非常简单的 KeyRow:

密钥.kt

@Composable
fun Key(modifier: Modifier = Modifier, label: String, onClick: () -> Unit) {
    val shape = RoundedCornerShape(4.dp)
    //TODO: make clickable outside but don't show ripple
    Box(modifier = modifier
            .padding(2.dp)
            .clip(shape)
            .clickable(onClick = onClick)
            .background(Color.White)
            .padding(vertical = 12.dp, horizontal = 4.dp), contentAlignment = Alignment.Center) {
        Text(text = label, fontSize = 20.sp)
    }
}

密钥行.kt

@Composable
fun KeyRow(keys: List<String>) {
    Row(modifier = Modifier.fillMaxWidth().background(color = grey200)) {
        keys.forEach {
            Key(modifier = Modifier.weight(1f), label = it, onClick = {  })
        }
    }
}

这就是它的样子:

2

我想实现这个 animation:

3

但是,我目前坚持这个

![4]

层次结构

-Keyboard
--KeyRow
---KeyLayout
----Key
----KeyPressedOverlay (only visible when pressed)

我的主要问题是我不知道如何在不使父 Layout 更大的情况下显示 KeyPressedOverlay Composale(大于 Key Composable)。 结果,我需要以某种方式溢出父布局。

我猜你正在寻找pressIndicatorGestureFilter修饰符......我试过这个并为我工作......

var pressed by remember { mutableStateOf(false) }
val padding = if (pressed) 32.dp else 16.dp
Text("A", Modifier
    .pressIndicatorGestureFilter(
        onStart = {
            pressed = true
        },
        onStop = {
            pressed = false
        },
        onCancel = {
            pressed = false
        }
    )
    .background(Color.White)
    .padding(start = 16.dp, end = 16.dp, top = padding, bottom = padding)
)

不确定这是否是最好的方法(可能不是),但我找到了使用ConstraintLayout的解决方案......

val keys = listOf("A", "B", "C", "D")
ConstraintLayout(
    modifier = Modifier.graphicsLayer(clip = false)
) {
    val refs = keys.map { createRef() }
    refs.forEachIndexed { index, ref ->
        val modifier = when (index) {
            0 -> Modifier.constrainAs(ref) {
                start.linkTo(parent.start)
            }
            refs.lastIndex -> Modifier.constrainAs(ref) {
                start.linkTo(refs[index - 1].end)
                end.linkTo(parent.end)
            }
            else -> Modifier.constrainAs(ref) {
                start.linkTo(refs[index - 1].end)
                end.linkTo(refs[index + 1].start)
            }
        }
        val modifierPressed = Modifier.constrainAs(createRef()) {
            start.linkTo(ref.start)
            end.linkTo(ref.end)
            bottom.linkTo(ref.bottom)
        }
        KeyboardKey(
            keyboardKey = keys[index],
            modifier = modifier,
            modifierPressed = modifierPressed
        )
    }
}

这里的一个重要细节是graphicLayer(clip = false) (类似于View Toolkit 中的clipChildren )。 然后,我为每个键和按下的键创建一个修饰符。 请注意, modifierPressed与另一个修改器的中心/底部对齐。 最后, KeyboardKey在下面描述。

@Composable
fun KeyboardKey(
    keyboardKey: String,
    modifier: Modifier,
    modifierPressed: Modifier
) {
    var pressed by remember { mutableStateOf(false) }
    Text(keyboardKey, Modifier
        .then(modifier)
        .pressIndicatorGestureFilter(
            onStart = { pressed = true },
            onStop = { pressed = false },
            onCancel = { pressed = false }
        )
        .background(Color.White)
        .padding(16.dp)
    )
    if (pressed) {
        Text(
            keyboardKey, Modifier
                .then(modifierPressed)
                .background(Color.White)
                .padding(
                    start = 16.dp, 
                    end = 16.dp, 
                    top = 16.dp, 
                    bottom = 48.dp
                )
        )
    }
}

这是我得到的结果: 键盘效果

编辑:添加更多逻辑,我能够得到这个...... 在此处输入图像描述

我希望这次能有所帮助;)这里的要点是为了以防万一...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM