Creating Instruction Guide using Bottomsheet

The PSLab android app consists of different instruments like oscilloscope, multimeter, wave generator etc and each instrument has different functionality and usage so it is necessary that there should be an instruction guide for every instrument so that the user can easily read the instruction to understand the functionality of the instrument.

In this we will create an instruction guide for the Wave Generator which will contain information about the instrument, it’s functionalities, steps for how to use the instrument.

The main component that I used to create instruction guide is Bottom SheetBottom Sheet is introduced in Android Support v23.2 . It is a special UI widget which slide up from the bottom of the screen and it can be used to reveal some extra information that we cannot show on the main layout like bottom menus,  instructions etc.

They are of two types :

  1. Modal Bottom Sheet:–  This Bottom Sheet has properties very similar to normal dialogs present in Android like elevation only difference is that they pop up from the bottom of screen with proper animation and they are implemented using BottomSheetDialogFragment Class.

  2. Persistent Bottom Sheet:– This Bottom Sheet is included as a part of the layout and they can be slid up and down to reveal extra information. They are implemented using BottomSheetBehaviour Class.

For my project, I used persistent Bottom Sheet as modal Bottom Sheet can’t be slid up and down by the swipe of the finger whereas persistent Bottom Sheet can be slid up and down and can be hidden by swipe features.

Implementing the Bottom Sheet

Step 1: Adding the Dependency

To start using Bottom Sheet we have to add the dependency (We have also include Jake Wharton-Butterknife library for view binding but it is optional.)

dependencies {

   implementation fileTree(include: ['*.jar'], dir: 'libs')

   implementation "com.android.support:appcompat-v7:26.0.1"
   implementation "com.android.support:design:26.0.1"
   implementation "com.jakewharton:butterknife:8.8.1"

   annotationProcessor "com.jakewharton:butterknife-compiler:8.8.1"

Step 2: Creating Bottom Sheet layout file

In this step, we will create the layout of the Bottom Sheet, as our purpose of making Bottom Sheet is to show extra information regarding the instrument so we will include ImageView and TextView inside the layout that will be used to show the content later.

Some attributes in the layout worth noting are:

  • app:layout_behavior: This attribute makes the layout act as Bottom Sheet.
  • app:behavior_peekHeight: This is the height of the Bottom Sheet when it is minimized.
  • app:behavior_hideable: Defines if the Bottom Sheet can be hidden by swiping it down.

Here, we will also create one extra LinearLayout having height equal to the peek_height. This  LinearLayout will be at the top of the BottomSheet as shown in Figure 1 and it will be visible when the BottomSheet is in a minimized state(not hidden). Here we will put text view with like “Show guide” and an arrow pointing upwards so that it is easier for the user to understand that sheet can be viewed by sliding up.

Figure 1 LinearLayout containing textview and imageview

Here is the gist[2] that contains code for the layout of the Bottom Sheet guide

After this step, we can see a layout of Bottom Sheet in our Android Editor as shown in Figure 2

Figure 2 shows the layout of the Bottom Sheet

Step 3: Creating the Container view layout containing content and Bottom Sheet

For container view, we will create new layout under Res Layout and name it “container_view_wavegenerator.xml”

In this layout, we will use ‘Coordinator Layout’ as ViewGroup because persistent Bottom Sheet is implemented using BottomSheetBehavior class which can only be applied to the child of ‘CoordinatorLayout’.

Then add the main layout of our instrument and the layout of the Bottom Sheet inside this layout as its child.

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

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

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

Step 4: Setting Up Bottom Sheet and Handling callbacks

Now we will head over to the “WaveGenerator.java” file(or any instrument java file)Here we will handle set up Bottom Sheet and handle callbacks by using following classes:

BottomSheetBehavior provides callbacks and makes the Bottom Sheet work with CoordinatorLayout.

BottomSheetBehavior.BottomSheetCallback() provides the callback when the Bottom Sheet changes its state. It has two methods that need to be overridden:

  1. public void onSlide(@NonNull View bottomSheet, float slideOffset)

    This method is called when the Bottom Sheet slides up and down on the screen. It has slideOffset as a parameter whose value varies from -1.0 to 0.0 when the Bottom Sheet comes from the hidden state to collapsed and 0.0 to 1.0 when it goes from collapsed state to expanded state.

  2. public void onStateChanged(@NonNull View bottomSheet, int newState)

    This method is called when BottomSheet changed its state. Here, let us also understand the different states which can be attained by the Bottom Sheet:

    • BottomSheetBehavior.STATE_EXPANDED : When the Bottom Sheet is fully expanded showing all the content.
    • BottomSheetBehavior.STATE_HIDDEN : When the Bottom Sheet is hidden at the bottom of the layout.
    • BottomSheetBehavior.STATE_COLLAPSED : When the Bottom Sheet is in a collapsed state that is only the peek_height view part of the layout is visible.
    • BottomSheetBehavior.STATE_DRAGGING : When the Bottom Sheet is dragging.
    • BottomSheetBehavior.STATE_SETTLING : When the Bottom Sheet is settling either at expanded height or at collapsed height.

We will implement these methods in our instrument class, and also put the content that needs to be put inside the Bottom Sheet.

@BindView(R.id.bottom_sheet)
LinearLayout bottomsheet;
@BindView(R.id.guide_title)
TextView bottomSheetGuideTitle;
@BindView(R.id.custom_dialog_schematic)
ImageView bottomSheetSchematic;
@BindView(R.id.custom_dialog_desc)
TextView bottomSheetDesc;

BottomSheetBehavior bottomSheetBehavior;

@Override
protected void onCreate(Bundle savedInstanceState) { 
              
           //main instrument implementation code

           setUpBottomSheet()
}

private void setUpBottomSheet() {

   bottomSheetBehavior = BottomSheetBehavior.from(bottomsheet);

    bottomSheetGuideTitle.setText(R.string.wave_generator);
   bottomSheetSchematic.setImageResource(R.drawable.sin_wave_guide);
   bottomSheetDesc.setText(R.string.wave_gen_guide_desc);

  bottomSheetBehavior.setBottomSheetCallback(new 
  BottomSheetBehavior.BottomSheetCallback() {
       @Override
       public void onStateChanged(@NonNull View bottomSheet, int newState) {
           if (newState == BottomSheetBehavior.STATE_EXPANDED) {
               bottomSheetSlideText.setText(R.string.hide_guide_text);
           } else {
               bottomSheetSlideText.setText(R.string.show_guide_text);
           }
       }

       @Override
       public void onSlide(@NonNull View bottomSheet, float slideOffset) {
           Log.w("SlideOffset", String.valueOf(slideOffset));
        }
      });
}

After following all the above steps the Bottom Sheet will start working properly in the Instrument layout as shown in Figure 3

Figure 3 shows the Bottom Sheet in two different states

To read more about implementing Bottom Sheet in layout refer this: AndroidHive article- working with bottomsheet

Resources

  1. Developer Documentation – BottomSheetBehaviour
  2. Gist containing xml file for layout of Custom Bottomsheet