How to improve empty list layout using android’s ViewStub

0

Introduction

In the previous article, I showed you how to create a ListView layout with an add action bar for quickly adding the items.

When displaying a list, it is important that we handle the case when the list becomes empty and we should not shy away from having an explicit view for the empty case.

In the current article, I will show you how to create a separate empty list view and refer to the empty list view in the main list view layout. In the process we will come to know about ViewStub and FrameLayout.

Empty ListView

First create your own empty list image. I have created a small icon just for the example’s sake.

Next, create a separate layout for empty list view. I have shown you here two examples.
One with LinearLayout and the other using FrameLayout.
    1. You can create a linear layout with an image and some text.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content"
              android:layout_height="wrap_content" android:layout_gravity="center" android:orientation="vertical"
              android:padding="20dp">

    <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content"
               android:src="@drawable/ic_empty_list" android:contentDescription="@string/empty_list_hint"/>

    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp"
              android:layout_gravity="center_horizontal" android:gravity="center" android:textStyle="bold"
              android:textSize="20sp" android:text="@string/no_items"/>

</LinearLayout>

 

      • Or overlay the text over the image

 

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content"
             android:layout_height="wrap_content" android:layout_gravity="center">

    <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"
               android:src="@drawable/android_empty_list" android:contentDescription="@string/empty_list_hint"/>

    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"
              android:gravity="center" android:textSize="20sp" android:text="@string/no_items"
              android:textColor="@color/empty_list_color"/>

</FrameLayout>

 

What is FrameLayout

In the above layout, I have used FrameLayout as the parent to overlay text on the image. If you note, under the FrameLayout I have two child views, one is Image and the other is text. So first the image view is drawn and next the text is overlayed on it.
The above example is one of the main purposes why we use FrameLayout, which is primarily to stack up elements one on top of the other, that is, overlaying views in the Z -axis.
You can also use FrameLayout to block out an area on the screen for displaying a single item. An example will follow as we continue with our layout.

ViewStub

Let’s modify the list view layout to point to the above empty list layout.

We can do it two different ways.

  • Use Include to re-use an already existing layout
<include layout="@layout/empty_list" android:id="@android:id/empty"/>
  • Or use ViewStub which is an invisible, zero-sized View that can be used to lazily inflate layout resources at runtime. Thus it may never be inflated if it is not made visible.
<ViewStub android:id="@android:id/empty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout="@layout/empty_list"/>

 

If the ListView has data, empty view layout held by @android:id/empty will never be inflated as ListView and empty view are mutually exclusive from visibility point of view.

Final Layout

Below layout is the modified ver#  of the layout from my previous article, the empty ViewStub held by @android:id/empty and the ListView are put together under FrameLayout and share the layout-weight and layout-height properties. This is another example of FrameLayout where it is used to block out an area on the screen. Note here that the initial plain text view of @android:id/emptyis replaced by the richer view using ViewStub.
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/taskListParent"
              android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical">

    <FrameLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1">

        <ViewStub android:id="@android:id/empty" android:layout_width="wrap_content"
                  android:layout_height="wrap_content" android:layout_gravity="center"
                  android:layout="@layout/empty_list"/>

        <ListView android:id="@android:id/list" android:layout_width="fill_parent"
                  android:layout_height="wrap_content"/>

    </FrameLayout>

    <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content"
                  android:orientation="horizontal">

        <EditText android:id="@+id/quickAddText" android:layout_width="0dp" android:layout_height="wrap_content"
                  android:layout_weight="1" android:hint="@string/add_hint"/>

        <ImageButton android:id="@+id/quickAddButton" android:layout_width="wrap_content"
                     android:layout_height="wrap_content" android:background="@android:color/transparent"
                     android:contentDescription="@string/add_hint" android:onClick="add"
                     android:src="@drawable/btn_add"/>

    </LinearLayout>

</LinearLayout>

Download Source Code

You can download the source code here: sandboxListViewWithViewStub.zip

Share.

Leave A Reply