Recherche…


Introduction

ViewPager est un gestionnaire de mise en page qui permet à l'utilisateur de parcourir les pages de données à gauche et à droite. Il est le plus souvent utilisé conjointement avec Fragment, qui est un moyen pratique de fournir et de gérer le cycle de vie de chaque page.

Remarques

Une chose importante à noter à propos de l'utilisation de ViewPager est qu'il existe deux versions différentes de FragmentPagerAdapter et de FragmentStatePagerAdapter .

Si vous utilisez des fragments natifs android.app.Fragment avec un FragmentPagerAdapter ou un FragmentStatePagerAdapter, vous devez utiliser les versions de la bibliothèque de support v13 de l'adaptateur, à savoir android.support.v13.app.FragmentStatePagerAdapter .

Si vous utilisez la bibliothèque de support android.support.v4.app.Fragment avec un fragment FragmentPagerAdapter ou FragmentStatePagerAdapter, vous devez utiliser les versions de bibliothèque de support v4 de l'adaptateur, à savoir android.support.v4.app.FragmentStatePagerAdapter .

Utilisation de base de ViewPager avec des fragments

Un ViewPager permet d'afficher plusieurs fragments dans une activité qui peut être parcourue en basculant à gauche ou à droite. Un ViewPager doit être alimenté par Views ou Fragments à l'aide d'un PagerAdapter .

Il existe cependant deux implémentations plus spécifiques que vous trouverez plus utiles dans le cas de l'utilisation de Fragments, à savoir FragmentPagerAdapter et FragmentStatePagerAdapter . Lorsqu'un fragment doit être instancié pour la première fois, getItem(position) sera appelé pour chaque position nécessitant une instanciation. La méthode getCount() renvoie le nombre total de pages afin que ViewPager sache combien de fragments doivent être affichés.

FragmentPagerAdapter et FragmentStatePagerAdapter conservent tous deux un cache des fragments que ViewPager devra afficher. Par défaut, ViewPager essaiera de stocker un maximum de 3 fragments correspondant au fragment actuellement visible, et ceux situés à droite et à gauche. Aussi FragmentStatePagerAdapter gardera l'état de chacun de vos fragments.

Sachez que les deux implémentations supposent que vos fragments conserveront leurs positions, donc si vous conservez une liste des fragments au lieu d'en avoir un nombre statique comme vous pouvez le voir dans la méthode getItem() , vous devrez créer une sous-classe de PagerAdapter et remplacer au moins instantiateItem() , destroyItem() et getItemPosition() méthodes.

Ajoutez simplement un ViewPager dans votre mise en page comme décrit dans l' exemple de base :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout> 
    <android.support.v4.view.ViewPager
        android:id="@+id/vpPager"> 
    </android.support.v4.view.ViewPager>
</LinearLayout>

Définissez ensuite l'adaptateur qui déterminera le nombre de pages existantes et le fragment à afficher pour chaque page de l'adaptateur.

public class MyViewPagerActivity extends AppCompatActivity {
    private static final String TAG = MyViewPagerActivity.class.getName();

    private MyPagerAdapter mFragmentAdapter;
    private ViewPager mViewPager;

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

        //Apply the Adapter
        mFragmentAdapter = new MyPagerAdapter(getSupportFragmentManager());    
        mViewPager = (ViewPager) findViewById(R.id.view_pager);
        mViewPager.setAdapter(mFragmentAdapter);
    }

    private class MyPagerAdapter extends FragmentPagerAdapter{

        public MyPagerAdapter(FragmentManager supportFragmentManager) {
            super(supportFragmentManager);
        }

        // Returns the fragment to display for that page
        @Override
        public Fragment getItem(int position) {
            switch(position) {
                case 0:
                    return new Fragment1();

                case 1:
                    return new Fragment2();

                case 2:
                    return new Fragment3();

                default:
                    return null;
            }
        }

        // Returns total number of pages    
        @Override
        public int getCount() {
            return 3;
        }

    }
}
3.2.x

Si vous utilisez android.app.Fragment vous devez ajouter cette dépendance:

compile 'com.android.support:support-v13:25.3.1'

Si vous utilisez android.support.v4.app.Fragment vous devez ajouter cette dépendance:

compile 'com.android.support:support-fragment:25.3.1'

ViewPager avec TabLayout

Un TabLayout peut être utilisé pour faciliter la navigation.
Vous pouvez définir les onglets pour chaque fragment de votre adaptateur à l'aide de la méthode TabLayout.newTab() , mais il existe une autre méthode plus pratique et plus simple pour cette tâche: TabLayout.setupWithViewPager() .

Cette méthode se synchronise en créant et en supprimant des onglets en fonction du contenu de l'adaptateur associé à votre ViewPager chaque fois que vous l'appelez.
En outre, il va définir un rappel chaque fois que l'utilisateur retourne la page, l'onglet correspondant sera sélectionné.

Il suffit de définir une mise en page

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout>

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        app:tabMode="scrollable" />

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight="1" />

</LinearLayout>

Ensuite, implémentez FragmentPagerAdapter et appliquez-le à ViewPager :

public class MyViewPagerActivity extends AppCompatActivity {
    private static final String TAG = MyViewPagerActivity.class.getName();

    private MyPagerAdapter mFragmentAdapter;
    private ViewPager mViewPager;
    private TabLayout mTabLayout;

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

        // Get the ViewPager and apply the PagerAdapter
        mFragmentAdapter = new MyPagerAdapter(getSupportFragmentManager());    
        mViewPager = (ViewPager) findViewById(R.id.view_pager);
        mViewPager.setAdapter(mFragmentAdapter);

        // link the tabLayout and the viewpager together
        mTabLayout = (TabLayout) findViewById(R.id.tab_layout);
        mTabLayout.setupWithViewPager(mViewPager);
    }

    private class MyPagerAdapter extends FragmentPagerAdapter{

        public MyPagerAdapter(FragmentManager supportFragmentManager) {
            super(supportFragmentManager);
        }

         // Returns the fragment to display for that page
        @Override
        public Fragment getItem(int position) {
            switch(position) {
                case 0:
                    return new Fragment1();

                case 1:
                    return new Fragment2();

                case 2:
                    return new Fragment3();

                default:
                    return null;
            }
        }
        
        // Will be displayed as the tab's label
        @Override
        public CharSequence getPageTitle(int position) {
            switch(position) {
                case 0:
                    return "Fragment 1 title";

                case 1:
                    return "Fragment 2 title";

                case 2:
                    return "Fragment 3 title";

                default:
                    return null;
            }
        }

        // Returns total number of pages 
        @Override
        public int getCount() {
            return 3;
        }

    }
}

ViewPager avec PreférenceFragment

Jusqu'à récemment, l'utilisation de android.support.v4.app.FragmentPagerAdapter empêchait l'utilisation de PreferenceFragment comme l'un des fragments utilisés dans FragmentPagerAdapter.

Les dernières versions de la bibliothèque de support v7 incluent désormais la classe PreferenceFragmentCompat , qui fonctionnera avec un ViewPager et la version v4 de FragmentPagerAdapter.

Exemple de fragment qui étend PreferenceFragmentCompat :

import android.os.Bundle; 
import android.support.v7.preference.PreferenceFragmentCompat; 
import android.view.View; 
 
public class MySettingsPrefFragment extends PreferenceFragmentCompat { 
  
    public MySettingsPrefFragment() { 
        // Required empty public constructor 
    } 
 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        addPreferencesFromResource(R.xml.fragment_settings_pref); 
    } 
 
    @Override 
    public void onCreatePreferences(Bundle bundle, String s) { 
 
    } 
}

Vous pouvez maintenant utiliser ce fragment dans une sous-classe android.support.v4.app.FragmentPagerAdapter :

private class PagerAdapterWithSettings extends FragmentPagerAdapter {

    public PagerAdapterWithSettings(FragmentManager supportFragmentManager) {
        super(supportFragmentManager);
    }

    @Override
    public Fragment getItem(int position) {
        switch(position) {
            case 0:
                return new FragmentOne();

            case 1:
                return new FragmentTwo();

            case 2:
                return new MySettingsPrefFragment();

            default:
                return null;
        }
    }
    
    // .......

}

Ajouter un ViewPager

Assurez-vous que la dépendance suivante est ajoutée au fichier build.gradle votre application sous les dépendances:

compile 'com.android.support:support-core-ui:25.3.0'

Ajoutez ensuite le ViewPager à votre disposition d'activité:

<android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

Définissez ensuite votre PagerAdapter :

public class MyPagerAdapter extends PagerAdapter {

    private Context mContext;

    public CustomPagerAdapter(Context context) {
        mContext = context;
    }

    @Override
    public Object instantiateItem(ViewGroup collection, int position) {
 
        // Create the page for the given position. For example:
        LayoutInflater inflater = LayoutInflater.from(mContext);
        ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.xxxx, collection, false);
        collection.addView(layout);
        return layout;
    }

    @Override
    public void destroyItem(ViewGroup collection, int position, Object view) {
        // Remove a page for the given position. For example:
        collection.removeView((View) view);
    }

    @Override
    public int getCount() {
        //Return the number of views available.
        return numberOfPages;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        // Determines whether a page View is associated with a specific key object
        // as returned by instantiateItem(ViewGroup, int). For example:
        return view == object;
    }    
}

Enfin, configurez le ViewPager dans votre activité:

public class MainActivity extends AppCompatActivity {

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

        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        viewPager.setAdapter(new MyPagerAdapter(this));
    }
}

ViewPager avec un indicateur de points

ViewPager avec un indicateur de points

Tout ce dont nous avons besoin sont: ViewPager , TabLayout et 2 tirables pour les points sélectionnés et par défaut.

Tout d'abord, nous devons ajouter TabLayout à notre disposition d'écran et le connecter à ViewPager . Nous pouvons le faire de deux manières:


Onglet imbriquéMise en forme dans ViewPager

<android.support.v4.view.ViewPager
    android:id="@+id/photos_viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.TabLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</android.support.v4.view.ViewPager>

Dans ce cas, TabLayout sera automatiquement connecté à ViewPager , mais TabLayout sera à côté de ViewPager , pas sur lui.


TabLayout séparé

<android.support.v4.view.ViewPager
    android:id="@+id/photos_viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<android.support.design.widget.TabLayout
    android:id="@+id/tab_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

Dans ce cas, nous pouvons mettre TabLayout n'importe où, mais nous devons connecter TabLayout avec ViewPager programmation

ViewPager pager = (ViewPager) view.findViewById(R.id.photos_viewpager);
PagerAdapter adapter = new PhotosAdapter(getChildFragmentManager(), photosUrl);
pager.setAdapter(adapter);

TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(pager, true);

Une fois que nous avons créé notre mise en page, nous devons préparer nos points. Nous créons donc trois fichiers: selected_dot.xml , default_dot.xml et tab_selector.xml .


selected_dot.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:innerRadius="0dp"
            android:shape="ring"
            android:thickness="8dp"
            android:useLevel="false">
            <solid android:color="@color/colorAccent"/>
        </shape>    
    </item>
</layer-list>

default_dot.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:innerRadius="0dp"
            android:shape="ring"
            android:thickness="8dp"
            android:useLevel="false">
            <solid android:color="@android:color/darker_gray"/>
        </shape>    
    </item>
</layer-list>

tab_selector.xml

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

    <item android:drawable="@drawable/selected_dot"
          android:state_selected="true"/>

    <item android:drawable="@drawable/default_dot"/>
</selector>

Maintenant, nous devons ajouter seulement 3 lignes de code à TabLayout dans notre présentation XML et vous avez terminé.

app:tabBackground="@drawable/tab_selector"
app:tabGravity="center"
app:tabIndicatorHeight="0dp"

Configuration de OnPageChangeListener

Si vous devez écouter les modifications apportées à la page sélectionnée, vous pouvez implémenter l'écouteur ViewPager.OnPageChangeListener sur ViewPager:

viewPager.addOnPageChangeListener(new OnPageChangeListener() {
    
    // This method will be invoked when a new page becomes selected. Animation is not necessarily complete.
    @Override
    public void onPageSelected(int position) {
         // Your code
    }
    
    // This method will be invoked when the current page is scrolled, either as part of 
    // a programmatically initiated smooth scroll or a user initiated touch scroll.
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
         // Your code
    }
    
    // Called when the scroll state changes. Useful for discovering when the user begins
    // dragging, when the pager is automatically settling to the current page, 
    // or when it is fully stopped/idle.
    @Override
    public void onPageScrollStateChanged(int state) {
         // Your code
    }
});


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow