Material Design for Tablets

So far we’ve seen use cases for popular design patterns restricted to a handset only. Now let’s look at applying Material Design for Tablets in Android app development.

New to Material Design? Get started with Android Material Design for pre Lollipop first.

Let’s begin with the project setup so our app can handle different screen sizes, and fire up a layout accordingly.

A fitting example to showcase the best tablet design would be the Navigation Drawer pattern. It’s pretty famous and can be seen on almost any mobile app. On mobiles, you swipe right or tap the Hamburger menu to open it. While on tablet, it usually stays opened (Master Detail flow). Like a two pane layout. Let’s look at making such a template for your tablet app.

tablet-land

Material Design Tablet Metrics

This doesn’t involve you doing anything ‘special’. You just need to create appropriate folders for your tablet resources, and add relevant files. That is key.

Layout for Tablet Design

Here’s the breakdown which shows the folders you need to have under res/ folder. Keep in mind the default folder for layouts is res/layout and for values its res/values.  We’re going to create alternate resources for tablets that will override these defaults.

I’ll try my best to keep it simple and not over-complicate.

breakpoints-tableThe folders work on a concept of smallest width (sw). The key takeaway here is that layouts above 600dp is tablet, with 600dp and 720dp being 7 inch and 10 inch tablets respectively. For alternative landscape configurations, append -land to the folder name.

For values folder it follows the same concept. This is the bare minimum and enough for most cases. However, if you’re the curious one like me, here’s the full breakdown.

I strongly suggest that you follow that link whenever making your folder structure for a hybrid tablet app. Simply because the Material Design specs are the updated guidelines and NOT this.

So given that you’ve understood everything that went on above, for this post, we need a layout for phone, and an alternate for tablet. Given that, we will need a res/layout and res/layout-sw-600dp folders.

Tablets are best used in landscape so while you can go ahead and use the layout-sw-600dp folder if you want, but the two pane layout is ideal for landscape, so I’m going with the layout-sw-600dp-land folder.

Dimensions

Also note that the dimension values that you specify, you must define its alternate dimension values in the res/values/dimens.xml folder. Remember to use the correct values folder for tablets.

Example, the default activity margins are 16dp for mobile, and 24dp for 7 inch to 9 inch tablets. So I would define a dimension like this:

PHONE: res/values/dimens.xml: <dimen name="activity_margin">16dp</dimen>

TABLET: res/values-sw600dp/dimens.xml: <dimen name="activity_margin">24dp</dimen>

Note how both dimension values have the same name, while residing in different res/values folder. Android will take care of accessing the correct folder. In this case, it takes 16dp until a device’s width is 599dp. Anything 600dp and beyond in width will take 24dp.


Enough of me rambling, let’s dive into making our tablet app. Basically, we’ll create 2 layouts, one for phone and another for tablet that reside in different layout folders. Then in our Activity class, we’ll check which layout is in use and setup accordingly. Yep, it takes twice the effort my friend. That’s why we use Fragments 😉

Phone Layout

Start by defining your res/layout/activity_main.xml

Since I mentioned we’ll be doing a two pane layout, for phones that very layout is our regular Navigation Drawer. I’m implementing a Material Navigation Drawer with the help of the Design Support Library.

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

    <FrameLayout
        android:id="@+id/main_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!--Use this Frame to inflate your Fragment -->
        <FrameLayout
            android:id="@+id/main_content_area"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

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

    </FrameLayout>

    <!-- Your drawer content -->
    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer" />

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

To learn more about NavigationView or Navigation Drawer, read Easy Navigation Drawer with Design Support Library.

Tablet Layout

Now for res/layout-sw600dp-land/activity_main.xml

Optionally, if you want the regular phone landscape to have this layout as well, then you can include this layout in res/layout-land/ instead.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="@dimen/drawer_width"
        android:layout_height="match_parent"
        android:background="@android:color/white"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer" />

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

    <FrameLayout
        android:id="@+id/main_content_area"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="?attr/actionBarSize" />

</LinearLayout>

The thing to notice here is, the ID for NavigationView and FrameLayout (which inflates Fragment) are the same. The only thing different, is the Drawer layout in res/layout/activity_main.xml. Hence we will use this difference to identify whether its a tablet or phone layout.

Remember that the Android framework will automatically choose the correct layout. So we just need to check which one it is and react accordingly. This, we will handle in Java.

Handling Both Layouts in Activity

The crux of the Activity is this:

  if (findViewById(R.id.drawer) != null) {
            mTwoPane = false;
            // Handle Phone layout setup here
        } else {
            mTwoPane = true;
            // Handle Tablet setup here
}

We find any one ID that’s unique to either layout (phone or tablet). Here, the Drawer exists only in for the phone layout, hence we check if a view containing that ID is inflated. So if the layout holding the Drawer is inflated, it means its a phone. Otherwise its tablet.

We use this simple if condition to check the type of device and initialize accordingly, using a Boolean ‘mTwoPane‘ to keep track of the changes. Alternatively you can fetch the device width and handle changes, but I find this solution more elegant.

public class MainActivity extends AppCompatActivity {
    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setUpToolbar();

        if (findViewById(R.id.drawer) != null) {
//            Phone layout
            mTwoPane = false;

            setUpNavDrawer();
            ...
        } else {
//            Tablet layout
            mTwoPane = true;
            ...
            }
        }
        // Initialize & handle views here common to both Phone & Tablet
        mNavigationView = (NavigationView) findViewById(R.id.nav_view);
        // Inflate the common Fragment here @+id/main_content_area (FrameLayout)
        ...
    }

Hope the comments are self explanatory. Anything specific to phone or tablet is handled in their respective if or else statements. What is common to both is handled outside them.

Final Output

Finally after a lot of folder creations and alternate resource files, we’re ready to run our tablet app.

[su_row][su_column size=”1/2″]

Screenshot_2015-09-07-18-22-50

Mobile (Portrait)

[/su_column][su_column size=”1/2″]

Screenshot_2015-09-07-18-23-04

Mobile (Landscape)

[/su_column][/su_row]

[su_row][su_column size=”1/2″]

tablet-portrait

Tablet (Portrait)

[/su_column][su_column size=”1/2″]

tablet-land

Tablet (Landscape)

[/su_column][/su_row]


Source Code:
Available on GitHub.

Wrap Up

I hope this post provided needed insights for you to get started on Material Design for Tablets. I’ve used a pretty common use case- a two pane layout with the Navigation Drawer, covering small (600dp) and large (720dp) tablet versions.

We’ve seen how we can define alternate resource files in our folder structure which lets Android pick the right one depending on screen size. We also saw how to handle different layouts in our code and react accordingly. Designing for Android tablet opens up a whole new dimension for us designers to play more freely on a larger screen.

Remember that a good app is one that intelligently makes use of available space, yet retaining familiarity.

Hoping to see you come up with awesome layout designs. Do show them off in the comments below.

Suleiman

Product Designer who occasionally writes code.

You may also like...

4 Responses

  1. goodev says:

    I think there maybe missing a layout for tablet :

Leave a Reply

Your email address will not be published. Required fields are marked *