androidandroid-jetpack-composeandroid-jetpack

How to dynamically change focus of children based on hover events?


I have this kind of requirement, not sure if jetpack compose supports this usecase or not. If there is a way to do this, appreciate your help:

Problem Definition In the following code snippet, TestScreen uses a custom layout, TestLayout, which kind of observes all the hover events, and determines which child element to get focus. The solution I am not able to come up with is, since TestLayout is generic, its content can be any complex Composable, so it should be able to dynamically parse though children and determine which are focusable and based on some logic (by observing hover events), it should determine which child item to get focus and set focus. e.g. child items can be buttons, text fields, or a list (LazyColumn) etc.

@Composable
fun TestScreen() {
    TestLayout {
        Column {
            Row() {
                TestButton(label = "test1")
                TestButton(label = "test2")
            }
            Row() {
                TestButton(label = "test3")
                TestButton(label = "test4")
            }
        }
    }
}

@Composable
fun TestLayout(content: @Composable () -> Unit) {
    
}

@Composable
fun TestButton(label: String) {

}

Solution

  • It looks like you need access to the child focusables.

    You could create custom modifiers using the Modifier.Node APIs and add them to each of the focusable children. If this custom modifier node implements the TraversalNode interface, the parent can search for these nodes in the sub-hierarchy. If this node also implements FocusRequesterModifierNode, the parent can call requestFocus() when it traverses to the node.

    Here is some more information to get you started using Modifier.Nodes.