Fixed
Status Update
Comments
ma...@google.com <ma...@google.com>
kl...@google.com <kl...@google.com>
kl...@google.com <kl...@google.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
kl...@google.com <kl...@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
ap...@google.com <ap...@google.com> #4
Project: platform/frameworks/support
Branch: androidx-main
commit 04501ae82a6f8349c5a4037080bb2b93c7fddefe
Author: Zach Klippenstein <klippenstein@google.com>
Date: Fri Apr 15 15:26:57 2022
Ignore bringIntoView requests that are already satisfied by an in-progress request.
If a new bringIntoView call happens before the previous one is finished,
then if the new one requests a rectangle that will already be in
view after the old request is satisfied, the new request is ignored.
Bug: b/216790855
Fixes: b/184760918
Test: New tests for BringIntoViewResponder and text field.
Test: ./gradlew :compose:f:f:cDAT
Relnote: "Concurrent `BringIntoViewRequester.bringIntoView` calls for
rectangles that are completely overlapping will now only honor the
larger rectangle's request."
Change-Id: I34be70f23527e4fea694fd5266bbc127cc1d1b0b
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldFocusTest.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewRequester.kt
M compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextFieldsInScrollableDemo.kt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponderTest.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.kt
https://android-review.googlesource.com/2065910
Branch: androidx-main
commit 04501ae82a6f8349c5a4037080bb2b93c7fddefe
Author: Zach Klippenstein <klippenstein@google.com>
Date: Fri Apr 15 15:26:57 2022
Ignore bringIntoView requests that are already satisfied by an in-progress request.
If a new bringIntoView call happens before the previous one is finished,
then if the new one requests a rectangle that will already be in
view after the old request is satisfied, the new request is ignored.
Bug:
Fixes:
Test: New tests for BringIntoViewResponder and text field.
Test: ./gradlew :compose:f:f:cDAT
Relnote: "Concurrent `BringIntoViewRequester.bringIntoView` calls for
rectangles that are completely overlapping will now only honor the
larger rectangle's request."
Change-Id: I34be70f23527e4fea694fd5266bbc127cc1d1b0b
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldFocusTest.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewRequester.kt
M compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextFieldsInScrollableDemo.kt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponderTest.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.kt
ap...@google.com <ap...@google.com> #5
Project: platform/frameworks/support
Branch: androidx-main
commit c1cf16ad7e547a8e267fd25fb6698ecbbb0ca58a
Author: Zach Klippenstein <klippenstein@google.com>
Date: Wed Apr 20 14:36:22 2022
Improve BringIntoViewResponder dispatching behavior for concurrent requests.
The initial fix for this, aosp/2065910, did not ensure that
BringIntoViewRequester.bringIntoView didn't return until the request was
satisfied or interrupted, and couldn't queue requests.
This change queues all overlapping requests, ensures bringIntoView
doesn't return until the previous request is cancelled or complete, and
adds a bunch of tests for various overlapping and interrupting
behaviors. It also improves the documentation a bit.
Fixes: b/216790855
Test: New tests in BringIntoViewResponderTest
Test: ./gradlew :compose:f:f:cDAT
Relnote: "`BringIntoViewRequester.bringIntoView` will now always suspend
until the request is either completed or was interrupted by a newer,
non-overlapping request. Overlapping requests will be queued."
Change-Id: I43e7f73af86615f08e2d2d05bfd05ac96d0c65e4
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewRequester.kt
M compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.android.kt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponderTest.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoView.kt
https://android-review.googlesource.com/2071910
Branch: androidx-main
commit c1cf16ad7e547a8e267fd25fb6698ecbbb0ca58a
Author: Zach Klippenstein <klippenstein@google.com>
Date: Wed Apr 20 14:36:22 2022
Improve BringIntoViewResponder dispatching behavior for concurrent requests.
The initial fix for this, aosp/2065910, did not ensure that
BringIntoViewRequester.bringIntoView didn't return until the request was
satisfied or interrupted, and couldn't queue requests.
This change queues all overlapping requests, ensures bringIntoView
doesn't return until the previous request is cancelled or complete, and
adds a bunch of tests for various overlapping and interrupting
behaviors. It also improves the documentation a bit.
Fixes:
Test: New tests in BringIntoViewResponderTest
Test: ./gradlew :compose:f:f:cDAT
Relnote: "`BringIntoViewRequester.bringIntoView` will now always suspend
until the request is either completed or was interrupted by a newer,
non-overlapping request. Overlapping requests will be queued."
Change-Id: I43e7f73af86615f08e2d2d05bfd05ac96d0c65e4
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewRequester.kt
M compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.android.kt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponderTest.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoViewResponder.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/relocation/BringIntoView.kt
Description
If two requests are made concurrently on the same BringIntoViewRequester, if the responder is using standard animation APIs (like scrollable is) then the last request to be processed will cancel all the animations for the other requests.
This currently happens when text fields gain focus. Consider a text field with a large decoration box (eg a material text field). The focusable first gets the focus event and makes a request to bring the entire decoration box into view. Then the text field gets the focus event and makes a request to bring the cursor area into view. The cursor area is always inside the decoration box. If the cursor area is already in view, that second request noops and the first request completes, bringing the entire decoration box into view. However, if the cursor area started off hidden (as is common, eg if the entire text field would be covered by the newly shown keyboard), then the second request cancels the first and only the cursor area is brought into view, which means part of the decoration box will stay clipped.
I think the solution is that the bring into view responder should detect when a request comes in while a previous request is still being processed, somehow calculate the merge of the two requests, and only cancel the animation if it needs to adjust it to handle the merge result.
The merge algorithm might look something like this:
In particular, in the case where the entire text field can fit in the responder, this algorithm would always prioritize requests for bringing the entire text field into view over requests to bring the cursor into view.
This logic must happen at each responder node. Because text fields contain their own scrollable below the focusable, even if the cursor request will be ignore by a scrollable much higher up in the tree, the text field's own scrollable still needs to process it.