Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move focus from one component to another in Jetpack compose?

I am trying to move the focus from one component to another on a button click. I have this code right now.

    ...
            Column(
            modifier = Modifier
                .fillMaxSize()
                .statusBarsPadding()
                .navigationBarsPadding()
                .background(surfaceColors.surface)
        ) {
            TopBar(
                TopBarState(
                    endText = if (theViewPages[state.currentPageIndex].isShowSkip) stringResource(id = R.string.Skip) else null,
                    onEndTextPressed = { store.dispatch(TheViewAction.OnSkip) },
                    isBackButtonVisible = false
                ) //need to focus on this component when user clicks on button
            )
    
            Column(
                horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.Center,
                modifier = Modifier
                    .fillMaxHeight()
            ) {
                HorizontalPager(
                    HorizontalPagerState(
                        modifier = Modifier
                            .aspectRatio(1f / 1.5f),
                        count = theViewPages.size,
                        onPageChange = { store.dispatch(TheViewAction.OnPageChange(it)) },
                        manuallyScrollPage = state.manuallyScrollPage,
                        content = { currentPage ->
                            TheItemView(
                                item = TheViewItemModel(
                                    theViewPages[currentPage].isShowSkip,
                                    theViewPages[currentPage].title,
                                    theViewPages[currentPage].image,
                                    theViewPages[currentPage].description,
                                    theViewPages[currentPage].buttonText
                                ),
                                onButtonClick = {
                                    if (state.currentPageIndex != theViewPages.size - 1) {
                                        //when user clicks this button focus moves to above component
store.dispatch(TheViewAction.ManuallyScrollPage)
                                    } else {
                                        store.dispatch(TheViewAction.OnGettingStarted)
                                    }
                                }
                            )
                        }
                    )
                )
            }
        }
    ...

and I have this TheItemView

@Composable
fun TheItemView(
    item: TheViewItemModel,
    onButtonClick: () -> Unit
) {
    val typoColors = EnhanceTheme.colors.typoColors
    val defaultPadding = dimensionResource(id = DesignSystem.dimen.borderDefault)
    val largePadding = dimensionResource(id = DesignSystem.dimen.large)

    Column(
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {

...
        Text(
            text = "ABCDF",
            modifier = Modifier.padding(horizontal = largePadding)
        )

        Column(
            verticalArrangement = Arrangement.Bottom,
            horizontalAlignment = Alignment.CenterHorizontally,
            modifier = Modifier.weight(1f)
        ) {
            Button(
                buttonState =
                ButtonState(
                    label = "TEST,
                    onClick = onButtonClick,
                  
                   
                )
            )
        }
            ...
    }
}

I want to do this for accessibility. I have tried couple of option online but none of them worked. tried this Jetpack Compose: Move focus between TextFields using D-Pad without onKeyEvent already and similar Thanks.

like image 860
Ahmed S. Durrani Avatar asked Dec 05 '25 20:12

Ahmed S. Durrani


1 Answers

You can use FocusRequester

Step 1

val scope = rememberCoroutineScope()
val focusRequester = remember { FocusRequester() }

Step 2

Attach FocusRequester to the modifier of target composable

Modifier.focusRequester(focusRequester)

Step 3

Request focus like this inside onClick lambda

scope.launch { focusRequester.requestFocus() }

Example

Surface(
   modifier = Modifier.padding(16.dp),
   color = MaterialTheme.colorScheme.background
) {
    val scope = rememberCoroutineScope()
    val focusRequester = remember { FocusRequester() }
    var email by remember { mutableStateOf("") }
    var password by remember { mutableStateOf("") }
    Column(
        modifier = Modifier
            .fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.spacedBy(10.dp)
    ) {
        OutlinedTextField(
            value = email,
            onValueChange = { email = it },
            modifier = Modifier
                .fillMaxWidth(),
            placeholder = {
                Text(text = "email")
            }
        )
        OutlinedTextField(
            value = password,
            onValueChange = { password = it },
            modifier = Modifier
                .fillMaxWidth()
                .focusRequester(focusRequester),
            placeholder = {
                Text(text = "password")
            }
        )
        Button(onClick = {
            scope.launch {
                focusRequester.requestFocus()
            }
        }) {
            Text(text = "Move focus on password field")
        }
    }
}
like image 161
Adnan Habib Avatar answered Dec 08 '25 08:12

Adnan Habib



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!