-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Description
Description:
When Bottom Sheet's flag fitToContents is set to default value true, the bottom sheet will always set its state to STATE_EXPANDED whenever a swipe up gesture is performed on the bottom sheet, even tho the content is not long enough to be expanded to full screen, i.e. swiping up result in NO VISUAL CHANGES to the UI.
A side effect of the above is that, in a "non-expandable" bottom sheet, when we do swipe up gesture, it will think itself been set to STATE_EXPANDED and then invalidate the bottom sheet drawable, which will make the top corners of the bottom sheet flat (from rounded top corners)
Take the blow recording as a example:
STATE_COLLAPSED -> STATE_EXPANDED by swiping up
device-2021-09-06-133302.mp4
STATE_EXPANDED -> STATE_COLLAPSED by swiping down
device-2021-09-06-133438.mp4
STATE_EXPANDED -> STATE_COLLAPSED by swiping down on BottomSheetDialog, release it and let itself auto settle
device-2021-09-06-133622.mp4
Expected behavior:
This might be controversial but there are two directions we would expect:
- NEVER have
STATE_COLLAPSEDfor a short bottom sheet thatfitToContent == true, (this will involve fix for other use cases to prevent the state becomesSTATE_COLLAPSED) OR - Prevent the bottom sheet's state to become
STATE_EXPANDEDwhen we tries to swipe up
Source code:
@Override
public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) {
int top;
@State int targetState;
if (yvel < 0) { // Moving up
if (fitToContents) {
top = fitToContentsOffset;
targetState = STATE_EXPANDED; <<<-------- This is where we need to ad extra logic
} else {
int currentTop = releasedChild.getTop();
if (currentTop > halfExpandedOffset) {
top = halfExpandedOffset;
targetState = STATE_HALF_EXPANDED;
} else {
top = getExpandedOffset();
targetState = STATE_EXPANDED;
}
}
} else if (hideable && shouldHide(releasedChild, yvel)) {
...
} else if (yvel == 0.f || Math.abs(xvel) > Math.abs(yvel)) {
// If the Y velocity is 0 or the swipe was mostly horizontal indicated by the X velocity
// being greater than the Y velocity, settle to the nearest correct height.
...
} else { // Moving Down
...
}
startSettlingAnimation(releasedChild, targetState, top, true);
}
Proposed Solution for the 2nd approach above (as it will not impact other uses cases)
if (yvel < 0) { // Moving up
if (fitToContents) {
// Keep it at collapsed state when the collapsed height and expanded height are the same,
// i.e. content is not long enough to visually expand the bottom sheet
if (fitToContentsOffset == collapsedOffset) {
top = collapsedOffset;
targetState = STATE_COLLAPSED;
} else {
top = fitToContentsOffset;
targetState = STATE_EXPANDED;
}
}
} else if (...) { ... }
Android API version: API 29
Material Library version: 1.5.0-alpha02
Device: ONE PLUS 8 PRO
To help us triage faster, please check to make sure you are using the latest version of the library.
We also happily accept pull requests.