Hoinzey

Javascript. Kotlin. Android. Java

Jetpack Compose: Focus manager

Focus manager allows us to focus/traverse input fields in a linear or non-linear way when pressing the "next" button on the device's keyboard.


Jamie Sanson wrote a good post on it here which covers some additional features. I found that late into writing my example code and was too lazy to modify what I'd planned to write.


You can find my full example code here.

Focus modifiers

You can define a custom focus requester as seen below with secondNameFocusRequester. The focus requester is passed in the modifier to the field which will be focused - in this case the field for second name. Then in the keyboard actions of the TextField we trigger the call when the user presses the next button.


                    
                    
    @Composable
    fun FormContent(modifier: Modifier) {
        val secondNameFocusRequester = remember { FocusRequester() }

        //First name
        FormTextField(..
            onNextClicked = {secondNameFocusRequester.requestFocus()})

        //Second name
        FormTextField(..
            modifier = Modifier.focusRequester(secondNameFocusRequester))
    }
                        
                        
    @Composable
    fun FormTextField(
        modifier: Modifier
        onNextClicked: () -> Unit) {
        TextField(..
            keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
            keyboardActions = KeyboardActions(onNext = {onNextClicked()})
        )
    }
                

Focus manager

Alternatively you can get a reference of the current focus manager and make use of the methods on that. In the below examples you can see it used to move Down to the next item in the list, and also clearFocus which is going to hide the keyboard for us. Useful to help bring a form button into view for example.


                    
                    
    @Composable
    fun FormContent(modifier: Modifier) {
        val focusManager = LocalFocusManager.current

        //Address 1
        FormTextField(
            modifier = Modifier.focusRequester(address1FocusRequester),
            value = "",
            label = "Address 1",
            onNextClicked = {focusManager.moveFocus(FocusDirection.Down)})

            //Address 2
        FormTextField(
            modifier = Modifier.focusRequester(address2FocusRequester),
            value = "",
            label = "Address 2",
            onNextClicked = {focusManager.clearFocus()})
    }
                

Focus on entry to screen

To focus on a field when you enter the screen, you can use a focus modifier along with a LaunchedEffect to bring attention to the first form field straight away.


                    
                    
    @Composable
    fun FormContent(modifier: Modifier) {

        val firstNameFocusRequester = remember { FocusRequester() }

        val focusManager = LocalFocusManager.current

        //First name
        FormTextField(
            modifier = Modifier.focusRequester(firstNameFocusRequester),
            ..)

        LaunchedEffect(Unit) {
            firstNameFocusRequester.requestFocus()
        }
    }