Android: Don’t Overlook ViewSwitcher

Switching between views in Android is a recurring requirement. Loading screens and background processing is a prime example. The process usually goes: show a loading or splash screen, load data in the background, and when the data has been loaded switch to a view showing the loaded data. The first instinct of developers, especially those new to Android, is to use a view’s visibility attribute to achieve this. Set View1 to Visible, View2 to Invisible until processing is done then reverse. Numerous code examples online use this clumsy procedure and after using Android for months now I have only just come across ViewSwitcher by chance. ViewSwitcher provides the capacity to switch between two views using simple logic that produces more readable code. In this short post I will highlight this often overlooked class with a brief description and example code demonstrating its use.

Views and ViewSwitcher

In Android a view is the basic building block for user interface components. Views and ViewGroups ultimately make up what is displayed on an Android device. ViewSwitcher is just a view animator that has the ability to switch between these basic components. Using ViewSwitcher is simple. Views are added by the method addView(View child, int index, ViewGroup.LayoutParams params) or by using the ViewSwitcher factory and are accesssed (usually) using the methods showNext() and showPrevious(). It is important to note that ViewSwitcher can only hold two child views at a time.

More about ViewSwitcher:
http://developer.android.com/reference/android/widget/ViewSwitcher.html

ViewSwitcher in Action

Let’s say we have two views represented in XML.
A Button (XML1):

<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/btn_loadmorecontacts"
    android:text="Load More Items"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:textAppearance="?android:attr/textAppearanceLarge" 
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:textColor="#FFFFFF" 
    android:background="@android:drawable/list_selector_background" 
    android:clickable="true" 
    android:onClick="onClick" />

An Indeterminate ProgressBar and TextView (XML2):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"
    android:gravity="center_horizontal" 
    android:minHeight="?android:attr/listPreferredItemHeight">

    <ProgressBar 
        android:id="@+id/progressbar"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_centerVertical="true" />

    <TextView 
        android:text="Loading…" 
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_height="wrap_content" 
        android:layout_width="wrap_content"
        android:layout_toRightOf="@+id/progressbar" 
        android:layout_centerVertical="true" 
        android:gravity="center"
        android:padding="10dip"
        android:textColor="#FFFFFF" />
</RelativeLayout>

The following code creates a ListView of items and a footer item with the text “Load More Items”. When this is clicked the view will change showing a ProgressBar until the background job is complete and then return to it’s original view, all using ViewSwitcher.

public class ViewSwitcherExample extends ListActivity
				 implements OnClickListener {
    
	//sample list items
	static final String[] ITEMS = new String[]
          { "List Item 1", "List Item 2", 
            "List Item 3", "List Item 4", 
            "List Item 5", "List Item 6", 
            "List Item 7", "List Item 8", 
            "List Item 9", "List Item 10" };
	
	//the ViewSwitcher
	private ViewSwitcher switcher;
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
	  super.onCreate(savedInstanceState);
	  
	  //no window title
	  requestWindowFeature(Window.FEATURE_NO_TITLE);
	  
	  //create the ViewSwitcher in the current context
	  switcher = new ViewSwitcher(this);
	  
	  //footer Button: see XML1
	  Button footer = (Button)View.inflate(this, R.layout.btn_loadmore, null);
	  
	  //progress View: see XML2
	  View progress = View.inflate(this, R.layout.loading_footer, null);
	  
	  //add the views (first added will show first)
	  switcher.addView(footer);
	  switcher.addView(progress);
	  
	  //add the ViewSwitcher to the footer
	  getListView().addFooterView(switcher);
	  
	  //add items to the ListView
	  setListAdapter(new ArrayAdapter(this,
	          android.R.layout.simple_list_item_1, ITEMS));
	}

	@Override /* Load More Button Was Clicked */
	public void onClick(View arg0) {
		//first view is showing, show the second progress view
		switcher.showNext();
		//and start background work
		new getMoreItems().execute();
	}
	
	/** Background Task To Get More Items**/
	private class getMoreItems extends AsyncTask {
		@Override
		protected Object doInBackground(Void… params) {
			//code to add more items
			//...
			try {
				Thread.sleep(3000); //only to demonstrate
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return null;
		}

		@Override /* Background Task is Done */
		protected void onPostExecute(Object result) {
			//go back to the first view
			switcher.showPrevious();
                        //update the ListView
		}
	}
}

Continue the conversation by sharing your comments here on the blog and by following us on Twitter @CTCT_API

Leave a Comment