Status Update
Comments
ae...@google.com <ae...@google.com>
so...@google.com <so...@google.com> #2
In EditText first event closes the keyboard and second handles back navigation. In Compose, first closes the keyboard, on second text field loses the focus, third handles back navigation.
I checked a bit the code and found that we consume the key event when we move the focus. If I always return false
in
So we probably shouldn't consume events with keyCode=KEYCODE_BACK
.
da...@gmail.com <da...@gmail.com> #3
The behavior can be useful in some situation if it could be controlled and not be the default :-)
so...@google.com <so...@google.com> #4
Re-assigning to Ralston for a proper fix.
ap...@google.com <ap...@google.com> #5
Branch: androidx-main
commit 583cec5c1b9c99f841ecd7493666d08ea23cbd50
Author: Ralston Da Silva <ralu@google.com>
Date: Thu Jul 01 15:22:22 2021
Fix back button handling in Compose
In Android, when a top level focusable item is focused, and the
user clicks back, we exit the app. However in Compose, we first
clear focus and then exit the app when the user presses back again.
This CL removes the need for the extra back press for Compose.
Note: This is an alternate fix to aosp/1753281.
Bug: 192433071
Test: ./gradlew compose:ui:ui:connectedCheck -P android.testInstrumentationRunnerArguments.class=androidx.compose.ui.focus.ComposeViewKeyEventInteropTest
Change-Id: I8a9098a06792668c9e3bafe9485ff2e07b10a8a5
M compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/ComposeViewKeyEventInteropTest.kt
M compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusTraversalInTest.kt
M compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusTraversalOutTest.kt
M compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusManager.kt
so...@google.com <so...@google.com>
ma...@gmail.com <ma...@gmail.com> #6
Thanks for the very quick turnaround time on this. Very appreciated.
ma...@gmail.com <ma...@gmail.com> #7
Which version did this fix land into? It seems it's not fixed in compose 1.0.0-rc02.
so...@google.com <so...@google.com> #8
This change won't make it to 1.0 release
ph...@gmail.com <ph...@gmail.com> #9
I'm not sure, what is expected behaviour for android?
In compose, when screen opens with a TextField, it's not becoming focused, but using xml EditText it does.
After the fix, will the TextField resign focus after first back button tap, or focus just won't prevent back button from working when keyboard is hidden?
For me the first case seems preferable, but still I'm not sure why in xml EditText it's focused but keyboard not shown. I haven't worked with xml much.
In case anyone is looking for a solution until this fix is released, check out my answer:
ra...@google.com <ra...@google.com> #10
If the keyboard(IME) is open, the back key dismisses the keyboard.
Otherwise, the back key moves focus to the parent. In most cases you don't have a parent, but consider this example:
Row(Modifier.focusable()) {
Box(Modifier.focusable()) {
}
}
If the box is focused, then clicking back will move focus to the Row.
In compose, we have a top level focusable modifier that is not visible to the user. In this example, setContent has a focusable modifier (That we use internally to control focus, and TextField has it's own focusable modifier:
setContent {
TextField()
}
Now, when the text field is focused, the keyboard is shown. Clicking back once would hide the keyboard, clicking back the second time would clear focus from the text field, and clicking back the third time would send the back key to the activity and exit the app.
This bug fixes this issue where you needed 3 back presses to clear focus. Now on the second back press, instead of moving focus to the root focus modifier (which the user can't see), we send it to the activity so that the app can exit.
With this fix you would still need two back presses. Dismissing the keyboard does not clear focus. This is by design, and is consistent with the Classic view system. It allows the user to dismiss the keyboard, but still continue typing on the keyboard without the user having to hit tab multiple times to re-focus on the TextField that was previously focused.
ma...@gmail.com <ma...@gmail.com> #11
The fix did not make it to v1.0.1 either. Can we expect it in any 1.0.x release soon or will it be exclusive to 1.1.x releases?
va...@gmail.com <va...@gmail.com> #12
sc...@javadude.com <sc...@javadude.com> #13
@ExperimentalComposeUiApi
@Composable
fun CommonTextField(
value: String?,
@StringRes label: Int,
onBack: () -> Unit,
onValueChange: (String) -> Unit
) =
TextField(
value = value ?: "",
label = { Text(text = stringResource(label)) },
onValueChange = onValueChange,
modifier = Modifier
.padding(8.dp)
.fillMaxWidth()
// workaround for bug:
// for the moment, we'll just force it to consume the Back key in onKeyEvent
// and explicitly pop the stack in the navigator
// a fix for the bug has been submitted but per the comments it sounds like it won't make the 1.0.0 release
// NOTE: the "Back" key reference is currently experimental API and could change
.onKeyEvent {
if (it.key == Key.Back) {
onBack()
true
} else {
false
}
}
)
ph...@gmail.com <ph...@gmail.com> #14
You can use compose 1.1.0-alpha03, the fix is included there. Not sure if there is anything unstable compared to 1.0.2, you need to test that.
Also, if you are as unhappy as I am with the fact that the focus stays with TextField after the keyboard disappears, take a look at
wo...@gmail.com <wo...@gmail.com> #15
Dismissing the keyboard does not clear focus. This is by design, and is consistent with the Classic view system. It allows the user to dismiss the keyboard, but still continue typing on the keyboard without the user having to hit tab multiple times to re-focus on the TextField that was previously focused.
How can the user continue typing after they have closed the keyboard?
si...@gmail.com <si...@gmail.com> #16
ph...@gmail.com <ph...@gmail.com> #17
it may be cool for development, but in real life I believe 99% of people don't use external keyboard with a phone, so it's quite strange to leave the focus for such a rare case.
I think the focus should not disappear only if there's some external device connected.
ro...@google.com <ro...@google.com> #18
There are still Android phones with physical keyboards. Hardware keyboards are also used with tablets, and laptop-style devices (Chromebooks for instance). Finally, the hardware keyboard may be an accessibility input device.
wo...@gmail.com <wo...@gmail.com> #19
And would it be possible to check if there is a hardware keyboard? I assume that the vast majority of devices only uses the onscreen keyboard and for these, after closing the keyboard it doesn it make any sense to keep the cursor blinking.
Description
Jetpack Compose release version: 1.0.0-beta09 Android Studio Build: Android Studio Arctic Fox | 2020.3.1 Beta 3 Build #AI-203.7717.56.2031.7395685, built on May 25, 2021
Steps to reproduce:
EditText
needs 2 back presses to quit. Whilst the compose app with theTextField
needs 3 back presses to quit.The same behavior happens with
BasicTextField
.It is of course undesired to have to press the back button once more to achieve the desired effect in a compose app.