Status Update
Comments
na...@gmail.com <na...@gmail.com> #2
Project: platform/frameworks/support
Branch: androidx-main
Author: Louis Pullen-Freilich <
Link:
Adds OverscrollEffect#withoutDrawing and OverscrollEffect#withoutEventHandling
Expand for full commit details
Adds OverscrollEffect#withoutDrawing and OverscrollEffect#withoutEventHandling
These APIs allow overscroll to have events dispatched to it by one component, and rendered in a separate component.
Fixes: b/266550551
Fixes: b/204650733
Fixes: b/255554340
Fixes: b/229537244
Test: OverscrollTest
Relnote: "Adds OverscrollEffect#withoutDrawing and OverscrollEffect#withoutEventHandling APIs - these APIs create a wrapped instance of the provided overscroll effect that doesn't draw / handle events respectively, which allows for rendering overscroll in a separate component from the component that is dispatching events. For example, disabling drawing the overscroll inside a lazy list, and then drawing the overscroll separately on top / elsewhere."
Change-Id: Idbb3d91546b49c1987a041f959bce4b2b09a9f61
Files:
- M
compose/foundation/foundation/api/current.txt
- M
compose/foundation/foundation/api/restricted_current.txt
- M
compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/OverscrollDemo.kt
- M
compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/OverscrollSample.kt
- M
compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/OverscrollTest.kt
- M
compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Overscroll.kt
Hash: f64e25b7a473c757d080521e7dd97b3f6670f60d
Date: Fri Nov 01 18:43:56 2024
si...@google.com <si...@google.com>
si...@google.com <si...@google.com>
so...@google.com <so...@google.com> #3
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.compose.foundation:foundation:1.8.0-alpha06
androidx.compose.foundation:foundation-android:1.8.0-alpha06
androidx.compose.foundation:foundation-jvmstubs:1.8.0-alpha06
androidx.compose.foundation:foundation-linuxx64stubs:1.8.0-alpha06
na...@gmail.com <na...@gmail.com> #4
Sure, I'll test it again and be back with the results tomorrow.
na...@gmail.com <na...@gmail.com> #5
I indeed could not reproduce the issue in a "clean" environment anymore. However, within the app that I discovered the problem in, using an OutlinedTextField now resulted in a crash with the exception IllegalArgumentException: offset(1) is out of bounds [0, 0]
.
After a bit of experimentation, I discovered that this appears to be caused by the fact that the text field was used within a Dialog
. That problem was reproducible even in a clean demo app, using
Dialog(onCloseRequest = {}) {
Surface {
var text = state { "" }
OutlinedTextField(
value = text.value,
onValueChange = { text.value = it },
label = { Text("Label") },
modifier = Modifier.fillMaxWidth()
)
}
}
I'm not sure whether this crash arose as a result to changes around the prior issue (since they both seem to be related to selection bounds), or whether this is a different issue entirely. Should I create a new ticket for it or leave it here? If needed, I can provide a demo project, or a recording.
so...@google.com <so...@google.com> #6
Thanks for coming back to us with the details.
Yes, the text field crashing inside a Dialog is a
Back to the original issue, since we couldn't reproduce it, I'm closing this bug. But please feel free to reopen this bug or file a new bug if you encounter any issues.
na...@gmail.com <na...@gmail.com> #7
I apologize for the turnaround, but just as I was happy about the issue being gone, I managed to reproduce the original bug. I am not completely sure how fixable this is, though.
The difference between the real app and the test was that the textfield value was held and updated not by a regular Compose state, but by an external entity (in this case, MvRx). My guess is that MvRx doesn't always update its state immediately (when it does, it initiates a redraw of the View by itself). I think this state being out of sync is what's causing the issue. At least, I was able to reproduce the behavior by simulating a delayed view update from outside like this:
object ExternalState {
var text: String = ""
}
fun refreshView() {
val handler = Handler()
handler.postDelayed({
(requireView() as ViewGroup).setContent(Recomposer.current()) {
OutlinedTextField(
value = ExternalState.text,
onValueChange = {
ExternalState.text = it
refreshView()
},
label = { Text("Label") },
modifier = Modifier.fillMaxWidth()
)
}
}, 10)
}
It seems like I don't have permission to reopen the bug.
so...@google.com <so...@google.com>
si...@google.com <si...@google.com> #8
Andrey can you please check if you see something to do on the compose side? I do not know Rx.
I checked the sample code in
My guess is that MvRx doesn't always update its state immediately (when it does, it initiates a redraw of the View by itself). I think this state being out of sync is what's causing the issue.
Just based on the comment, if MvRx does not update its state it would be an MvRx & Compose conflict or MvRx issue. What is your suggestion to provide syncronization?
an...@google.com <an...@google.com> #9
var text by remember { mutableStateOf("Text") }
val handler = remember { Handler(Looper.getMainLooper()) }
OutlinedTextField(
value = text,
onValueChange = {
handler.removeCallbacksAndMessages(null)
handler.postDelayed({
text = it
}, 10)
},
label = { Text("Label") },
modifier = Modifier.fillMaxWidth()
)
See the video with how it works.
In the real apps users will not use just mutableStateOf for storing the text as they have their own business logic handling it. and communicating with business logic and updating state back will often happen with some delay - that is what happens in MxRx.
We need to make our IME integration be handling such cases properly
si...@google.com <si...@google.com> #10
The delayed recompose does not fit to the current execution model of TF. TF expects the value to be set or not set; but not a delay. In the current case we can't handle delayed "resets" (since meanwhile user writes something and the new value is basically a reset).
Adam, Leland, I still need to read some documents but is this related to the current coroutine effort? If not do you have any opinions on how to solve the issue.
an...@google.com <an...@google.com> #11
si...@google.com <si...@google.com>
si...@google.com <si...@google.com> #12
checked this. it is either not possible or not worth a change or trick with the current TextFieldValue API. We are planning to change that API and will consider this as a part of it.
si...@google.com <si...@google.com>
si...@google.com <si...@google.com>
na...@gmail.com <na...@gmail.com> #13
Since there should be no major API changes anytime soon now, what's the status on this issue?
si...@google.com <si...@google.com>
ji...@gmail.com <ji...@gmail.com> #14
ma...@gmail.com <ma...@gmail.com> #15
This still happens in Compose 1.3.0-alpha02, see duplicated issues for new steps and code (
This seems like a pretty big oversight as it makes validation of the text fields (such as preventing user from entering more than N characters) very bad experience for the user. And no responses since 2020...
ub...@gmail.com <ub...@gmail.com> #16
This is easily worked around by using the constructor that takes a TextFieldValue as value, but should be fixed nonetheless.
I would be very interested in the reporter's "easy workaround" using the TextFieldValue
constructor. How does that work? When I'm trying to use it, I'm only able to enter one char as a user and no more...
ub...@gmail.com <ub...@gmail.com> #17
I hacked around the issue in the following way:
Before:
// asyncSource comes from the View Model and is changed via `changeText()`
OutlinedTextField(
value = asyncSource.data,
onValueChange = {
viewModel.changeText(it)
}
)
After:
// asyncSource comes from the View Model and is changed via `changeText()`
var inputText by remember(asyncSource.data) { mutableStateOf(asyncSource.data) }
OutlinedTextField(
value = inputText,
onValueChange = {
inputText = it
viewModel.changeText(it)
}
)
I recognize that this is actually duplicating some of the logic, but I didn't have the jumping cursor issue anymore and still retain all flexibility of using asynchronous handling in my View Model and as a data source for the UI.
da...@facile.it <da...@facile.it> #18
Hi, this is a 2020 bug which has undirectely been pointed out also in this ->
Please, at least start to work on this issue.
si...@google.com <si...@google.com> #19
Thanks for the comment.
The team already has started working on general structure of the TextField API since the current API and structure does not allow us to move forward with this ticket.
si...@google.com <si...@google.com> #20
updated the assignee (one of Halil, Zach but can set only one), and also the priority to communicate that the work is ongoing in buganizer.
ro...@oda.com <ro...@oda.com> #21
Hey, regarding this issue, i also notified that :
D/InsetsController: show(ime(), fromIme=true)
is called infinite times, when the mutableState is in the viewModel and i start writing in the textField.
On some devices it work, on others you are stuck after the first character.
Is this fix going to be in 1.4.0 final?
va...@gmail.com <va...@gmail.com> #22
ha...@google.com <ha...@google.com> #23
Yes, the work on this bug and related issues regarding TextField state was started a while ago. 1.5-alpha01
release includes some of this work.
It's unlikely that anything will be finalized in one release-cycle but the upcoming changes will be initially released as Experimental. So, the iterative changes won't be confined to alpha releases.
se...@gmail.com <se...@gmail.com> #24
The solution in post #18 seems to work for me. Hoping this will be fixed soon officially.
da...@decathlon.com <da...@decathlon.com> #25
thanks
st...@gmail.com <st...@gmail.com> #27
kl...@google.com <kl...@google.com> #29
Closing this since async onValueChange updates are not supported and will continue to not be supported.
ma...@gmail.com <ma...@gmail.com> #30
ap...@google.com <ap...@google.com> #32
Branch: androidx-main
commit 125070eab17fd3d941e8718ec8a5b9b0d88ee3b4
Author: Zach Klippenstein <klippenstein@google.com>
Date: Wed Oct 04 13:14:11 2023
Kdoc polish for BasicTextField.
- Moved all sample links to the bottom. When rendering kdoc, Studio
doesn't render code samples inline, it places them all at the end. Any
text that comes after the first sample link is not rendered at all. So
any important documentation must come before the first sample link or
it will not be shown when users are viewing docs in Studio.
- Cleaned up wording of state management caveats. Our async requirements
weren't obvious, so I stated them explicitly and linked to our more
detailed guide.
Relnote: "Improved documentation on `BasicTextField` regarding
`onValueChange` requirements."
Test: n/a
Bug:
Change-Id: I90fc9dea845dafbf35fd439fe7813b2a752d9189
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicTextField.kt
pr...@google.com <pr...@google.com> #33
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.compose.foundation:foundation:1.6.0-alpha08
androidx.compose.foundation:foundation-android:1.6.0-alpha08
androidx.compose.foundation:foundation-desktop:1.6.0-alpha08
Description
Steps to reproduce:
1. Use OutlinedTextField with the String-based constructor in any composable function
2. Type something long (a sentence or something) into the field
3. Observe the cursor randomly being placed before the letter that was just typed
This is easily worked around by using the constructor that takes a TextFieldValue as value, but should be fixed nonetheless.