Status Update
Comments
ap...@google.com <ap...@google.com> #2
Thanks for the report! Our UX best practices recommend that components preview the target state. For modal bottom sheets, which have a positional threshold of 56 dp, this means that the scrim's visibility gets determined based on the target value. The target value changes once the positional threshold is crossed. From the UX perspective, we do not recommend gradually changing the scrim alpha.
If you want to deviate from Material's UX, ModalBottomSheetLayout
is probably a good place to start copying the implementation and adjusting this to your needs. However, we understand this is cumbersome while the new swipeable APIs are still internal.
We are still considering different ways of exposing the progress
for modal bottom sheets and other components. It is on our to-do-list, but we are working on some other high-priority tasks at the moment.
Some more nerdy context:
Swipeable is a state machine, and a modal bottom sheet can have three values (Hidden, HalfExpanded and Expanded). The progress is modelled as the fraction of the distance between the current value and target value. For a drag that starts at Expanded
, drags through HalfExpanded
and finishes somewhere after the threshold, the progress will look like this:
1.0f // currentValue = Expanded, targetValue = Expanded
0.9f
0.8f
0.7f // Positional threshold here. currentValue = Expanded, targetValue = HalfExpanded
0.3f
0.4f
...
1.0f // currentValue = HalfExpanded, targetValue = HalfExpanded
(Assuming a positional threshold of 30%)
This makes sense at the Swipeable level, but is a bit confusing as an end-user ModalBottomSheetState API. For the use cases that we see, a (hypothetical) progressBetweenVisibleAndInvisible
API is probably more useful, but we need to have some more explorations.
CC Jose from Material as I believe this would be useful in M3 as well.
Description
Because we have different APIs that act as data inputs to drawing abstractions (ImageBitmap/ImageVector) we should consider renaming ImagePainter to BitmapPainter as it only consumes ImageBitmap parameters.