Search code examples
androidkotlinandroid-jetpack-composeandroid-tvandroid-jetpack-compose-tv

How to set default focus item in Android jetpack Compose


I have a screen with several focusable widgets for TV.

enter image description here Every time I have to click the direction key then Box01 get focused.

Does anyone know how to set Box01 focused by default? enter image description here

My Code:

@Composable
fun DefaultFocusSample(){
    Row(Modifier.padding(100.dp)) {
        FocusBox("Box01")
        Spacer(modifier = Modifier.padding(10.dp))
        FocusBox("Box02")
        Spacer(modifier = Modifier.padding(10.dp))
        FocusBox("Box03")
        Spacer(modifier = Modifier.padding(10.dp))
        FocusBox("Box04")
    }

}
@Composable
fun FocusBox(text:String){
    var color by remember { mutableStateOf(White) }
    Box(
        Modifier
            .onFocusChanged {
                color = if (it.isFocused) Green else White }
            .focusable()
            .border(2.dp,color)
    ){
        Text(text = text,
        modifier = Modifier.padding(10.dp))
    }
}

Solution

  • To manually bring focus to focusable, you can use FocusRequester, like this:

    @Composable
    fun FocusBox(text:String, requester: FocusRequester = FocusRequester()){
        var color by remember { mutableStateOf(Color.White) }
        Box(
            Modifier
                .focusRequester(requester)
                .onFocusChanged {
                    color = if (it.isFocused) Color.Green else Color.White
                }
                .focusable()
                .border(2.dp, color)
        ) {
            Text(text = text,
                modifier = Modifier.padding(10.dp))
        }
    }
    
    Row(
        Modifier
            .background(Color.Yellow)
            .padding(10.dp)
    ) {
        val requester = FocusRequester()
        FocusBox("Box01", requester)
        LaunchedEffect(Unit) {
            requester.requestFocus()
        }
        Spacer(modifier = Modifier.padding(10.dp))
        FocusBox("Box02")
        Spacer(modifier = Modifier.padding(10.dp))
        FocusBox("Box03")
        Spacer(modifier = Modifier.padding(10.dp))
        FocusBox("Box04")
    }
    

    LaunchedEffect is a side effect, it'll be run only once when composable appears. Check out more in the documentation