34

I have a Jetpack Compose (Beta04) BasicTextField (with decorationBox). How can I clear the focus?

I have tried with focusRequester but this doesn't works:

val focusRequester = remember { FocusRequester() }

// ...

BasicTextField(modifier = Modifier.focusRequester(focusRequester), /* ... */)

// ...

placesFocusRequester.freeFocus()
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
Tobi
  • 507
  • 1
  • 5
  • 13

2 Answers2

78

To clear focus from the currently focused component you can use the FocusManager.clearFocus method:

    val focusRequester = remember { FocusRequester() }
    val focusManager = LocalFocusManager.current
    var value by rememberSaveable { mutableStateOf("initial value") }
    BasicTextField(
        value = value,
        onValueChange = { value = it },
        decorationBox = { innerTextField ->
            Row(
                Modifier
                    .background(Color.LightGray, RoundedCornerShape(percent = 30))
                    .padding(16.dp)
                    .focusRequester(focusRequester)
            ) {
                //...
                innerTextField()
            }
        }
    )
  
    Button(onClick = { focusManager.clearFocus() }) {
        Text("Clear focus")
    }
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • 1
    How do I achieve the same if I want to clear the focus upon native backpress? – Avinash Parasurampuram Sep 08 '21 at 01:54
  • 3
    @AvinashParasurampuram use BackHandler(true){ focusManager.clearFocus() } – Amr Jyniat Nov 15 '21 at 14:24
  • 1
    This was surprisingly simple, thanks. For anyone using view models, I'd recommend you keep the FocusRequester in there so you can reuse it elsewhere and set up LocalFocusManager in the composable. – OzzyTheGiant May 25 '22 at 16:08
  • @AvinashParasurampuram and how can you exit the screen when you override the back action with the `BackHandler` set to always true? That works for removing the focus, but not for you will be stuck on the screen – Worker123 Nov 03 '22 at 10:55
-3
@Composable 
fun InputEditText(
    value: String,
    modifier: Modifier,
    onValueChange: (String) -> Unit,
    textStyle: TextStyle, hintTextStyle: 
    TextStyle, placeHolderString: String = "",
    enabled: Boolean = true, readOnly: Boolean = false,
    singleLine: Boolean = false,
    maxLines: Int = Int.MAX_VALUE,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    cursorColor: Color = Color.Black,
    imageVector: ImageVector,
    iconTint: Color = Color.Gray,
    backColor: Color = Color.White,
    borderColor: Color = Color.LightGray,
    showPassword: Boolean = false,
    backGroundShape: Shape = RectangleShape,
    passwordVisible: MutableState,
    error: String,
    howError: Boolean = false 
) { 
    BasicTextField( 
        visualTransformation = if (showPassword) { 
            if (!passwordVisible.value) VisualTransformation.None else PasswordVisualTransformation() 
        } else { VisualTransformation.None }, 
        value = value, 
        onValueChange = onValueChange, 
        modifier = modifier, 
        textStyle = textStyle, 
        decorationBox = { innerTextField -> 
            Column { 
                Row( 
                    modifier = Modifier
                        .background(backColor, backGroundShape)
                        .border( width = 1.dp, color = if (showError) Color.Red else borderColor, backGroundShape ) 
                        .padding(14.dp) 
                        .fillMaxWidth(), 
                    horizontalArrangement = Arrangement.Start, 
                    verticalAlignment = CenterVertically 
                ) { 
                    Icon(
                        imageVector = imageVector, 
                        contentDescription = null, 
                        tint = iconTint, 
                        modifier = Modifier.padding(end = 6.dp) 
                    ) 
                    if (value.isEmpty()) { 
                        Text(
                            text = placeHolderString, 
                            color = hintTextStyle.color, 
                            fontSize = hintTextStyle.fontSize, 
                            fontStyle = hintTextStyle.fontStyle, 
                            fontFamily = hintTextStyle.fontFamily, 
                            textAlign = hintTextStyle.textAlign, 
                            fontWeight = hintTextStyle.fontWeight, 
                            style = hintTextStyle 
                        ) 
                    } 
                    innerTextField() 
                    if (showPassword) { 
                        Column(
                            modifier = Modifier.fillMaxWidth(), 
                            verticalArrangement = Arrangement.Bottom, 
                            horizontalAlignment = Alignment.End 
                        ) { 
                            Image( 
                                painter = painterResource(
                                    id = if (!passwordVisible.value) 
                                        R.drawable.ic_baseline_visibility_off_24 
                                    else R.drawable.ic_baseline_visibility_24
                                ), 
                                contentDescription = "Cart button icon", 
                                modifier = Modifier
                                    .size(24.dp)
                                    .clickable { 
                                        passwordVisible.value = !passwordVisible.value 
                                    }, 
                                colorFilter = ColorFilter.tint(color = iconTint) 
                            ) 
                        } 
                    } 
                    if (showError) { 
                        Column(
                            modifier = Modifier.fillMaxWidth(), 
                            verticalArrangement = Arrangement.Bottom, 
                            horizontalAlignment = Alignment.End 
                        ) { 
                            Icon(
                                imageVector = Icons.Filled.Info, 
                                contentDescription = null, 
                                tint = Color.Red, 
                                modifier = Modifier.padding(end = 6.dp) 
                            ) 
                        } 
                    } 
                } 
                if (showError) { 
                    Row(modifier = Modifier.fillMaxWidth()) { 
                        Text(
                            text = error, 
                            modifier = Modifier.fillMaxWidth(), 
                            style = TextStyle(
                                color = Color.Red, 
                                fontFamily = FontFamily.SansSerif, 
                                fontSize = 11.sp, 
                                textAlign = TextAlign.Start, 
                            ) 
                        ) 
                    } 
                } 
            } 
        }, 
        enabled = enabled,
        readOnly = readOnly, 
        singleLine = singleLine, 
        maxLines = maxLines, 
        keyboardOptions = keyboardOptions, 
        keyboardActions = keyboardActions, 
        cursorBrush = SolidColor(cursorColor) 
    ) 
}
commandiron
  • 1,019
  • 1
  • 9
  • 25