Fixed
Status Update
Comments
pa...@google.com <pa...@google.com>
lo...@gmail.com <lo...@gmail.com> #3
One solution would be to clip only at the edges where scrolling content can go under. It might mean hacking the clip bounds to be the width or height of the nearest clipping parent composable, or the topmost one.
ap...@google.com <ap...@google.com> #4
Project: platform/frameworks/support
Branch: androidx-main
commit 0df3d14606dc7376ef7b5a4c91d45716524e3a5c
Author: Andrey Kulikov <andreykulikov@google.com>
Date: Mon May 24 20:30:27 2021
Fix for scrollable containers clipping its children on the cross axis
In the scrollable containers we want to clip the main axis sides in order to not display the content which is scrolled out. But once we apply clipToBounds() modifier on such containers it causes unexpected behavior as we also clip the content on the cross axis sides. It is unexpected as Compose components are not clipping by default. The most common case how it could be reproduced is a horizontally scrolling list of Cards. Cards have the elevation by default and such Cards will be drawn with clipped shadows on top and bottom. This was harder to reproduce in the Views system as usually scrolling containers like RecyclerView didn't have an opaque background which means the ripple was drawn on the surface on the first parent with background. In Compose as we don't clip by default we draw shadows right in place. We faced similar issue in Compose already with Androids Popups and Dialogs where we decided to just predefine some constant with a maximum elevation size we are not going to clip. We are going to reuse this technique here. This will improve how it works in most common cases. If the user will need to have a larger unclipped area for some reason they can always add the needed padding inside the scrollable area.
Relnote: Fix for scrollable containers clipping its children on the cross axis. It was easily reproducible if you have a LazyRow with Card items. now the shadow will not be clipped.
Test: new tests
Fixes: 186318448
Change-Id: Icb6356d8dac24720981caa6afe8785546a2e7847
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ScrollTest.kt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowTest.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
https://android-review.googlesource.com/1713918
Branch: androidx-main
commit 0df3d14606dc7376ef7b5a4c91d45716524e3a5c
Author: Andrey Kulikov <andreykulikov@google.com>
Date: Mon May 24 20:30:27 2021
Fix for scrollable containers clipping its children on the cross axis
In the scrollable containers we want to clip the main axis sides in order to not display the content which is scrolled out. But once we apply clipToBounds() modifier on such containers it causes unexpected behavior as we also clip the content on the cross axis sides. It is unexpected as Compose components are not clipping by default. The most common case how it could be reproduced is a horizontally scrolling list of Cards. Cards have the elevation by default and such Cards will be drawn with clipped shadows on top and bottom. This was harder to reproduce in the Views system as usually scrolling containers like RecyclerView didn't have an opaque background which means the ripple was drawn on the surface on the first parent with background. In Compose as we don't clip by default we draw shadows right in place. We faced similar issue in Compose already with Androids Popups and Dialogs where we decided to just predefine some constant with a maximum elevation size we are not going to clip. We are going to reuse this technique here. This will improve how it works in most common cases. If the user will need to have a larger unclipped area for some reason they can always add the needed padding inside the scrollable area.
Relnote: Fix for scrollable containers clipping its children on the cross axis. It was easily reproducible if you have a LazyRow with Card items. now the shadow will not be clipped.
Test: new tests
Fixes: 186318448
Change-Id: Icb6356d8dac24720981caa6afe8785546a2e7847
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ScrollTest.kt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowTest.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
wo...@gmail.com <wo...@gmail.com> #5
Thanks for your fantastic work :)
[Deleted User] <[Deleted User]> #6
Hi!
I've stumbled across this issue when searching for information about clipping myself. It's really unexpected that LazyList clips in the cross axis, and the use case can very well expand beyond shadows.
For my case, I needed a small avatar which holds a card and is placed with a certain offset, and the MaxSupportedElevation used for clip in the cross-axis was not sufficient for my use-case. It's implemented with negative offset and lies within an item placed in a LazyRow.
My use case is solvable by altering the padding (and making a custom spacing-scheme for the overlying LazyColumn), but it's not an optimal solution. Would be really nice if clipping in the cross-axis could be removed as a whole!
Tested on compose 1.2.0.
I've stumbled across this issue when searching for information about clipping myself. It's really unexpected that LazyList clips in the cross axis, and the use case can very well expand beyond shadows.
For my case, I needed a small avatar which holds a card and is placed with a certain offset, and the MaxSupportedElevation used for clip in the cross-axis was not sufficient for my use-case. It's implemented with negative offset and lies within an item placed in a LazyRow.
My use case is solvable by altering the padding (and making a custom spacing-scheme for the overlying LazyColumn), but it's not an optimal solution. Would be really nice if clipping in the cross-axis could be removed as a whole!
Tested on compose 1.2.0.
an...@google.com <an...@google.com> #7
Hey. Unfortunately I am not sure it will be an efficient solution. We anyway have to clip with some bounds and the smaller the bounds the more efficient it is to clip. Feel free to use content padding as you need for your use case
Description
I have a
LazyRow
ofCard
s.Now
LazyRow
creates as aLazyList
which creates aSubcomposeLayout
which has `clipToBounds() in it's modifiers set.This leads to
LazyRow
clipping the shadows of cards. As a workaround I can create enough content padding. This is however a suboptimal solution because that makes it harder to position other elements in relation to that LazyRow composable as it's bottom / top now do not start at the bottom / top of the cards.It would be great if you could find a way such that
LazyRow
/LazyColumn
would not clip it's children.Tested on compose beta 5.