Sunday, April 25, 2021

jetpack compose - TextField clear focus

Compose TextField Clear Focus
TextField is one of the most used widgets of the android jetpack compose library. A TextField is used for writing some text on the android user interface or modifying text in an app. TextField is the equivalent of the android view system’s EditText widget. They act likely the same in an android app. But the jetpack compose library provides us a different API to manage the TextField behaviors such as requesting focus on TextField and clear focus from a TextField widget.

This android jetpack compose tutorial will demonstrate how we can clear focus from a TextField widget programmatically. We can use FocusManager.clearFocus() method to clear focus from the currently focused component and set the focus to the root focus modifier. To do that we create an instance of LocalFocusManager and call its clearFocus() method to remove focus from TextField.

Finally, we used two Button widgets to make our tutorial. On the first Button click event, we set focus to our TextField widget. And on the second Button’s click event we clear/remove focus from the TextField widget programmatically. Here we call FocusRequester object’s requestFocus() method by a Button click event to request TextField focus programmatically. And call the FocusManager.clearFocus() method to clear focus from the TextField widget. So, we can say that FocusRequester.requestFocus() method allows us to set focus on its associated TextField and FocusManager.clearFocus() method remove focus from the currently focused component.

When we request or set focus on a TextField widget, the soft keyboard is visible on the app screen. On the other side when we clear or remove focus from a TextField widget then the soft keyboard hides/collapsed from the app screen. TextField also visually behaves differently on its focus state and unfocused state.

This tutorial code is written in an android studio IDE, so you can copy the code and paste it into your android studio IDE main activity file to check how we set focus on a TextField widget and how we also clear focus from TextField programmatically. Build apk and run it on an emulator device or on a physical android device to test it. Screenshots are also displayed at the bottom of the code snippets. Look at those to understand the code perfectly.
MainActivity.kt

package com.cfsuman.jetpackcompose

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Column
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            MainContent()
        }
    }


    @Composable
    fun MainContent(){
        Column(
            Modifier
                .background(Color(0xFFEDEAE0))
                .fillMaxSize()
                .padding(32.dp),
            verticalArrangement = Arrangement.spacedBy(24.dp)
        ) {
            var textState by remember { mutableStateOf(TextFieldValue()) }
            val localFocusManager = LocalFocusManager.current
            val focusRequester = FocusRequester()

            OutlinedTextField(
                value = textState,
                onValueChange = { textState = it },
                label = { Text(text = "Input your name") },
                modifier = Modifier
                    .focusRequester(focusRequester)
                    .fillMaxWidth(),
            )

            Button(onClick = {
                focusRequester.requestFocus()
            }) {
                Text(text = "Request Focus")
            }

            Button(onClick = {
                localFocusManager.clearFocus()
            }) {
                Text(text = "Clear Focus")
            }
        }
    }


    @Preview
    @Composable
    fun ComposablePreview(){
        //MainContent()
    }
}