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); } }
0 comments:
Post a Comment