Search code examples
androidkotlinandroid-jetpack-composeaccessibilityfocus

In Jetpack Compose, how can you check to see if a screen has re-composed?


I want to be able to set accessibility focus on a Text object, but only once it becomes visible (through mutable state boolean that is remembered). This means that the screen needs to finish re-composing before we can do anything else to it.

I've set up my code as follows:

    var isVisible by remember { mutableStateOf(false) }
    var focusRequester = remember { FocusRequester() }
    if (isVisible) {
        Text(text = "Text", modifier = Modifier
            .focusRequester(focusRequester)
            .focusable())
        focusRequester.requestFocus()
    }
    
    Button(onClick = { isVisible = true  }) {
        Text(text = "Make text appear and focused")
    }

This fails when we reach focusRequester.requestFocus() because the Text object isn't yet visible on the screen yet.

Is there a way to check if the screen has re-composed? So that I can do something like this:

    if (isVisible) {
        Text(text = "Text", modifier = Modifier
            .focusRequester(focusRequester)
            .focusable())
        if (isRecomposed) {
             focusRequester.requestFocus()
        }
    }

Solution

  • You can use LaunchedEffect which triggers its block when your Compoable enters composition.

    @Preview
    @Composable
    private fun RecompositionSample() {
    
        var isVisible by remember { mutableStateOf(false) }
        val focusRequester = remember { FocusRequester() }
    
        Column {
            if (isVisible) {
                Text(
                    text = "Text",
                    modifier = Modifier
                        .focusRequester(focusRequester)
                        .focusable(true)
                )
    
                LaunchedEffect(Unit) {
                    awaitFrame()
                    focusRequester.requestFocus()
                }
            }
    
            Button(onClick = { isVisible = true }) {
                Text(text = "Make text appear and focused")
            }
        }
    }