64 votes

ViewPager comme une file d'attente circulaire / conditionnement

Je suis à l'aide d'un ViewPager avec l' FragmentStatePagerAdapter , pour permettre la navigation entre certains fragments.

Disons que j'ai trois fragments: A, B et C. Le ViewPager montre Un Fragment d'abord, et vous permet de naviguer vers du Fragment B en glissant de droite à gauche, puis à le Fragment C en glissant de nouveau. Cela permet à la suite de chemins de navigation: A <--> B <--> C.

Ce que je voudrais, c'est être capable de glisser de gauche à droite sur Fragment, et avoir la ViewPager montrer le Fragment C, c'est à dire pour qu'il se comporte comme une circulaire de la file d'attente et permettre l' ... --> C <--> A <--> B <--> C <--> A <-- ...

Je ne veux pas que les Fragments dupliqué dans d'autres positions (c'est à dire de se retrouver avec plus de trois instances).

Est-ce d'emballage fonctionnalité est possible avec un ViewPager?

49voto

antonyt Points 10649

J'ai mis en place un ViewPager/PagerAdapter qui peuvent permettre à des pseudo-infini de pagination comportement. Il fonctionne en spécifiant un très grand nombre que le nombre réel, mais les cartes à la portée réelle de l'ensemble de données/pageset. Il compense le début par un grand nombre également de sorte que vous pouvez immédiatement faire défiler à gauche de la première page.

Il ne fonctionne pas si bien, une fois que vous obtenez à 1 000 000 ème de la page (vous verrez bugs graphiques lors du défilement), mais ce n'est généralement pas un monde réel de cas d'utilisation. J'ai pu résoudre ce problème en réinitialisant le comptage d'un nombre inférieur de temps en temps, mais je vais laisser la façon dont il est pour l'instant.

L' InfinitePagerAdapter encapsule une existante ViewPager, et donc l'utilisation est assez transparent. L' InfiniteViewPager ne fait un peu de travail pour vous assurer que vous pouvez potentiellement faire défiler à gauche et à droite à plusieurs reprises.

https://github.com/antonyt/InfiniteViewPager

9voto

Graydyn Young Points 91

Une autre façon de le faire est d'ajouter une fausse copie du premier élément dans la vue de radiomessagerie à la fin de votre carte, et une fausse copie du dernier élément au début. Puis, quand vous regardez le premier/dernier élément dans la vue de radiomessagerie, de changer les pages, sans animation.

Donc, fondamentalement, la première/dernière éléments dans votre point de vue pager sont des faux, juste là pour produire de la bonne animation, et ensuite passer à la fin/au début. Exemple:

list.add(list.get(0)); //add the first item again as the last, to create the wrap effect
list.add(0, list.get(list.size()-2)); //insert a copy of the last item as the new first item, so we can scroll backwards too

viewPager.setAdapter(list);
viewPager.setCurrentItem(1, false); //default to the second element (because the first is now a fake)

viewPager.setOnPageChangeListener(new OnPageChangeListener() {
private void handleScrollState(final int state) {
        if (state == ViewPager.SCROLL_STATE_IDLE) { //this is triggered when the switch to a new page is complete
            final int lastPosition = viewPager.getAdapter().getCount() - 1;
            if (currentPosition == lastPosition) {
                viewPager.setCurrentItem(1, false); //false so we don't animate
            } else if (currentPosition == 0) {
                viewPager.setCurrentItem(lastPosition -1, false);
            }
        }

}

9voto

Bhasker Points 28

Maintenant vu cette question et a trouvé une solution. Solution De Lien

Apportez les modifications suivantes à votre onPageScrollStateChanged fonction. Considérez que vous avez 4 onglets.

private int previousState, currentState;

public void onPageScrollStateChanged(int state) {              

            int currentPage = viewPager.getCurrentItem();       //ViewPager Type
            if (currentPage == 3 || currentPage == 0){
                previousState = currentState;
                currentState = state;
                if (previousState == 1 && currentState == 0){

                    viewPager.setCurrentItem(currentPage == 0 ? 3 : 0);

                }

            }

        }

Si l' état variable est dans les onglets existants, sa valeur est 1.

Il devient 0 fois que vous essayez de naviguer avant votre premier onglet ou après votre dernier onglet. Donc, comparer les précédents et actuels membres, comme indiqué dans le code et vous avez terminé.

Voir onPageScrollStateChanged fonction ici.

Espérons que cela aide.

6voto

NPike Points 5187

Ce presque accomplit ce que antonyt veut, il ne vous laissera pas aller d'Un point a -> C bien. (Pas testé vigoureusement, mais semble fonctionner assez bien)

public class MyAdapter extends PagerAdapter {
    private List<Object> mItems;
    private int mFakeCount = 0;

    public MyAdapter(Context context, List<Object> items) {
        mItems = items;
        mFakeCount = mItems.size()+1;
    }

    @Override
    public int getCount() {
        return mFakeCount;
    }

    @Override
    public Object instantiateItem(View collection, int position) {
        // make the size larger, and change the position
        // to trick viewpager into paging forever
        if (position >= mItems.size()-1) {
            int newPosition = position%mItems.size();

            position = newPosition;
            mFakeCount++;
        }

        // do your layout inflating and what not here.
        // position will now refer to a correct index into your mItems list
        // even if the user has paged so many times that the view has wrapped
    }
}

-1voto

JasJar Points 183

Désolé pour le retard, mais j'ai vu les réponses et je j'ai été incapable de le retenir, eu de réponse trop :).

Sur votre carte, sur la méthode get comte, procédez comme suit:

 @Override
    public int getCount() {
        return myList.size() % Integer.MAX_VALUE; 
  }

Qui va travailler!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X