# How to handle focus in Jetpack Compose with examples

> This guide will show you how to handle text focus in Jetpack Compose. There are different APIs responsible for different functionalities around text focus: the FocusRequester, the FocusManager and the various focus related Modifiers. We'll cover all of them and how to utilize them in your Jetpack Compose applications.

Published 6 January 2023 by Alex Styl.

[![Featured in Android Weekly #552](https://androidweekly.net/issues/issue-552/badge)](https://androidweekly.net/issues/issue-552)

This guide will show you how to handle text focus in Jetpack Compose. There are different APIs responsible for different functionalities around text focus: the `FocusRequester`, the `FocusManager` and the various focus related `Modifier`s. We'll cover all of them and how to utilize them in your Jetpack Compose applications:

## How to request text focus

In order to request focus and make the soft keyboard to show, you need access to the `FocusRequester`:

```kotlin
Column {
    val focusRequester = remember { FocusRequester() }

    var value by remember { mutableStateOf("") }

    TextField(
        modifier = Modifier.focusRequester(focusRequester),
        value = value,
        onValueChange = {
            value = it
        }
    )

    Button(onClick = {
        focusRequester.requestFocus()
    }) {
        Text("Gain focus")
    }
}
```

note how the `FocusRequester` instance is passed to the `focusRequester()` modifier of the `TextField` and then is used when the `Button` is _clicked_. The `remember {}` is used so that we do not create a new `FocusRequester` on every composition.

## How to clear text focus

The `FocusManager` is the class which exposes APIs regarding controlling focus on the screen. Its `clearFocus()` function can be used to remove any focus like so:

```kotlin
val focusManager = LocalFocusManager.current
var value by remember { mutableStateOf("") }

TextField(
    value = value,
    onValueChange = {
        value = it
    }
)

LaunchedEffect(Unit) {
    while (true) {
        delay(2000)
        focusManager.clearFocus()
    }
}
```

in this example, the `FocusManager` will clear any focus from the screen every 2 seconds.

## How to pass focus to the next composable

The `FocusManager` can only pass focus from one composable to the next. More specifically using the `FocusManager.moveFocus()` function and passing the direction you need:

```kotlin
Column {
    val focusManager = LocalFocusManager.current
    var value by remember { mutableStateOf("") }

    TextField(
        value = value,
        onValueChange = {
            value = it
        },
        singleLine = true,
        keyboardActions = KeyboardActions {
            focusManager.moveFocus(FocusDirection.Next)
        },
    )
    TextField(
        value = value,
        onValueChange = {
            value = it
        },
        singleLine = true,
        keyboardActions = KeyboardActions {
            focusManager.clearFocus()
        },
    )
}
```

In the above example, pressing the soft keyboard's IME action while the first `TextField` is pressed will move focus to the next `TextField`. Doing the same while the second `TextField` is focused, the focus will be cleared.

Passing a different `FocusDirection` to the `moveFocus()` function allows you to move towards any direction you need (such as backwards or up and down).

## How to specify focus order

We saw how the `FocusRequester` is responsible for capturing focus and how you need to pass an instance of it to the composable's `Modifier`.

You can customize which composable's `FocusRequester` is next or previous by override its focusProperties using the `focusProperties()` modifier:

```kotlin
Row {
    val focusManager = LocalFocusManager.current
    Column {
        val (a, b, c) = FocusRequester.createRefs()
        TextField(
            modifier = Modifier
                .focusRequester(a)
                .focusProperties {
                    next = b
                },
            value = "",
            onValueChange = {},
        )
        TextField(
            modifier = Modifier
                .focusRequester(b)
                .focusProperties {
                    previous = a
                    next = c
                },
            value = "",
            onValueChange = {},
        )
        TextField(
            modifier = Modifier
                .focusRequester(c)
                .focusProperties {
                    previous = b
                },
            value = "",
            onValueChange = {},
        )
    }
    Column {
        Button(onClick = {
            focusManager.moveFocus(FocusDirection.Previous)
        }) {
            Text("Previous")
        }
        Button(onClick = {
            focusManager.moveFocus(FocusDirection.Next)
        }) {
            Text("Next")
        }
    }
}
```

The `FocusRequester.createRefs()` is a convinience function which creates multiple `FocusRequester`s instances which you can pass to multiple composables.

## How to listen to focus changed events

There is a `Modifier` for that. Use the `onFocusChanged { }` Modifier. It provides a callback every time the focus state changes.

That was everything you need to know about focus in Jetpack Compose. We saw the three different parts of the focus API: the `FocusRequester`, the `FocusManager` and the related focus `Modifier`s. Depending on your requirements you might want to use them in combination to achieve the result you need.
