2012-08-17 8 views
13

Ich benutze einen PagerAdapter. Ich habe viele Elemente, deshalb lade ich nicht alle Elemente gleichzeitig. Ich lade den Adapter neu, ich ändere die alten Elemente um die neuen Elemente. Zum Beispiel habe ich 4 Elemente, wenn ich beim letzten Element angekommen bin, lade ich die Elemente neu und rufe setCurentItem (1) auf, um den Viewpager in Position 1 anzeigen zu können. Ich habe viele Tests gemacht. Ich habe:setCurrentItem in ViewPager Scrollen nicht sofort in der richtigen Position

viewPager.setCurrentItem(1,false); //But not scroll, put drastically the new page. 
viewPager.setCurrentItem(1); 

ich versucht habe onPageScrollStateChanged (int arg0) zu ändern, ich habe nur drei Ansichten und ubicate immer in der Mitte.

if (arg0 == ViewPager.SCROLL_STATE_DRAGGING) { 
    if(focusedPage==2) { 
     //Modify adapter 
     viewPager.setCurrentItem(1,false); 

    }else if(focusedPage==0){ 
     //Modify adapter 
     viewPager.setCurrentItem(1,false); 
    } 

Und ich habe tryed onPageSelected (int arg0)

focusedPage=arg0; 

Mit diesem letzten Beispiel habe ich bewegen die Ansichten sofort aber immer es befindet sich auf der letzten Seite zu ändern. Jeder weiß, wie ich rutschen kann.

Danke

Antwort

43

Kann ich mehr über die Hintergründe wissen, was Sie erreichen wollen?

Wie auch immer, von dem, was ich verstehen kann, versuchen Sie, eine "unendliche" ViewPager gehen von der letzten auf die erste und umgekehrt (bitte korrigieren Sie mich, wenn ich falsch liege). Und Sie wollen Ihre ViewPager auf die erste Seite gehen, aber scrollen - nicht nur aus dem Nichts erscheinen.

Nun, wenn Sie die glatte Bildlauf (der zweite Parameter) deaktivieren, wird es direkt auf die Seite ohne Scroll-Bewegung gehen (und wird nicht auf die anderen Seiten auf dem Weg "ändern"), und wenn Sie aktivieren die sanfte Bildlauffunktion, dann wird es durch alle Ansichten gehen, so dass Sie sehen werden, wie es nicht die nächste, sondern die erste war.

/*No swipe animation, and no onPageChanged for the page in the middle*/ 
    mPager.setCurrentItem(1, false); 

    /*The same as if you do not add the second parameter*/ 
    mPager.setCurrentItem(1, true); 

    /*Your ViewPager scrolls through all the needed views until it arrives at that view.*/ 
    mPager.setCurrentItem(1); 

Was ich Sie mit diesem Hintergrund empfehlen kann ist, dass Sie versuchen können, „Dummy“ Blick an den Positionen 0 und „letzte“ und die Ansicht in Position 0 hinzufügen, würde zuletzt die gleichen wie Position“sein - 1 "und die" letzte "Ansicht wäre die gleiche wie die Position" 1 ". Sie werden also alles normal machen, mit der Ausnahme, dass Sie auf dem OnPageChangeListener prüfen, ob die aktuelle Seite die Position "0" oder "last" hat. Wenn dies der Fall ist, rufen Sie setCurrentItem ("1", false) oder setCurrentItem ("last - 1 ", falsch) abhängig davon, in welcher Position Sie sich gerade befinden. Auf diese Weise behalten Sie den "Seitenwechsel" -Effekt bei, während Sie das erreichen, was Sie wollen.

Ich hoffe, das kann Ihnen bei Ihrem Problem helfen.

HINWEIS: Es kann eine laggy ändern, nachdem Sie an der neuen Position ankommen, weil sie den Blick für die aktuelle, nächste und letzte Ansichten laden müssen (oder, wenn Sie auf 4.0+ sind dann wird es lade nur die aktuelle Position).

UPDATE:

Wenn Sie den Inhalt der Liste/Array ändern, den Inhalt des ViewPager bestimmt, müssen Sie rufen:

ViewPager mPager = new ViewPager(); 
mPager.getAdapter().notifyDataSetChanged(); //This notify that you need to recreate the views 

/*This is if you want to change the data and then go to a specific position 
If you do not do this you will have a very Buggy Behavior*/ 
new Handler().post(new Runnable() { 
@Override 
public void run() { 
    mPager.setCurrentItem(2); //Where "2" is the position you want to go 
    } 
}); 

UPDATE 2:

Warum fügst du nicht alle deine Elemente der ViewPager hinzu? Die ViewPager hat bereits eine Optimierung für die Behandlung dieser Fälle, in meinem Fall habe ich eine Menge Elemente und es funktioniert wie ein Charme.

Eine andere Sache, in Ihrem Code sehe ich Sie wechseln auf die mittlere Seite jedes Mal, wenn eine Seite "Abrechnung". Aber dann zeigst du wirklich nie die rechte und linke Ansicht, also warum hast du sie?

Zuletzt, wenn Sie Ihre Datenmenge ändern, müssen Sie die "notifyDataSetChanged" -Methode, die ich oben erwähnt, aufrufen, und dann rufen Sie die "setCurrentItem" -Methode in einem Handler. Wenn Sie dies nicht tun, wird Ihre App nicht wie erwartet funktionieren.

UPDATE 3:

Nun, das einzige, was ich empfehlen kann, ist eine Liste mit dem Sie die neuen Objekte hinzugefügt halten, die Sie aus der Datenbank holen, und dann solange Sie Einfügen von Objekten auf die halten Ende der Liste gibt es kein Problem. Wenn Sie Objekte in der Mitte oder am Anfang hinzufügen möchten, müssen Sie das notifyDataSetChanged aufrufen, aber das wird langsam sein, da es die Ansichten erneut generieren wird. Wir machen es so und es funktioniert perfekt und wir laden sogar die Informationen von einem Server herunter, die Daten sind nicht lokal (und eigentlich fügen wir dem Ende und dem Anfang der Liste Informationen hinzu).

Wenn Sie weitere Fragen dazu haben, zögern Sie nicht zu fragen.

UPDATE 4:

Nur falls jemand tatsächlich für eine kreisförmige ViewPager suchen, habe ich eine proof of concept code, die Sie wiederverwenden. Es funktioniert ohne Probleme und ich habe es mit komplexen Ansichten verwendet und es gibt immer noch keine Verzögerung.

+0

Dank @Jorge Aguilar. Ich habe deine Idee benutzt, aber ich habe einige Dinge geändert. Ich habe eine "Dummy" -Ansicht hinzugefügt, aber ich habe verschiedene Ansichten eingestellt. Zum Beispiel, wenn ich a, b, c, d, e. Ich habe das erste Mal gesagt: a, a, a. Und setCurrentItem (1, falsch). Wenn der Benutzer zum nächsten Viewpager blättert, ist es: a, b, c und setCurrentItem (1, false), ... In onPageScrollStateChanged habe ich diesen Code eingefügt. Aber jetzt habe ich ein kleines Problem. Wenn der Benutzer schnell scrollen möchte, kann er dies nicht tun, weil Verzögerungen auftreten. Hast du irgendeine Idee? Danke – MARM

+0

Können Sie Ihre Frage redigieren oder eine neue Frage mit mehr Details über das neue Problem stellen, um Sie besser zu verstehen und Ihnen besser zu helfen. Ich habe die Antwort bereits aktualisiert, um einige wertvolle Dinge hinzuzufügen. Und wenn Sie dies als Antwort für jeden eingeben können, können Sie wissen, dass es gelöst wurde. –

+0

Ich habe meine Frage bearbeitet. – MARM

1

Es funktioniert nicht ohne postDelayed, versuchen Sie mit diesem Code:

viewPager.postDelayed(new Runnable() 
{ 
    @Override 
    public void run() 
    { 
     viewPager.setCurrentItem(num, true); 
    } 
}, 100); 
Verwandte Themen