Widget Catalog: SlidingPaneLayout

In the master-detail UI pattern, we are showing both the master and the detail fragment, side-by-side, on larger screens, while showing only one at a time on smaller screens. SlidingPaneLayout encapsulates that logic.

SlidingPaneLayout will detect the screen size. If the screen size is big enough, SlidingPaneLayout will display its two children side-by-side. If the screen size is not big enough, SlidingPaneLayout will display one child at a time. However, by default, when the “master” child is visible, a thin strip on the right will allow the user to return to the “detail” child. Similarly, a swiping gesture can switch from the “detail” back to the “master” child. These are in addition to any changes in context you might introduce based on UI operations (e.g., tapping on an element in a master RecyclerView automatically switching to the detail child).

SlidingPaneLayout is in the Support Library, in the support-core-ui artifact for 27.1.1 and its own slidingpanelayout artifact in 28.0.0 and higher.

Declaring a SlidingPaneLayout

A SlidingPaneLayout can go in your activity’s layout. It works like a horizontal LinearLayout and is designed to hold two or more children. The first child is considered to be “the pane” and is the portion that slides over top of everything else in the SlidingPaneLayout.

As with a LinearLayout, you can use android:layout_width to specify minimum widths for your contents, plus android:layout_weight to allocate any unused space:

<android.support.v4.widget.SlidingPaneLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/panes"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <fragment
    android:id="@+id/sensors"
    android:name="com.commonsware.android.sensor.monitor.SensorsFragment"
    android:layout_width="300sp"
    android:layout_height="match_parent"/>

  <fragment
    android:id="@+id/log"
    android:name="com.commonsware.android.sensor.monitor.SensorLogFragment"
    android:layout_width="400dp"
    android:layout_height="match_parent"
    android:layout_weight="1"/>

</android.support.v4.widget.SlidingPaneLayout>
(from Sensor/Monitor/app/src/main/res/layout/activity_main.xml)

Here, we have two fragments inside of the SlidingPaneLayout. If the current screen width is 300sp+400dp or larger, both fragments will be shown side-by-side, with the log fragment taking up all remaining space (courtesy of its android:layout_weight="1" attribute). If the current width is smaller than 300sp+400dp, though, the two fragments will overlap, with the sensors fragment sliding over top of the log fragment.

Visual Representation

The app that is using the above layout is from the chapter on sensors. The sensors fragment shows a list of all of the sensors on the device, and the log shows a roster of sensor readings from that sensor.

SlidingPaneLayout, Showing the Pane
Figure 1050: SlidingPaneLayout, Showing the Pane

SlidingPaneLayout, with Hidden Pane
Figure 1051: SlidingPaneLayout, with Hidden Pane

SlidingPaneLayout, with Both Panes on a Tablet
Figure 1052: SlidingPaneLayout, with Both Panes on a Tablet

Interacting with a SlidingPaneLayout

Sometimes, just setting up the SlidingPaneLayout is sufficient. Sometimes, you want user interactions to affect the pane. For example, the aforementioned sample app closes the pane once the user makes a selection in the list of available sensors.

SlidingPaneLayout offers: