How to implement Bottom Sheets using new design support library 23.2
Asked Answered
S

4

32

Google release the new update to support library 23.2 in that they added bottom sheet feature. Can any one tell how to implement that bottom sheet using that library.

Severin answered 25/2, 2016 at 5:21 Comment(1)
android-developers.blogspot.in/2016/02/…Steinke
W
37

enter image description here

enter image description here

use layout like below

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout>

        <android.support.design.widget.CollapsingToolbarLayout>

            <ImageView/>

            <android.support.v7.widget.Toolbar/>

        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout>

            //.....

        </LinearLayout>


    </android.support.v4.widget.NestedScrollView>

    <FrameLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:behavior_hideable="true"
        app:layout_behavior="android.support.design.widget.BottomSheetBehavior">

        //your bottom sheet layout

        </LinearLayout>
    </FrameLayout>


    <android.support.design.widget.FloatingActionButton/>

</android.support.design.widget.CoordinatorLayout>

in Activity

CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.main_content);
// The View with the BottomSheetBehavior
View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);
final BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
    @Override
    public void onStateChanged(@NonNull View bottomSheet, int newState) {
        // React to state change
        Log.e("onStateChanged", "onStateChanged:" + newState);
        if (newState == BottomSheetBehavior.STATE_EXPANDED) {
                fab.setVisibility(View.GONE);
            } else {
                fab.setVisibility(View.VISIBLE);
            }
    }

    @Override
    public void onSlide(@NonNull View bottomSheet, float slideOffset) {
        // React to dragging events
        Log.e("onSlide", "onSlide");
    }
});

behavior.setPeekHeight(100);
Wrapper answered 25/2, 2016 at 6:46 Comment(6)
How to anchor the bottom sheet?Antiquated
@KaveeshKanwal: use setPeekHeight for anchor or from xml app:behavior_peekHeight="100dp"Wrapper
The problem is that this only covers one part of the bottom sheet design, namely the persistent ones. Modal bottom sheets (eg. a Share dialog) aren't normally part of the main layout but has their own. It'd be nice to now if anybody has an idea of how to cover that case as well.Forestation
@Gábor, Modal bottom sheets are dialogs with custom views, you can use the class BottomSheetDialog to display them. BottomSheetDialog class has a method setContentView() to set the custom view and another method show() to display them.Barnardo
@DhawalSodhaParmar Can you please help me with bottom sheet. what should i do onStateChanged if i want to hide the state inside if state expanded ?Valorize
@jaydroider: check this answer it may help you https://mcmap.net/q/173498/-disabling-user-dragging-on-bottomsheetWrapper
P
9

You can just follow instructions provided here: http://android-developers.blogspot.com/2016/02/android-support-library-232.html

"By attaching a BottomSheetBehavior to a child View of a CoordinatorLayout (i.e., adding app:layout_behavior=”android.support.design.widget.BottomSheetBehavior”), you’ll automatically get the appropriate touch detection to transition between five state..."

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/white">

    <!-- Your Widgets -->

    <FrameLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ff0000"
        app:behavior_hideable="true"
        app:layout_behavior="android.support.design.widget.BottomSheetBehavior">

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Test" />

    </FrameLayout>

</android.support.design.widget.CoordinatorLayout>

Then from your activity:

View bottomSheet = findViewById(R.id.bottom_sheet);
BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.setState(<desired state>);
Posy answered 25/2, 2016 at 5:37 Comment(2)
For me bottomSheetBehavior.setState(<desired state>); does not work directly after BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet); in the onCreate() from my activity nor the onResume, it throws a java.lang.Object java.lang.ref.WeakReference.get()' on a null object reference. But if I wait some time for a user interaction (button click) it works. any idea ?Parabasis
See #35906625. Basically extend the BottomSheetBehaviour, override onLayoutChild and call setState after calling super. Code has been provided.Mask
R
6

gradle:first use compile 'com.android.support:design:23.2.0'

in your layout

<include layout="@layout/content_sheet" />

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="@dimen/fab_margin"
    android:src="@android:drawable/ic_dialog_email" />
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/bottom_sheet"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
    style="@style/Widget.Design.BottomSheet.Modal">
    <CalendarView
        android:layout_width="match_parent"
        android:layout_height="match_parent"></CalendarView>
</FrameLayout>

in java

    CoordinatorLayout coordinatorLayout= (CoordinatorLayout) findViewById(R.id.cl_main);
    final View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);
    final BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
    behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {

        }
        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {
            // React to dragging events

        }
    });
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            behavior.setState(BottomSheetBehavior.STATE_EXPANDED );
        }
    });
Rabbitry answered 25/2, 2016 at 9:59 Comment(0)
P
1

You can follow the tutorial on tutsplus.com https://code.tutsplus.com/articles/how-to-use-bottom-sheets-with-the-design-support-library--cms-26031

<android.support.design.widget.CoordinatorLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/coordinator_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

     <com.google.android.gms.maps.MapView
        android:id="@+id/map_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:uiCompass="true"
        app:uiMapToolbar="false" />


     <android.support.v4.widget.NestedScrollView
            android:id="@+id/bottom_sheet"
            android:layout_width="match_parent"
            app:behavior_peekHeight="100dp"
            app:behavior_hideable="true"
            android:layout_height="350dp"
            android:clipToPadding="true"
            android:background="@android:color/holo_orange_light"
            app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
            >
     
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="@string/ipsum"
                android:padding="16dp"
                android:textSize="16sp"/>
     
        </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

If you want it to be swipe dismissable, make sure to add app:behavior_hideable="true" on the tag.

inside your activity you can say:

  BottomSheetBehavior mBottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottom_sheet));
  mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);

  findViewById(R.id.button).setOnClickListener(p-> mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED));
Pulchi answered 17/3, 2017 at 9:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.