material-components-android icon indicating copy to clipboard operation
material-components-android copied to clipboard

[BottomSheetBehavior] BottomSheetBehavior doesn't play well with layout transitions

Open bejibx opened this issue 4 years ago • 3 comments
trafficstars

Description: layout with attached BottomSheetBehavior jumps to top of its parent container if you change view visibility inside it with enabled LayoutTransitions.

Here is how it looks like with enabled layout transitions:

with-transitions

And if I disable layout transitions it works as expected:

without-transitions

Source code: BottomSheetBug.zip

The reason is LayoutTransition basically works as follows:

  1. Remember current views state
  2. Wait for next layout
  3. Remember new views state
  4. Start animations from old state to new state

And if we look at BottomSheetBehavior#onLayoutChild(CoordinatorLayout, V, int) method we can see this:

    // First let the parent lay it out
    parent.onLayoutChild(child, layoutDirection);
    // Offset the bottom sheet
    parentWidth = parent.getWidth();
    parentHeight = parent.getHeight();
    childHeight = child.getHeight();
    fitToContentsOffset = max(0, parentHeight - childHeight);
    calculateHalfExpandedOffset();
    calculateCollapsedOffset();

The problem here - when parent.onLayoutChild(child, layoutDirection); is called parent CoordinatorLayout lays out our view on top of itself and this causes View.OnLayoutChangeListener inside LayoutTransition to trigger with new values before BottomSheetBehavior have chance to offset it properly.

Ideally, I would have add some method to CoordinatorLayout to get view bounds without layout it, use it, then offset view to proper position and call View#layout(int, int, int, int) at the end from BottomSheetBehavior.

Android API version: 30

Material Library version: 1.3.0

Device: API 25 emulator

bejibx avatar Feb 11 '21 18:02 bejibx