androidx.compose.ui.focus

Interfaces

FocusEnterExitScope

Receiver scope for FocusProperties.onEnter and FocusProperties.onExit.

Cmn
FocusEventModifier

This interface is deprecated. Use FocusEventModifierNode instead

Cmn
FocusEventModifierNode

Implement this interface create a modifier node that can be used to observe focus state changes to a FocusTargetNode down the hierarchy.

Cmn
FocusManager
Cmn
FocusOrderModifier

This interface is deprecated. Use Modifier.focusProperties() instead

Cmn
FocusProperties

Properties that are applied to focusTarget that is the first child of the FocusPropertiesModifierNode that sets these properties.

Cmn
FocusPropertiesModifierNode

Implement this interface create a modifier node that can be used to modify the focus properties of the associated FocusTargetNode.

Cmn
FocusRequesterModifier

This interface is deprecated. Use FocusRequesterModifierNode instead

Cmn
FocusRequesterModifierNode

Implement this interface to create a modifier node that can be used to request changes in the focus state of a FocusTargetNode down the hierarchy.

Cmn
FocusState

The focus state of a FocusTargetNode.

Cmn
FocusTargetModifierNode

This modifier node can be delegated to in order to create a modifier that makes a component focusable.

Cmn

Classes

FocusDirection

The FocusDirection is used to specify the direction for a FocusManager.moveFocus request.

Cmn
FocusOrder

This class is deprecated. Use FocusProperties instead

Cmn
FocusRequester

The FocusRequester is used in conjunction with Modifier.focusRequester to send requests to change focus.

Cmn
Focusability

Focusability configures whether a focus target can be focused.

Cmn

Objects

FocusRequester.Companion
Cmn
FocusRequester.Companion.FocusRequesterFactory

Convenient way to create multiple FocusRequester instances.

Cmn

Top-level functions summary

FocusTargetModifierNode
FocusTargetModifierNode(
    focusability: Focusability,
    onFocusChange: ((previous: FocusState, current: FocusState) -> Unit)?
)

Create a FocusTargetModifierNode that can be delegated to in order to create a modifier that makes a component focusable.

Cmn

Extension functions summary

Boolean

Deny requests to clear focus.

Cmn
Modifier

This function is deprecated. Replaced by focusTarget

Cmn
Modifier
Modifier.focusOrder(focusOrderReceiver: FocusOrder.() -> Unit)

This function is deprecated. Use focusProperties() instead

Cmn
Modifier

This function is deprecated. Use focusRequester() instead

Cmn
Modifier
Modifier.focusOrder(
    focusRequester: FocusRequester,
    focusOrderReceiver: FocusOrder.() -> Unit
)

This function is deprecated. Use focusProperties() and focusRequester() instead

Cmn
Modifier

This modifier allows you to specify properties that are accessible to focusTargets further down the modifier chain or on child layout nodes.

Cmn
Modifier

Add this modifier to a component to request changes to focus.

Cmn
Modifier

This modifier can be used to save and restore focus to a focus group.

Cmn
Modifier

This function is deprecated. Use focusRestorer(FocusRequester) instead

Cmn
Modifier

Add this modifier to a component to make it focusable.

Cmn
Boolean

Use this function to send a request to free focus when one of the components associated with this FocusRequester is in a Captured state.

Cmn
Unit
Cmn
Modifier
Modifier.onFocusChanged(onFocusChanged: (FocusState) -> Unit)

Add this modifier to a component to observe focus state events.

Cmn
Modifier
Modifier.onFocusEvent(onFocusEvent: (FocusState) -> Unit)

Add this modifier to a component to observe focus state events.

Cmn
Boolean

Use this function to request focus.

Cmn
Boolean

Use this function to restore focus to one of the children of the node pointed to by this FocusRequester.

Cmn
Boolean

Use this function to request the focus target to save a reference to the currently focused child in its saved instance state.

Cmn

Top-level functions

FocusTargetModifierNode

fun FocusTargetModifierNode(
    focusability: Focusability = Focusability.Always,
    onFocusChange: ((previous: FocusState, current: FocusState) -> Unit)? = null
): FocusTargetModifierNode

Create a FocusTargetModifierNode that can be delegated to in order to create a modifier that makes a component focusable. Use a different instance of FocusTargetModifierNode for each focusable component.

Parameters
focusability: Focusability = Focusability.Always

the Focusability that configures focusability for this node

onFocusChange: ((previous: FocusState, current: FocusState) -> Unit)? = null

a callback invoked when the FocusTargetModifierNode.focusState changes, providing the previous state that it changed from, and the current focus state. Note that this will be invoked if the node is losing focus due to being detached from the hierarchy, but before the node is marked as detached (node.isAttached will still be true).

Extension functions

captureFocus

fun FocusRequesterModifierNode.captureFocus(): Boolean

Deny requests to clear focus.

Use this function to send a request to capture focus. If a component captures focus, it will send a FocusState object to its associated onFocusChanged modifiers where FocusState.isCaptured == true.

When a component is in a Captured state, all focus requests from other components are declined.

import androidx.compose.foundation.border
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color.Companion.Red
import androidx.compose.ui.graphics.Color.Companion.Transparent
import androidx.compose.ui.unit.dp

val focusRequester = remember { FocusRequester() }
var value by remember { mutableStateOf("apple") }
var borderColor by remember { mutableStateOf(Transparent) }
TextField(
    value = value,
    onValueChange = {
        value =
            it.apply {
                if (length > 5) focusRequester.captureFocus() else focusRequester.freeFocus()
            }
    },
    modifier =
        Modifier.border(2.dp, borderColor).focusRequester(focusRequester).onFocusChanged {
            borderColor = if (it.isCaptured) Red else Transparent
        }
)
Returns
Boolean

true if the focus was successfully captured by one of the focus modifiers associated with this FocusRequester. False otherwise.

focusModifier

fun Modifier.focusModifier(): Modifier

Add this modifier to a component to make it focusable.

focusOrder

fun Modifier.focusOrder(focusOrderReceiver: FocusOrder.() -> Unit): Modifier

Use this modifier to specify a custom focus traversal order.

import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester

Column(Modifier.fillMaxSize(), Arrangement.SpaceEvenly) {
    val (item1, item2, item3, item4) = remember { FocusRequester.createRefs() }
    Row(Modifier.fillMaxWidth(), Arrangement.SpaceEvenly) {
        Box(
            Modifier.focusRequester(item1)
                .focusProperties {
                    next = item2
                    right = item2
                    down = item3
                    previous = item4
                }
                .focusable()
        )
        Box(
            Modifier.focusRequester(item2)
                .focusProperties {
                    next = item3
                    right = item1
                    down = item4
                    previous = item1
                }
                .focusable()
        )
    }
    Row(Modifier.fillMaxWidth(), Arrangement.SpaceEvenly) {
        Box(
            Modifier.focusRequester(item3).focusProperties {
                next = item4
                right = item4
                up = item1
                previous = item2
            }
        )
        Box(
            Modifier.focusRequester(item4).focusProperties {
                next = item1
                left = item3
                up = item2
                previous = item3
            }
        )
    }
}
Parameters
focusOrderReceiver: FocusOrder.() -> Unit

Specifies FocusRequesters that are used when the user wants to move the current focus to the next item, or wants to move focus left, right, up or down.

focusOrder

fun Modifier.focusOrder(focusRequester: FocusRequester): Modifier

A modifier that lets you specify a FocusRequester for the current composable so that this focusRequester can be used by another composable to specify a custom focus order.

import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester

Column(Modifier.fillMaxSize(), Arrangement.SpaceEvenly) {
    val (item1, item2, item3, item4) = remember { FocusRequester.createRefs() }
    Row(Modifier.fillMaxWidth(), Arrangement.SpaceEvenly) {
        Box(
            Modifier.focusRequester(item1)
                .focusProperties {
                    next = item2
                    right = item2
                    down = item3
                    previous = item4
                }
                .focusable()
        )
        Box(
            Modifier.focusRequester(item2)
                .focusProperties {
                    next = item3
                    right = item1
                    down = item4
                    previous = item1
                }
                .focusable()
        )
    }
    Row(Modifier.fillMaxWidth(), Arrangement.SpaceEvenly) {
        Box(
            Modifier.focusRequester(item3).focusProperties {
                next = item4
                right = item4
                up = item1
                previous = item2
            }
        )
        Box(
            Modifier.focusRequester(item4).focusProperties {
                next = item1
                left = item3
                up = item2
                previous = item3
            }
        )
    }
}

focusOrder

fun Modifier.focusOrder(
    focusRequester: FocusRequester,
    focusOrderReceiver: FocusOrder.() -> Unit
): Modifier

A modifier that lets you specify a FocusRequester for the current composable along with focusOrder.

focusProperties

fun Modifier.focusProperties(scope: FocusProperties.() -> Unit): Modifier

This modifier allows you to specify properties that are accessible to focusTargets further down the modifier chain or on child layout nodes.

import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusTarget
import androidx.compose.ui.input.InputMode.Companion.Touch
import androidx.compose.ui.platform.LocalInputModeManager

Column {
    // Always focusable.
    Box(modifier = Modifier.focusProperties { canFocus = true }.focusTarget())
    // Only focusable in non-touch mode.
    val inputModeManager = LocalInputModeManager.current
    Box(
        modifier =
            Modifier.focusProperties { canFocus = inputModeManager.inputMode != Touch }
                .focusTarget()
    )
}

focusRequester

fun Modifier.focusRequester(focusRequester: FocusRequester): Modifier

Add this modifier to a component to request changes to focus.

import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color.Companion.Black
import androidx.compose.ui.graphics.Color.Companion.Green
import androidx.compose.ui.unit.dp

val focusRequester = remember { FocusRequester() }
var color by remember { mutableStateOf(Black) }
Box(
    Modifier.clickable { focusRequester.requestFocus() }
        .border(2.dp, color)
        // The focusRequester should be added BEFORE the focusable.
        .focusRequester(focusRequester)
        // The onFocusChanged should be added BEFORE the focusable that is being observed.
        .onFocusChanged { color = if (it.isFocused) Green else Black }
        .focusable()
)

focusRestorer

fun Modifier.focusRestorer(fallback: FocusRequester = Default): Modifier

This modifier can be used to save and restore focus to a focus group. When focus leaves the focus group, it stores a reference to the item that was previously focused. Then when focus re-enters this focus group, it restores focus to the previously focused item.

import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.focusRestorer

LazyRow(Modifier.focusRestorer()) {
    item { Button(onClick = {}) { Text("1") } }
    item { Button(onClick = {}) { Text("2") } }
    item { Button(onClick = {}) { Text("3") } }
    item { Button(onClick = {}) { Text("4") } }
}
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.focusRestorer

val focusRequester = remember { FocusRequester() }
LazyRow(
    // If restoration fails, focus would fallback to the item associated with focusRequester.
    Modifier.focusRestorer(focusRequester)
) {
    item {
        Button(modifier = Modifier.focusRequester(focusRequester), onClick = {}) { Text("1") }
    }
    item { Button(onClick = {}) { Text("2") } }
    item { Button(onClick = {}) { Text("3") } }
    item { Button(onClick = {}) { Text("4") } }
}
Parameters
fallback: FocusRequester = Default

A FocusRequester that is used when focus restoration fails to restore the initially focused item. For example, this might happen if the item is not available to be focused. The default value of FocusRequester.Default chooses the default focusable item.

focusRestorer

@ExperimentalComposeUiApi
fun Modifier.focusRestorer(onRestoreFailed: (() -> FocusRequester)?): Modifier

Deprecated focusRestorer API. Use the version accepting FocusRequester instead of the lambda. This method will be removed soon after submitting.

focusTarget

fun Modifier.focusTarget(): Modifier

Add this modifier to a component to make it focusable.

Focus state is stored within this modifier. The bounds of this modifier reflect the bounds of the focus box.

Note: This is a low level modifier. Before using this consider using Modifier.focusable(). It uses a focusTarget in its implementation. Modifier.focusable() adds semantics that are needed for accessibility.

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.focusTarget
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color.Companion.Black
import androidx.compose.ui.graphics.Color.Companion.Green
import androidx.compose.ui.unit.dp

var color by remember { mutableStateOf(Black) }
Box(
    Modifier.border(2.dp, color)
        // The onFocusChanged should be added BEFORE the focusTarget that is being observed.
        .onFocusChanged { color = if (it.isFocused) Green else Black }
        .focusTarget()
)

freeFocus

fun FocusRequesterModifierNode.freeFocus(): Boolean

Use this function to send a request to free focus when one of the components associated with this FocusRequester is in a Captured state. If a component frees focus, it will send a FocusState object to its associated onFocusChanged modifiers where FocusState.isCaptured == false.

When a component is in a Captured state, all focus requests from other components are declined. .

import androidx.compose.foundation.border
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color.Companion.Red
import androidx.compose.ui.graphics.Color.Companion.Transparent
import androidx.compose.ui.unit.dp

val focusRequester = remember { FocusRequester() }
var value by remember { mutableStateOf("apple") }
var borderColor by remember { mutableStateOf(Transparent) }
TextField(
    value = value,
    onValueChange = {
        value =
            it.apply {
                if (length > 5) focusRequester.captureFocus() else focusRequester.freeFocus()
            }
    },
    modifier =
        Modifier.border(2.dp, borderColor).focusRequester(focusRequester).onFocusChanged {
            borderColor = if (it.isCaptured) Red else Transparent
        }
)
Returns
Boolean

true if the captured focus was successfully released. i.e. At the end of this operation, one of the components associated with this focusRequester freed focus.

invalidateFocusProperties

fun FocusPropertiesModifierNode.invalidateFocusProperties(): Unit

onFocusChanged

fun Modifier.onFocusChanged(onFocusChanged: (FocusState) -> Unit): Modifier

Add this modifier to a component to observe focus state events. onFocusChanged is invoked when the focus state changes. The onFocusChanged modifier listens to the state of the first focusTarget following this modifier.

import androidx.compose.foundation.border
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color.Companion.Black
import androidx.compose.ui.graphics.Color.Companion.Green
import androidx.compose.ui.unit.dp

var color by remember { mutableStateOf(Black) }
Box(
    Modifier.border(2.dp, color)
        // The onFocusChanged should be added BEFORE the focusable that is being observed.
        .onFocusChanged { color = if (it.isFocused) Green else Black }
        .focusable()
)

Note: If you want to be notified every time the internal focus state is written to (even if it hasn't changed), use onFocusEvent instead.

onFocusEvent

fun Modifier.onFocusEvent(onFocusEvent: (FocusState) -> Unit): Modifier

Add this modifier to a component to observe focus state events.

requestFocus

fun FocusRequesterModifierNode.requestFocus(): Boolean

Use this function to request focus. If the system grants focus to a component associated with this FocusRequester, its onFocusChanged modifiers will receive a FocusState object where FocusState.isFocused is true.

import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color.Companion.Black
import androidx.compose.ui.graphics.Color.Companion.Green
import androidx.compose.ui.unit.dp

val focusRequester = remember { FocusRequester() }
var color by remember { mutableStateOf(Black) }
Box(
    Modifier.clickable { focusRequester.requestFocus() }
        .border(2.dp, color)
        // The focusRequester should be added BEFORE the focusable.
        .focusRequester(focusRequester)
        // The onFocusChanged should be added BEFORE the focusable that is being observed.
        .onFocusChanged { color = if (it.isFocused) Green else Black }
        .focusable()
)

restoreFocusedChild

fun FocusRequesterModifierNode.restoreFocusedChild(): Boolean

Use this function to restore focus to one of the children of the node pointed to by this FocusRequester. This restores focus to a previously focused child that was saved by using saveFocusedChild.

Returns
Boolean

true if we successfully restored focus to one of the children of the focusTarget associated with this node.

saveFocusedChild

fun FocusRequesterModifierNode.saveFocusedChild(): Boolean

Use this function to request the focus target to save a reference to the currently focused child in its saved instance state. After calling this, focus can be restored to the saved child by making a call to restoreFocusedChild.

Returns
Boolean

true if the focus target associated with this node has a focused child and we successfully saved a reference to it.