Status Update
Comments
ma...@google.com <ma...@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
ma...@google.com <ma...@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
ma...@gmail.com <ma...@gmail.com> #4
Hi, sorry for not responding earlier. I saw that the experimental LazyColumn
& LazyRow
composables have been added and it looks like it should solve the issue. Will Lazy{Column,Row}
composables be used inside Lazy{Column,Row}For
in the future? Or will Lazy{Column,Row}For
be deprecated?
an...@google.com <an...@google.com> #5
ma...@gmail.com <ma...@gmail.com> #6
As far as I have seen Lazy{Column,Row}
don't set the key anywhere, so it is possible to set a custom key manually. Or am I missing something?
ap...@google.com <ap...@google.com> #7
Branch: androidx-main
commit aafeb1b7807ed6a353896480d25c60d18e85475b
Author: Andrey Kulikov <andreykulikov@google.com>
Date: Wed Jan 27 18:09:39 2021
Add custom keys support for LazyColumn/LazyRow
It allows smarter reordering as we match elements by key, not by index.
Example: we had elements 0, 1, 2 and all of the elements did have some local state with use of remember {}. Without custom keys when we remove an element 1 the list is now 0, 2. But the LazyColumn operates with indexes in the list, so the remembered values which were previously associated with item 1 will now be given for the item 2.
But if we provide custom keys like this:
LazyColumn {
items(list, key = { it }) { ... }
}
We can match the composition state of the item content by these keys, not indexes. This means in the example above the state associated with 2 would still be used even when we removed the item 1. The same would happen if we just reorder items.
We will also use this key as a key for saved instance state mechanism which means that when you use rememberSaveable { } inside the item's content it would be automatically restored when the activity would be recreated after screen rotation of if you navigate back to the screen with the list when using the compose-navigation library. The downside of this is that you have to only use types which can be stored inside the android.os.Bundle on Android (On Desktop there are no restrictions). But what if your custom class is not supported by Bundle? Always try to use the whole item object as a key but something like an id of it. In most cases you have String/Long/Int id which represents the element so pass it as a key:
LazyColumn {
items(users, key = { user ->
}
Relnote: "Custom keys support for LazyColumn/LazyRow was added. This allows us to smarter handle items reordering. So the state you stored in remember {} blocks will move together with the item when you reorder elements or removed the item from the middle.
LazyColumn {
items(users, key = { user ->
}"
Fixes: 164901852
Test: LazyCustomKeysTest, LazyItemStateRestoration
Change-Id: Ia50ef7cd8f47ab87d76edc4e0691199ce426729d
M compose/foundation/foundation/api/current.txt
M compose/foundation/foundation/api/public_plus_experimental_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/ListDemos.kt
A compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyCustomKeysTest.kt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyItemStateRestoration.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/CachingItemContentFactory.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyFor.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemInfo.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyMeasuredItem.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyMeasuredItemProvider.kt
M compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/SaveableStateHolder.kt
Description
Issue
Currently, each child of the wrapped with a
LazyColumnFor
composable is implicitlykey
containing the index of the item. Because of this if the order of the items is changed, the children, that got reordered, are needlessly recomposed (this is because the value of the keys have changed). In the extreme case, when an item is inserted at the beginning of the list, the entire subtree ofLazyColumnFor
get recomposed.Motivation
Oftentimes the items that are rendered in these lazy composables, have unique ids. Thus, it would be useful if there was a way of specifying the id of the item as a key.
Possible solution
I have thought of several solutions:
Option 1 would function similarly to how it does in React. Not specifying a key could be a warning.
Personally, I like option 2 better. I am not sure how this parameter could be named, but its type could simply be:
(Int, T) -> Any
Int
is the index of the itemT
is the type of the itemThe default value for the parameter could be defined as
{ i, _ -> i }
. This way, when the parameter is not specifiedLazyColumnFor
(orLazyRowFor
) would function exactly as it does now.Also maybe a better type signature could be
T.(Int) -> Any
, this way if the user wants to use an id of the item as a key, the function would be as simple as{ id }
instead of{ _, item -> item.id }
.