{% setvar book_path %}/reference/androidx/_book.yaml{% endsetvar %} {% include "_shared/_reference-head-tags.html" %}

FocusableKt

public final class FocusableKt


Summary

Public methods

static final @NonNull Modifier

Creates a focus group or marks this component as a focus group.

static final @NonNull Modifier
focusable(
    @NonNull Modifier receiver,
    boolean enabled,
    MutableInteractionSource interactionSource
)

Configure component to be focusable via focus system or accessibility "focus" event.

Public methods

focusGroup

@ExperimentalFoundationApi
public static final @NonNull Modifier focusGroup(@NonNull Modifier receiver)

Creates a focus group or marks this component as a focus group. This means that when we move focus using the keyboard or programmatically using FocusManager.moveFocus(), the items within the focus group will be given a higher priority before focus moves to items outside the focus group.

In the sample below, each column is a focus group, so pressing the tab key will move focus to all the buttons in column 1 before visiting column 2.

import androidx.compose.foundation.focusGroup
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.ui.Modifier

Row {
    Column(Modifier.focusGroup()) {
        Button({}) { Text("Row1 Col1") }
        Button({}) { Text("Row2 Col1") }
        Button({}) { Text("Row3 Col1") }
    }
    Column(Modifier.focusGroup()) {
        Button({}) { Text("Row1 Col2") }
        Button({}) { Text("Row2 Col2") }
        Button({}) { Text("Row3 Col2") }
    }
}

Note: The focusable children of a focusable parent automatically form a focus group. This modifier is to be used when you want to create a focus group where the parent is not focusable. If you encounter a component that uses a focusGroup internally, you can make it focusable by using a focusable modifier. In the second sample here, the LazyRow is a focus group that is not itself focusable. But you can make it focusable by adding a focusable modifier.

import androidx.compose.foundation.border
import androidx.compose.foundation.focusable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
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.graphics.Color.Companion.Black
import androidx.compose.ui.graphics.Color.Companion.Red
import androidx.compose.ui.unit.dp

val interactionSource = remember { MutableInteractionSource() }
LazyRow(
    Modifier
        .focusable(interactionSource = interactionSource)
        .border(1.dp, if (interactionSource.collectIsFocusedAsState().value) Red else Black)
) {
    repeat(10) {
        item {
            Button({}) { Text("Button$it") }
        }
    }
}

focusable

public static final @NonNull Modifier focusable(
    @NonNull Modifier receiver,
    boolean enabled,
    MutableInteractionSource interactionSource
)

Configure component to be focusable via focus system or accessibility "focus" event.

Add this modifier to the element to make it focusable within its bounds.

import androidx.compose.foundation.focusable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.layout.Column
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

// initialize focus reference to be able to request focus programmatically
val focusRequester = remember { FocusRequester() }
// MutableInteractionSource to track changes of the component's interactions (like "focused")
val interactionSource = remember { MutableInteractionSource() }

// text below will change when we focus it via button click
val isFocused = interactionSource.collectIsFocusedAsState().value
val text = if (isFocused) {
    "Focused! tap anywhere to free the focus"
} else {
    "Bring focus to me by tapping the button below!"
}
Column {
    // this Text will change it's text parameter depending on the presence of a focus
    Text(
        text = text,
        modifier = Modifier
            // add focusRequester modifier before the focusable (or even in the parent)
            .focusRequester(focusRequester)
            .focusable(interactionSource = interactionSource)
    )
    Button(onClick = { focusRequester.requestFocus() }) {
        Text("Bring focus to the text above")
    }
}
Parameters
boolean enabled

Controls the enabled state. When false, element won't participate in the focus

MutableInteractionSource interactionSource

MutableInteractionSource that will be used to emit FocusInteraction.Focus when this element is being focused.