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