Obtenir la position actuelle d'un ViewPager

84

Je sais qu'avec le widget Galerie, j'ai pu utiliser getSelectedItemPosition (); pour récupérer la position actuelle, mais il ne semble pas que ViewPager l'ait.

Je sais que je peux configurer un auditeur et récupérer la position lorsque la page est commutée. Mais je veux la position de vue actuelle.

Adam
la source

Réponses:

94

Créez un auditeur et définissez-le sur votre viewpager:

/**
 * Get the current view position from the ViewPager by
 * extending SimpleOnPageChangeListener class and adding your method
 */
public class DetailOnPageChangeListener extends ViewPager.SimpleOnPageChangeListener {

    private int currentPage;

    @Override
    public void onPageSelected(int position) {
        currentPage = position;
    }

    public final int getCurrentPage() {
        return currentPage;
    }
}
androidu
la source
4
Soyez juste conscient lorsque vous utilisez ceci: getCurrentPage () retournera toujours 0 lorsque la vue n'a jamais été modifiée. Pour une raison quelconque, si vous entrez dans le ViewPager sur une vue autre que la première vue, la valeur à laquelle vous vous attendez ne devrait pas être 0 ... Je viens de rencontrer un problème avec cela car je n'entrais pas toujours la vue sur la première vue.
Brandon Romano
1
@Adam pouvez-vous me dire comment appeler cette fonction getCurrentPage
user3233280
C'est très simple. Merci androidu.
whdals0
193

Vous pouvez utiliser:

mViewPager.getCurrentItem()
Terry
la source
Il n'y a pas de méthode getCurrentItem dans ViewPager
Dmitry Guselnikov
3
Désolé je me suis trompé. Je viens de mettre à jour ma bibliothèque de support et cette méthode existe dans une nouvelle version
Dmitry Guselnikov
4

Mise à jour 2019

Vous pouvez maintenant définir addOnPageChangeListenersur Afficher le téléavertisseur pour observer le changement de position de la page.

Puisque vous vouliez configurer un auditeur et récupérer la position lorsque la page est commutée

mViewPager.addOnPageChangeListener(object : OnPageChangeListener {
            override fun onPageScrollStateChanged(state: Int) {}
            override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}

            override fun onPageSelected(position: Int) {
                pagePosition.setText("" + position + "/" + galleryAdapter!!.count)
            }
        })
Hitesh Sahu
la source
-1

Je vous dis maintenant que c'est un hack, il n'y a donc aucune raison de voter pour cette raison. Cela signifie que cela vous sera utile ou non. Dans tous les cas, la description ci-dessous fournira un aperçu et sera utile à la communauté. En outre, cette solution convient aux API plus anciennes qui n'en ont pas ViewPager.getCurrentItem().


Tout d'abord, un peu d'informations. Si vous parcourez tous les enfants d'un ViewPager avec ViewPager.getChildAt(x);et imprimez avec toString()(ou getLeft()) chaque vue enfant (une page), puis faites cela chaque fois que vous changez de page, vous remarquerez que les enfants ne seront pas dans l'ordre logique dans lequel ils sont affichés lorsque vous commencez à revenir en arrière (pagination au début). Apparemment, cela supprimera l'enfant inutile du tableau, puis ajoutera l'enfant le plus récent au tableau. Ainsi, par exemple, disons que vous regardez la page 2 puis changé en page 3, votre liste d'enfants sera dans cet ordre page 2, page 3, page 4signifiant qui ViewPager.getChildAt(1);renverra la page courante. Mais, si vous revenez ensuite à la page 2 (à partir de la page 3), votre liste d'enfants sera dans cet ordre, ce page 2, page 3, page 1qui signifie queViewPager.getChildAt(1);ne renvoie pas la page actuelle. Je n'ai pas encore été en mesure de trouver une logique simple pour éliminer la page actuelle en utilisant ces informations. Parce que l'ordre des pages dans le tableau derrière getChildAtest dans un ordre arbitraire basé sur la façon dont l'utilisateur a paginé.

Cela étant dit, j'ai développé une solution de contournement. Je n'ai aucune idée si cette fonction fonctionnera dans tous les environnements, mais cela fonctionne pour mon projet actuel. Je suppose que si ce n'est pas le cas pour vous, c'est un problème de niveau d'API différent. Mais je ne soupçonne en fait aucun problème pour d'autres environnements.

Maintenant, sur la viande. Ce que j'ai remarqué, c'est que le résultat ViewPager.getChildAt(x).getLeft()aura un type de coordonnée horizontale de pixel par rapport au parent. J'ai donc utilisé ces informations pour éliminer quelle vue est la vue actuelle.

private int getCurrentPageIndex(ViewPager vp){
    int first,second,id1,id2,left;
    id1 = first = second = 99999999;
    View v;
    for ( int i = 0, k = vp.getChildCount() ; i < k ; ++i ) {
        left = vp.getChildAt(i).getLeft();
        if ( left < second ) {
            if ( left < first ) {
                second = first;
                id2 = id1;
                first = left;
                id1 = i;
            } else {
                second = left;
                id2 = i;
            }
        }
    }
    return id2;
}

Cette fonction est probablement un hack discutable car elle repose sur la valeur de getLeft()pour tout comprendre. Mais, j'attrape la coordonnée gauche de chaque enfant. Je compare ensuite cela aux autres valeurs et stocke les première et deuxième pages, renvoyant la deuxième page (page actuelle) hors de la fonction. Cela semble fonctionner à merveille.

Pourquoi (pourriez-vous demander) n'ai-je pas simplement utilisé onClickListenterou n'importe quelle solution? Eh bien, j'étais sacrément déterminé qu'il y avait un moyen simple de le faire sans avoir à inclure des auditeurs, d'autres classes, une concentration non concluante et d'autres ballonnements. Malheureusement, cette solution n'est pas tout à fait simple. Mais, cela supprime le ballonnement, les autres classes et les auditeurs. Si je peux trouver un moyen plus simple, je réécrirai cette fonction. Ou peut-être que cela permettra à quelqu'un d'autre d'avoir une révélation.

Pimp Trizkit
la source
1
tu m'as sauvé! avait un insecte hideux. ne pouvait pas trouver ce qui n'allait pas. Vous, monsieur, méritez un bazillion de votes positifs!
Nursultan Talapbekov
Merci messieurs! Je suppose que la communauté ne partage pas votre enthousiasme.
Pimp Trizkit