RSS

The ViewPager

27 Sep

So this is the first on the series on android open source libraries that I have come across. The ViewPager is used in alot of apps. It allows you to swipe across the screen to change the layout or move to the next page, sort of like tabs but not really. Its used in alot of apps, Google play store app uses it.

Im going to use Jake Wharton ViewPagerIndicator. 

  1. Go over to Git here or at the site, then look for a download button. Its going to a zip folder, unzip somewhere you will remember (in your worlkspace is good).
  2. Open eclipse, in your workspace, go to file -> Import. A dialog box will appear prompting you, under android select ‘Existing Android Code into Workspace’
  3. Browse into the folder you just unzipped and select ‘library’
  4. (I kno I skipped a number). Click ok and ok again in the next dialog.
  5. Start up your android project if you havent already. Now at the Project Explorer on your left, Right click on the folder of your application and choose properties. It should take you to this dialog. Choose android on the left.
  6.  Click on the ‘Add’ button then choose Library – the folder we imported into your workspace.
  7. If you are getting an error – “Found 2 versions of android-support-v4.jar in the dependency list but not all the versions are identical (check is based on SHA-1 only at this time).”. Go over to your ‘libs’ folder and replace android-support-v4.jar file with that in the library project you imported. Go to Project -> Clean.

We are now good to go. There are two things involved here: a ViewPager and an Indicator. The ViewPager is the main page while the indicator is sort of like the tab (in this case).

    1. In your project add a new xml file. (main_activity.xml – it was the default)
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <com.viewpagerindicator.TabPageIndicator
        android:id="@+id/indicator"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        />
    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        />
</LinearLayout>
    1. Also create xml file – one or more that will be the different pages that a user can swipe through
<!-- page.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Title"
        android:textAppearance="?android:attr/textAppearanceLarge" />
<a href="https://mycodeandlife.files.wordpress.com/2012/09/device-2012-09-27-204357.png"><img src="https://mycodeandlife.files.wordpress.com/2012/09/device-2012-09-27-204357.png?w=200" alt="" title="device-2012-09-27-204357" width="200" height="300" class="aligncenter size-medium wp-image-300" /></a>
    <TextView
        android:id="@+id/tvdesc"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Description" />

</LinearLayout>

On the java side we have MainActivity.java

package com.gilo.viewpagerexample;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

import com.viewpagerindicator.TabPageIndicator;

public class MainActivity extends Activity{
        //these are the titles that will appear on the "tabs"
	final String[] page_titles = new String[]{"Home", "Me", "Apps", "Android", "About"};
	//this will go the description TextView
        final String[] desc = new String[]{
			"This is the homepage the first one you will see.",
			"I'm pretty much me for now I run this really cool blog you should check it out at mycodeandlife.wordpress.com",
			"I build appps mostly for fun. If you ever want an app just holla",
			"This is the android section",
			"This blog is my journal through life in code and development"
	};
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Instantiating the adapter
        GiloAdapter mAdapter = new GiloAdapter(this);

        //instantiate the Views
        ViewPager mPager = (ViewPager)findViewById(R.id.pager);
        mPager.setAdapter(mAdapter);

        TabPageIndicator mIndicator = (TabPageIndicator)findViewById(R.id.indicator);
        mIndicator.setViewPager(mPager);
    }

    private class GiloAdapter extends PagerAdapter{

    	Context context;

    	public GiloAdapter(Context c){
    		this.context = c;
    	}

    	//This is the number of pages -- 5
		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return page_titles.length;
		}

		@Override
		public boolean isViewFromObject(View v, Object o) {
			// TODO Auto-generated method stub
			return v.equals(o);
		}

		//This is the title of the page that will apppear on the "tab"
		public CharSequence getPageTitle(int position) {
            return page_titles[position];
        }

		//This is where all the magic happen
		public Object instantiateItem(View pager, int position) {
			final LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    		View v = inflater.inflate(R.layout.page, null, false);

    		TextView title = (TextView)v.findViewById(R.id.tvTitle);
    		TextView description = (TextView) v.findViewById(R.id.tvdesc);

    		title.setText(page_titles[position]);
    		description.setText(desc[position]);

    		//This is very important
    		( (ViewPager) pager ).addView( v, 0 );

    		return v;
		}

    	@Override
    	public void destroyItem(View pager, int position, Object view) {
    		((ViewPager) pager).removeView((View) view);
    	}

    	@Override
    	public void finishUpdate(View view) {
    	}

    	@Override
    	public void restoreState(Parcelable p, ClassLoader c) {
    	}

    	@Override
    	public Parcelable saveState() {
    		return null;
    	}

    	@Override
    	public void startUpdate(View view) {
    	}

    }

}

The ViewPage takes an Adapter in this case I’ve written GiloAdapter. The most important method is instantiateItem(View pager, int position) which selects which Layoout to use. I used a LayoutInflator but with only one Layout.(The current library uses fragments). If you are familiar with Adapters from ListViews then its almost the same idea. The destroyItem() is also important that you override or your app will force close with weird error messages.

Lastly we are going to use the default style in the library, so in the manifest add this in the manifest in your Activity tag:

android:theme="@style/Theme.PageIndicatorDefaults"

The .MainActivity in my app

<activity
            android:name=".MainActivity"
             android:theme="@style/Theme.PageIndicatorDefaults"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

And we have

Thats it, next blogposts we’ll change the colors(customise), maybe look at another indicator.
Drop a comment if you found this helpful or if you got some error you can’t figure out, and I’ll try and have a look.

Advertisements
 
12 Comments

Posted by on September 27, 2012 in Android, Android tutorials, Code

 

Tags: , , , ,

12 responses to “The ViewPager

  1. milad

    October 30, 2012 at 8:26 am

    hello please help me i want add a custom list to view pager but i cant ..

    i want add this list http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/

    to pager please help me

     
    • Gilbert Kimutai

      October 31, 2012 at 8:48 am

      I am sorry I took long. been busy. If you could provide me with your code that will be really helpful. But just to give u an idea:The all the magic will happen at the InstantiateItem() method. below
      public Object instantiateItem(View pager, int position) {
      }

      First off u have the xml file containing the listView say called listview_page.xml. Now if we wanted to have it as the first page in our viewpager we’ll have to check the ‘position’ variable:

      public Object instantiateItem(View pager, int position) {
      if(position == 0){
      //inflate the listview_page.xml and instantiate the listView, set its adapter and all that stuff.

      }
      //whatever is to happen in the other pages is to described here
      }

       
    • Gilbert Kimutai

      October 31, 2012 at 8:59 am

      This way (I havent ran it yet):

      public Object instantiateItem(View pager, int position) {
      if(position == 0){
        //inflate the listview_page.xml and instantiate the listView, set its adapter and all that stuff.
        final LayoutInflater inflater = (LayoutInflater)  context.getSystemService               
                                               (Context.LAYOUT_INFLATER_SERVICE);  
        View v = inflater.inflate(R.layout.listview_page, null, false); //our listview_page
         
         ArrayList&lt;HashMap&gt; songsList = new ArrayList&lt;HashMap&gt;();
      
      		XMLParser parser = new XMLParser();
      		String xml = parser.getXmlFromUrl(URL); // getting XML from URL
      		if (xml != null) { //gilo - I added this to avoid the app from force closing when the network is done
      			
      			Document doc = parser.getDomElement(xml); // getting DOM element
      
      			NodeList nl = doc.getElementsByTagName(KEY_SONG);
      			// looping through all song nodes 
      			for (int i = 0; i &lt; nl.getLength(); i++) {
      				// creating new HashMap
      				HashMap map = new HashMap();
      				Element e = (Element) nl.item(i);
      				// adding each child node to HashMap key =&gt; value
      				map.put(KEY_ID, parser.getValue(e, KEY_ID));
      				map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
      				map.put(KEY_ARTIST, parser.getValue(e, KEY_ARTIST));
      				map.put(KEY_DURATION, parser.getValue(e, KEY_DURATION));
      				map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL));
      
      				// adding HashList to ArrayList
      				songsList.add(map);
      			}
      		}else{
      			Log.d("XML error", "XML is null");
      			Toast.makeText(this, "The app can't connect to the internet",     Toast.LENGTH_SHORT).show();
      		}
      
      		ListView list = (ListView) v.findViewById(R.id.list);
      
      		// Getting adapter by passing xml data ArrayList
      		adapter = new LazyAdapter(MainActivity.this, songsList); //use the .this
      		list.setAdapter(adapter);
      
                      ( (ViewPager) pager ).addView( v, 0 );
          		
          		return v;
         
        }
      //whatever is to happen in the other pages is to described here
      //the other pages will look like the tutorial above
      final LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          		View v = inflater.inflate(R.layout.page, null, false);
          		
          		TextView title = (TextView)v.findViewById(R.id.tvTitle);
          		TextView description = (TextView) v.findViewById(R.id.tvdesc);
          		
          		title.setText(page_titles[position]);
          		description.setText(desc[position]);
          		
          		//This is very important
          		( (ViewPager) pager ).addView( v, 0 );
          		
          		return v;
      
      }
      
      
       
      • Nebz

        November 19, 2012 at 8:25 pm

        I think this line should be:

        //This is very important
        ( (ViewPager) pager ).addView( list, 0 );
        
        return list;
        
        }
         
      • Gilbert Kimutai

        November 20, 2012 at 4:06 am

        @Nebz they way I did it caters for when you have more views on that page – Like if you had a TextView, EditText and a ListView. Since we only have a listview(which isnt common in real life) that will work.

         
  2. Nebz

    November 19, 2012 at 7:49 pm

    Great and clear tutorial! I’ve been searching this for 3 days!! And your answer to Milad question has saved my life.
    I got the nearly same problem to Milad. But could you tell me how to handle the onitemclick event from the list created above?? I want each time I click item, I’ll go to other activity. Thanks for any response.

     
    • Nebz

      November 20, 2012 at 7:49 am

      Never mind.. I got it already, I think Milad will need this code too if he plans to have multi level list (list with children) without using expandable list:

      
      myList.setOnItemClickListener(new OnItemClickListener() { 
                  	
          			public void onItemClick(AdapterView parent, View view, 
          					int position, long id) {
          				Intent intent = new Intent(getApplicationContext(), MyFragment.class);
          				
          				startActivity(intent);
          			}
          		});
      

      put just before the return.

       
      • Gilbert Kimutai

        November 20, 2012 at 2:20 pm

        Sorry I took long, I wasnt close to a comp, but yeah thats how i did it too. Check out https://mycodeandlife.wordpress.com/2012/11/18/gplayer/ its not really a tutorial but I was just playing with the pagers. U can draw some inspiration frm that.

         
  3. indu

    December 30, 2013 at 10:53 am

    hai i am using your code but i am not soving my probelm of importung the jar files.

     
  4. Tazeen

    March 24, 2014 at 9:54 am

    I’m using your code for page viewer , but i got some error in the layout.xml file like this Attribute is missing the Android namespace
    prefix for = … etc code line.Can you give me a solution.

     
  5. Saeed

    November 8, 2014 at 2:04 pm

    How can i change the text to icons in the tabs ?

     

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

 
%d bloggers like this: