Thursday, January 11, 2018

Android Bottom Sheet smooth expanding, like Google Maps

Leave a Comment

I want to recreate Bottom Sheet Behavior provided in the Google Maps app:

Link to expected behavior.

I have tried using BottomSheetBehavior and couple of other 3rd party libs like umano AndroidSlidingUpPanel but the problem I was unable to avoid is they are all snapping the Bottom Sheet in between states (collapsed and expanded).

I would like to have a Bottom Sheet which can be smoothly expanded by sliding up, without it snapping to the closest state but instead to remain where the user stopped with the sliding.

1 Answers

Answers 1

You can achieve this by subclassing BottomSheetBehavior, and overriding onTouchEvent to return early on ACTION_UP and ACTION_CANCEL.

public class CustomBottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {      public CustomBottomSheetBehavior() {         super();     }      public CustomBottomSheetBehavior(Context context, AttributeSet attrs) {         super(context, attrs);     }      @Override     public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {          int action = event.getActionMasked();         switch (action) {             case MotionEvent.ACTION_UP:             case MotionEvent.ACTION_CANCEL:                 return true;         }          return super.onTouchEvent(parent, child, event);     } } 

This prevents the BottomSheetBehavior class from handling these events and triggering the 'expand' or 'collapse' call.

To apply your CustomBottomSheetBehavior in xml: app:layout_behavior="com.yourpackage.CustomBottomSheetBehavior"


To restore default functionality to the BottomSheetBehavior when the sheet is fully expanded or collapsed, you can add a flag which is set when the slide offset reaches a certain value. In the following example, the bottom sheet ACTION_UP and ACTION_CANCEL events are only ignored when the slide offset is between 0.1 and 0.9.

public class CustomBottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {      private boolean isExpandedOrCollapsed;      public CustomBottomSheetBehavior() {         super();          listenForSlideEvents();     }      public CustomBottomSheetBehavior(Context context, AttributeSet attrs) {         super(context, attrs);          listenForSlideEvents();     }      void listenForSlideEvents() {         setBottomSheetCallback(new BottomSheetCallback() {             @Override             public void onStateChanged(@NonNull View bottomSheet, int newState) {             }              @Override             public void onSlide(@NonNull View bottomSheet, float slideOffset) {                 isExpandedOrCollapsed = slideOffset < 0.1f || slideOffset > 0.9f;             }         });     }      @Override     public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {          if (!isExpandedOrCollapsed) {             int action = event.getActionMasked();             switch (action) {                 case MotionEvent.ACTION_UP:                 case MotionEvent.ACTION_CANCEL:                     return true;             }         }          return super.onTouchEvent(parent, child, event);     } } 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment