---
title: "hierarchicalFocusGroup"
description: "[hierarchicalFocusGroup] is used to annotate composables in an application, so we can keep track
of what is the active part of the composition. In turn, this is used to coordinate focus in a
declarative way, requesting focus when needed, as the user navigates through the app (such as
between screens or between pages within a screen). In most cases, this is automatically handled
by Wear Compose components and no action is necessary. In particular this is done by
[BasicSwipeToDismissBox], [HorizontalPager], [VerticalPager] and PickerGroup. This modifier is
useful if you implement a custom component that needs to direct focus to one of several children,
like a custom Pager, a Tabbed layout, etc.

[hierarchicalFocusGroup]s can be nested to form a focus tree, with an implicit root. For sibling
[hierarchicalFocusGroup]s, only one should have active = true. Within the focus tree, components
that need to request focus can do so using [Modifier.requestFocusOnHierarchyActive]. Note that
ScalingLazyColumn and TransformingLazyColumn are using it already, so there is no need to add it
explicitly.

When focus changes, the focus tree is examined and the topmost (closest to the root of the tree)
[requestFocusOnHierarchyActive] which has all its [hierarchicalFocusGroup] ancestors with active
= true will request focus. If no such [requestFocusOnHierarchyActive] exists, the focus will be
cleared.

NOTE: This shouldn't be used together with [FocusRequester.requestFocus] calls in
[LaunchedEffect].




Sample using nested [hierarchicalFocusGroup]:"
type: "modifier"
---

<div class='type'>Compose Modifier</div>

<a id='references'></a>
<div class='sourceset sourceset-android'>Android</div>


```kotlin
public fun Modifier.hierarchicalFocusGroup(active: Boolean): Modifier
```


`hierarchicalFocusGroup` is used to annotate composables in an application, so we can keep track
of what is the active part of the composition. In turn, this is used to coordinate focus in a
declarative way, requesting focus when needed, as the user navigates through the app (such as
between screens or between pages within a screen). In most cases, this is automatically handled
by Wear Compose components and no action is necessary. In particular this is done by
`BasicSwipeToDismissBox`, `HorizontalPager`, `VerticalPager` and PickerGroup. This modifier is
useful if you implement a custom component that needs to direct focus to one of several children,
like a custom Pager, a Tabbed layout, etc.

`hierarchicalFocusGroup`s can be nested to form a focus tree, with an implicit root. For sibling
`hierarchicalFocusGroup`s, only one should have active = true. Within the focus tree, components
that need to request focus can do so using `Modifier.requestFocusOnHierarchyActive`. Note that
ScalingLazyColumn and TransformingLazyColumn are using it already, so there is no need to add it
explicitly.

When focus changes, the focus tree is examined and the topmost (closest to the root of the tree)
`requestFocusOnHierarchyActive` which has all its `hierarchicalFocusGroup` ancestors with active
= true will request focus. If no such `requestFocusOnHierarchyActive` exists, the focus will be
cleared.

NOTE: This shouldn't be used together with `FocusRequester.requestFocus` calls in
`LaunchedEffect`.




Sample using nested `hierarchicalFocusGroup`:

#### Parameters

| | |
| --- | --- |
| active | Pass true when this sub tree of the focus tree is active and may require the focus - otherwise, pass false. For example, a pager can apply this modifier to each page's content with a call to `hierarchicalFocusGroup`, marking only the current page as active. |




## Code Examples
### HierarchicalFocus2Levels
```kotlin
@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,
                                        ),
                                )
                            }
                        }
                    }
                }
            }
        }
    }
}
```
### HierarchicalFocusSample
```kotlin
@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 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
                                }
                            ),
                )
            }
        }
    }
}
```

