Sur la route d'Oxiane digressions diverses

LeBlog OXiane

19 déc
2011

Utiliser le ViewPager pour slider d’un écran à un autre

Je vais vous parler dans cet article d’un composant qui est disponible à partir de la version 3.0 d’android ou alors à partir de 1.6 via l’ACP. Il s’agit du ViewPager. Ce composant permet de présenter une galerie en plein écran. C’est à dire que pour pourrez scroller horizontalement d’un écran à un autre.
Vous pouvez voir notre démo de ce composant à la fin de cet article.
Ce composant à été présenté par Rich Hyndman ici : http://android-developers.blogspot.com/2011/08/horizontal-view-swiping-with-viewpager.html

On peut trouver des utilisation du ViewPager entre autres sur le Market ou encore sur Google+.

Il est également possible d’adapter le composant Gallery pour obtenir le même effet mais vous allez devoir vous creusez pas mal les méninges pour éviter certains problèmes.

Parmi ces problèmes vous aurez des composants qui interceptent le onClick alors que vous faite un slide, ou encore, plusieurs composants qui prennent en même temps l’état state_pressed alors que vous en touchez qu’un seul.

Bref il est beaucoup plus simple d’utiliser un composant fait pour : le ViewPager. La bonne surprise c’est qu’il est disponible à partir des version 1.6 grâce au package de compatibilité. Ce package développé par google. Il permet de rendre disponible des nouvelles API notamment les fragments, le ViewPager, etc…

Voilà comment utiliser ce composant étape par étape :

Installer le package de compatibilité Android (ACP)

Pour installer ce package, il suffit d’utiliser l’ AndroidSDK Manager, de développer le répertoire Extras et cocher « Android Support Package ».



Ensuite copier le jar ce trouve à Android\android-sdk\extras\android\support\v4\android-support-v4.jar dans le répertoire libs à la racine de votre projet (créé celui ci si il n’existe pas).

déclarer le Viewpager dans un layout.

Il va falloir dans le cas d’utilisation de l’ACP préfixer le composant par son nom de package.


Utiliser un adapter pour remplir le ViewPager

Le ViewPager, à l’instar du ListView, est couplé avec un adapter qui permet d’accéder à sa source de données. Le PageAdapter est le plus communs des adapter du ViewPager.
Les principales méthodes du PageAdapter sont les suivantes :

  • getCount(): retourne le nombres de pages du ViewPager
  • instantiateItem(View collection, int position): Crée une view pour une position donnée.
  • destroyItem(View collection, int position, Object view): Supprime une vue d’une position donnée.

Voici un exemple d’implémentation:

@Override
public int getCount() {
	return collection.size();
}    

@Override
public Object instantiateItem(View collection, int position) {
	View v = layoutInflater.inflate(...);
	...
	((ViewPager) collection).addView(v,0);
	return v;
}

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

Remarque:
A propos de la gestion de la mémoire, le ViewPager va toujours demander d’instancier la page à droite et à gauche de la page actuelle. Et il va demander la detruction des vues qui sont à plus de 1 en distance.
Par exemple si je suis sur la page 6 en théorie on a donc en mémoire la page 5, 6 et 7.
Si je scroll vers la page 7, alors la méthode instantiateItem() sera appelé avec la position 8 et la méthode destroyItem() avec la position 5.

Comment agir sur le Viewer depuis le code?

Notez que vous pouvez être averti d’un slide en attachant un listener au viewPager grace à la méthode setOnPageChangeListener(myPageChangeListener).
Cela permet par exemple d’indiquer le numéro de page sur une TextView.

mPager.setOnPageChangeListener(new OnPageChangeListener() {

	@Override
	public void onPageSelected(int currentPage) {
		pageTextView.setText(String.valueOf(currentPage+1));

	}
	....
});

Vous pouvez également dans le code demander au ViewPager de se positionner sur une page précise. Cela peut être utile par exemple si on veux qu’un click sur un bouton dans un menu fasse défiler le ViewPager sur une page voulue.
Cette méthode est viewPager.setCurrentItem(5);

Et avec un Fragment…

Pour les fragments il existe un adaptateur spécifique qui permet de simplifier leur utilisation dans un ViewPager: le FragmentPagerAdapter.
Cela permet de mettre un Fragment par page.
Ici vous n’aurez besoin de surcharger que deux méthodes:

  • getCount() qui retourne le nombre de page
  • getItem(int position) qui renvoie le Fragment

Par contre il y a une petite particularité au niveau de la construction du Fragment. On utilisera la méthode setArguments() pour lui passer des objets via un Bundle.

Voici un exemple de FragmentPagerAdapter:

public static class MyAdapter extends FragmentPagerAdapter {
	List mFormationList;

	public MyAdapter(FragmentManager fm, List formationList) {
		super(fm);
		mFormationList = formationList;
	}

	@Override
	public int getCount() {
		return mFormationList.size();
	}

	@Override
	public Fragment getItem(int position) {
	    Formation formation = mFormationList.get(position);
	    FormationFragment fragment = new FormationFragment();
	    Bundle args = new Bundle();
	    args.putParcelable("formation", formation);
	    fragment.setArguments(args);
	    return fragment;
	}
}

Conclusion


Voila, j’espère que cet article vous a donné envie d’utiliser ce magnifique composant qui donnera de l’allure à votre application. Par contre, je conseille de donner une indication visuelle à l’utilisateur pour lui permettre de voir que la zone est scrollable.

shocq

shocq

  • http://twitter.com/jlrousselin Jean-Louis ROUSSELIN

    Qui a prêté son IPhone pour faire la vidéo :p ?

  • Pingback: Sur la route d'Oxiane » Blog Archive » La combinaison de LoaderManager et MediaStore.Audio sous Android

  • Tybopier

    Salut, sympa le tuto. Il faudrait juste préciser au niveau de l’implémentation :

    au lieu de : 

    (Java = Sensible à la casse)

    ps : Si nécessaire -> clean/rebuild le projet après l’intégration de la library.

    Bonne continuation =)

  • Tybopier

    Oulah :/ 

  • Earest

    Est-ce qu’il est possible d’utiliser plusieurs fois un même layout dans le view pager en changeant dynamiquement les donnée en fonction de la page?