如何在jetpack compose中聚焦(或选择)小部件时将其置于前面

Tan*_*Sir 3 android kotlin android-jetpack-compose

我有一个这样的页面:

在此输入图像描述

当一个框被聚焦时,它将被缩放。我用来Modifier.graphicsLayer()缩放它。

但缩放后的盒子会被其他盒子覆盖(box01被box02、box04和box 05覆盖)

在此输入图像描述

我真正需要的是:缩放后的​​盒子覆盖其他盒子,如下所示:

在此输入图像描述

我的示例代码:

@Composable
fun FocusBox(
    title:String,
    requester: FocusRequester = FocusRequester(),
    modifier: Modifier = Modifier
) {
    var boxColor by remember { mutableStateOf(Color.White) }
    var scale by remember { mutableStateOf(1f) }
    Box(
        Modifier
            .focusRequester(requester)
            .onFocusChanged {
                boxColor = if (it.isFocused) Color.Green else Color.Gray
                scale = if (it.isFocused) { 1.3f } else { 1f }
            }
            .focusable()
            .graphicsLayer(
                scaleX = scale,
                scaleY = scale
            ).background(boxColor)
    ) {
        Text(
            text = title,
            modifier = Modifier.padding(30.dp),
            color = Color.White,
            style = MaterialTheme.typography.subtitle2
        )
    }
}

@Composable
fun FocusScaleBoxDemo(){
    Row(modifier = Modifier.padding(30.dp)){
        Column{
            FocusBox(title = "Box_01")
            Spacer(modifier = Modifier.padding(5.dp))
            FocusBox(title = "Box_02")
            Spacer(modifier = Modifier.padding(5.dp))
            FocusBox(title = "Box_03")
            Spacer(modifier = Modifier.padding(5.dp))
        }
        Spacer(modifier = Modifier.padding(5.dp))
        Column{
            FocusBox(title = "Box_04")
            Spacer(modifier = Modifier.padding(5.dp))
            FocusBox(title = "Box_05")
            Spacer(modifier = Modifier.padding(5.dp))
            FocusBox(title = "Box_06")
            Spacer(modifier = Modifier.padding(5.dp))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Phi*_*hov 6

基本上你需要zIndex把视野带到邻居下面。但这一修饰符仅适用于一个容器。因此,如果您仅将其添加到选定的框中,则相邻列仍将位于其之上。您还需要将其添加到Column包含选定的框中。

我还美化了你的代码:尽量避免代码重复 - 你会减少错误的机会并提高修改速度

@Composable
fun FocusScaleBoxDemo() {
    val columnsCount = 2
    val rowsCount = 3
    var focusedColumnIndex by remember { mutableStateOf(0) }
    Row(
        horizontalArrangement = Arrangement.spacedBy(10.dp),
        modifier = Modifier.padding(30.dp)
    ) {
        for (column in 0 until columnsCount) {
            Column(
                verticalArrangement = Arrangement.spacedBy(10.dp),
                modifier = Modifier
                    .zIndex(if (column == focusedColumnIndex) 1f else 0f)
            ) {
                for (row in 0 until rowsCount) {
                    val boxIndex = column * rowsCount + row
                    FocusBox(
                        title = "Box_${boxIndex + 1}",
                        onFocused = {
                            focusedColumnIndex = column
                        },
                    )
                }
            }
        }
    }
}

@Composable
fun FocusBox(
    title: String,
    onFocused: () -> Unit,
    requester: FocusRequester = remember { FocusRequester() },
) {
    var isFocused by remember { mutableStateOf(false) }
    val scale = if (isFocused) 1.3f else 1f
    Box(
        Modifier
            .focusRequester(requester)
            .onFocusChanged {
                isFocused = it.isFocused
                if (isFocused) {
                    onFocused()
                }
            }
            .focusable()
            .graphicsLayer(
                scaleX = scale,
                scaleY = scale
            )
            .background(if (isFocused) Color.Green else Color.Gray)
            .zIndex(if (isFocused) 1f else 0f)
    ) {
        Text(
            text = title,
            modifier = Modifier.padding(30.dp),
            color = Color.White,
            style = MaterialTheme.typography.subtitle2
        )
    }
}
Run Code Online (Sandbox Code Playgroud)