How to implement Bottom Sheet fragment
If you want to show a different type of bottom sheets in the same activity or want to make reusable bottom sheet the should use BottomSheetDialogFragment. The process for this is very similar to that of making a DialogFragment. As in any DialogFragment, Firstly you have to create a layout file for implement Bottom Sheet fragment
bottom_sheet_fragment.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:background="@color/white" android:padding="16dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="Location:" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Please select a location:" android:textColor="@android:color/black" android:textSize="16sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:orientation="horizontal"> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginRight="8dp" android:layout_weight="1" android:background="@android:color/black" android:text="Cancel" android:textColor="@android:color/white" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:layout_weight="1" android:background="@android:color/black" android:text="Get location" android:textColor="@android:color/white" /> </LinearLayout> </LinearLayout> |
Secondly comes to the JAVA file. For making a modal type of bottom sheet, you will have to extend BottomSheetDialogFragment and set the custom view.
MyBottomSheetFragment.java
1 2 3 4 5 6 7 8 9 10 11 |
public class MyBottomSheetFragment extends BottomSheetDialogFragment { @Override public void setupDialog(Dialog dialog, int style) { super.setupDialog(dialog, style); //Set the custom view View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_bottom_sheet, null); dialog.setContentView(view); } } |
1 2 3 4 5 6 7 8 9 10 11 |
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyBottomSheetFragment fragment = new MyBottomSheetFragment(); fragment.show(getSupportFragmentManager(), "TAG"); } } |
After that, When you call show() method it just spread the bottom sheet.
Listening to state changes in BottomSheetDialogFragment
To listen for state changes in DialogFragment you will first have to get access to the BottomSheetBehaviour instance. Here is how you do it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
public class MyBottomSheetFragment extends BottomSheetDialogFragment { @Override public void setupDialog(Dialog dialog, int style) { super.setupDialog(dialog, style); //Set the custom view View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_bottom_sheet, null); dialog.setContentView(view); CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) view.getParent()).getLayoutParams(); CoordinatorLayout.Behavior behavior = params.getBehavior(); if (behavior != null && behavior instanceof BottomSheetBehavior) { ((BottomSheetBehavior) behavior).setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { @Override public void onStateChanged(@NonNull View bottomSheet, int newState) { String state = ""; switch (newState) { case BottomSheetBehavior.STATE_DRAGGING: { state = "DRAGGING"; break; } case BottomSheetBehavior.STATE_SETTLING: { state = "SETTLING"; break; } case BottomSheetBehavior.STATE_EXPANDED: { state = "EXPANDED"; break; } case BottomSheetBehavior.STATE_COLLAPSED: { state = "COLLAPSED"; break; } case BottomSheetBehavior.STATE_HIDDEN: { dismiss(); state = "HIDDEN"; break; } } Toast.makeText(getContext(), "Bottom Sheet State Changed to: " + state, Toast.LENGTH_SHORT).show(); } @Override public void onSlide(@NonNull View bottomSheet, float slideOffset) { } }); } } |
Make sure to dismiss the dialog when the state is STATE_HIDDEN, the bottom sheet might have disappeared (gone into the hidden state) but since this is a DialogFragment, the dialog itself is still visible to the user.
In conclusion, how the bottom sheet looks like: