Reputation: 2072
I am not sure if it's bug about FocusManager or TextField or something else. If I try to set the TextField's value and clear the focus of a TextField at the same time (i.e. within a button click), the setting of the TextField's value would not work.
In the following code, after I type something in the TextField, clicking the "reset and clear" button only clears the focus from the TextField, but the value of the TextField does not change. If I click the button again, it does change the value of the TextField. It seems to me I can do either one but not both at the same time.
P.S. Add a delay right before the clearFocus would make it work, of course then whole lambda has to be wrapped inside a scope launch.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
ResetAndClearTextField()
}
}
}
}
}
@Composable
private fun ResetAndClearTextField() {
val (textFieldValue, setTextFieldValue) = remember { mutableStateOf(
TextFieldValue("")
) }
val focusManager = LocalFocusManager.current
Column {
TextField(
value = textFieldValue,
onValueChange = setTextFieldValue
)
Button(onClick = {
setTextFieldValue(TextFieldValue(""))
focusManager.clearFocus()
}) {
Text("reset and clear")
}
}
}
project build.gradle
buildscript {
ext {
compose_version = '1.0.1'
}
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.4"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
app build.gradle
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.testing.myapplication"
minSdk 26
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
useIR = true
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
kotlinCompilerVersion '1.5.21'
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
implementation 'androidx.activity:activity-compose:1.4.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
}
Upvotes: 2
Views: 1214
Reputation: 2072
I found that using scope to wrap the focusManager.clearFocus()
did not really work around the problem. It doesn't clear the focus at all but it would still respect the setTextFieldValue(TextFieldValue(""))
A real workaround is reverse the line, so clear the focus before setting the TextFieldValue.
focusManager.clearFocus()
setTextFieldValue(TextFieldValue(""))
Upvotes: 2