Compose Modifier

hierarchicalFocusGroup

hierarchicalFocusGroup is used to annotate composables in an application, so we can keep track of what is the active part of the composition.

HierarchicalFocusSample

@Sampled
@Composable
fun HierarchicalFocusSample() {
    var selected by remember { mutableIntStateOf(0) }

    Row(Modifier.fillMaxSize(), verticalAlignment = Alignment.CenterVertically) {
        repeat(5) { colIx ->
            Box(
                Modifier.hierarchicalFocusGroup(active = selected == colIx)
                    .weight(1f)
                    .clickable { selected = colIx }
                    .then(
                        if (selected == colIx) {
                            Modifier.border(BorderStroke(2.dp, Color.Red))
                        } else {
                            Modifier
                        }
                    )
            ) {
                // This is used to add a Gray background to the currently focused item, as seen by
                // the focus system.
                var focused by remember { mutableStateOf(false) }

                BasicText(
                    "$colIx",
                    style =
                        TextStyle(
                            color = Color.White,
                            fontSize = 20.sp,
                            textAlign = TextAlign.Center,
                        ),
                    modifier =
                        Modifier.fillMaxWidth()
                            .requestFocusOnHierarchyActive()
                            .onFocusChanged { focused = it.isFocused }
                            .focusable()
                            .then(
                                if (focused) {
                                    Modifier.background(Color.Gray)
                                } else {
                                    Modifier
                                }
                            ),
                )
            }
        }
    }
}

HierarchicalFocus2Levels

@Sampled
@Composable
fun HierarchicalFocus2Levels() {
    Column(Modifier.fillMaxSize()) {
        var selectedRow by remember { mutableIntStateOf(0) }
        repeat(2) { rowIx ->
            Row(
                Modifier.weight(1f)
                    .fillMaxWidth()
                    .hierarchicalFocusGroup(active = selectedRow == rowIx)
            ) {
                var selectedItem by remember { mutableIntStateOf(0) }
                repeat(2) { itemIx ->
                    Box(
                        Modifier.weight(1f).hierarchicalFocusGroup(active = selectedItem == itemIx)
                    ) {
                        // ScalingLazyColumn uses requestFocusOnHierarchyActive internally
                        ScalingLazyColumn(
                            Modifier.fillMaxWidth().clickable {
                                selectedRow = rowIx
                                selectedItem = itemIx
                            }
                        ) {
                            val prefix = (rowIx * 2 + itemIx + 'A'.code).toChar()
                            items(20) {
                                BasicText(
                                    "$prefix $it",
                                    style =
                                        TextStyle(
                                            color = Color.White,
                                            fontSize = 20.sp,
                                            textAlign = TextAlign.Center,
                                        ),
                                )
                            }
                        }
                    }
                }
            }
        }
    }
}
Jetpack Compose beyond MaterialFree components, screens and templates for apps that don’t look like Google’s. Copy them into your app, or let your coding agent add them.Browse for free

Content updated: