Android Expandable/Collapsible Views

Expandable/Collapsible Views (text, images, etc.) in Android are useful when we want to display all the available options on one screen, without the user having to scroll all the way to find the one he/she is interested in. What we are doing is trying to maximize the use of the available space on the screen by giving an overall view of its content. The Android SDK provides the ExpandableListView class, but sometimes that option is overkill or unfit for our intents & purposes, and we may decide to roll out our own mechanism.

help-content1 help-content2

This example uses a TextView, but any View can be expanded/collapsed the same way.

<!-- activity_info layout file -->
<!-- Clickable title -->
<TextView   android:id="@+id/help_title_gest"
            style="@style/title_help"
            android:text="@string/title"
            android:clickable="true"
            android:onClick="toggle_contents"/>

<!--content to hide/show -->
<TextView   android:id="@+id/txt_help_gest"
            style="@style/txt_help"
            android:text="@string/txt_content"/>

Notice that we have included the onClick handler in the XML, and that we are using styles. A quick reminder: if you are doing serious Android development, and are using neither styles, includes nor fragments to maximize re-usability, you are creating your own hell.

That said, writing the corresponding code is pretty straightforward:


// inside Activity
 TextView txt_help_gest;

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

    txt_help_gest = (TextView) findViewById(R.id.txt_help_gest);
    // hide until its title is clicked
    txt_help_gest.setVisibility(View.GONE);
}

/**
* onClick handler
*/
public void toggle_contents(View v){
      txt_help_gest.setVisibility( txt_help_gest.isShown()
                          ? View.GONE
                          : View.VISIBLE );
}

Note that we used View.GONE and not View.INVISIBLE. We would usually want to use the former for two main reasons.  Firstly, because  we wouldn’t want our expandable View to take up space while invisible. Secondly, using View.GONE provides at least to some extent an expanding/collapsing effect, since the space occupied expands & retracts along with its contents.

Now, if we wanted to go even further with visual effects, we would use Android animations, in this case an up & down sliding effect. We already wrote about animations in an earlier article, so we’ll skip the details here. The reader can also consult this article by Ravi Tamada for an excellent rundown of different visual effects.

For the slide-down effect, we can create  res/anim/slide_down.xml  this way:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
 android:fillAfter="true">

 <scale
 android:duration="200"
 android:fromXScale="1.0"
 android:fromYScale="0.0"
 android:interpolator="@android:anim/linear_interpolator"
 android:toXScale="1.0"
 android:toYScale="1.0" />

</set>

The down movement is illustrated by android:fromYScale going from zero to one in about 200 milliseconds on a linear change rate. Now we’ll write the corresponding method in an utility class Fx:


import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

//...

/**
 *
 * @param ctx
 * @param v
 */
 public static void slide_down(Context ctx, View v){

  Animation a = AnimationUtils.loadAnimation(ctx, R.anim.slide_down);
  if(a != null){
     a.reset();
     if(v != null){
      v.clearAnimation();
      v.startAnimation(a);
     }
  }
}

We’ll do the same for sliding up (left to the reader as an exercise), and our toggle method above will become:

/**
* onClick handler
*/
public void toggle_contents(View v){

  if(txt_help_gest.isShown()){
    Fx.slide_up(this, txt_help_gest);
    txt_help_gest.setVisibility(View.GONE);
  }
  else{
    txt_help_gest.setVisibility(View.VISIBLE);
    Fx.slide_down(this, txt_help_gest);
  }
}

That’s it. We now have a nice expandable/collapsible text section triggered by clicking on its title.

This article is also available at DZone and Java Code Geeks.

About these ads

,

  1. #1 by inferKNOX on February 2, 2014 - 11:10 am

    I would like to implement this to a new project using Eclipse (Kepler), however, I’m completely new and am unsure which files you are editing, or why when I add the code to the MainActivity.java and activity_main.xml, I get errors everywhere.
    Would you be willing to give a bit of a more in depth explanation on how to go about implementing this? Have looked at numerous expandable list views and this is the closest, visually, to what I’m trying to incorporate.

    • #2 by Aamir on May 13, 2014 - 1:20 pm

      Thanks very clear description very easy to understand

  2. #3 by Marurban on February 23, 2014 - 9:40 pm

    Great tip, but this line is unnecessary:
    txt_help_gest.setVisibility( txt_help_gest.isShown() ? View.GONE : View.VISIBLE );

  3. #4 by Mikael on May 3, 2014 - 2:50 pm

    thanks, proved usefull

  4. #5 by Bruno on June 11, 2014 - 6:25 pm

    Great Post thanks!
    But could you explain how u did the design of the layout. It looks great with the wallpaper and the textviews seperated with the lines….
    I am bad in layout designing :P

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: