How to make the bottom sheet (BottomSheetBehavior) expandable to an arbitrary position?
I have a bottom sheet and I want to change its behavior so that it works like on the main screen of the Google Maps app, where you can expand it to any position and leave it there and it won't automatically stick to the bottom or top. Here's my layout with bottom sheet:
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.gms.maps.MapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<View
android:id="@+id/shadow"
android:layout_width="match_parent"
android:layout_height="16dp"
android:background="@drawable/shape_gradient_top_shadow"
app:layout_anchor="@+id/map_bottom_sheet" />
<LinearLayout
android:id="@+id/map_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="300dp"
android:fillViewport="false"
android:orientation="vertical"
app:behavior_peekHeight="50dp"
android:background="@color/lightGray"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<include layout="@layout/bottom_sheet_top_buttons"/>
<android.support.v4.widget.NestedScrollView
android:id="@+id/bottom_sheet_content_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/lightGray"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
I need to basically eliminate forcing the STATE_EXPANDED and STATE_COLLAPSED states when the drag is complete.
Here's a visual explanation of what I am trying to achieve:
As you can see, the bottom sheet does not automatically snap to the top or bottom, but remains in whatever position it was left in.
source to share
Hi Alex, you can try this code for similar expected behavior, it is not so optimized but will help you understand the concept.
final DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
bottomSheetBehavior.setPeekHeight(200);
// set callback for changes
bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
Log.d(TAG, "onStateChanged: " + bottomSheet.getY() + "::" + bottomSheet.getMeasuredHeight() + " :: " + bottomSheet.getTop());
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
ViewGroup.LayoutParams params = bottomSheet.getLayoutParams();
params.height = Math.max(0, metrics.heightPixels - (int) bottomSheet.getTop());
bottomSheet.setLayoutParams(params);
}
});
source to share
Copy the code from android.support.design.widget.BottomSheetBehavior
to create your own behavior. Then change the method onViewReleased()
that is responsible for moving the sheet after you finish dragging. You also have to introduce a new state, in addition to the existing ones - the state helps to restore the position and tell others what state your sheet is in at the moment with the help getState()
.
@Override
public void onViewReleased(View releasedChild, float xVel, float yVel) {
int top;
@State int targetState;
// Use the position where the drag ended as new top
top = releasedChild.getTop();
// You have to manage the states here, too (introduce a new one)
targetState = STATE_ANCHORED;
if (mViewDragHelper.settleCapturedViewAt(releasedChild.getLeft(), top)) {
setStateInternal(STATE_SETTLING);
ViewCompat.postOnAnimation(releasedChild, new SettleRunnable(releasedChild, targetState));
} else {
setStateInternal(targetState);
}
}
source to share
I created a proof of concept coming from source code from the design library. You can view it here . The problem with the original behavior is that it doesn't allow flings and most of the methods are private, so extending the class and overriding some methods in an attempt to achieve this won't get you very far either. My implementation allows for additional snapping behavior, transient states (not automatically snapping after dragging), and adjustments when setting the gap height and maximum height.
source to share