PagerAdapter Startposition

75

Ich verwende das folgende Beispiel, um meinen viewPager zu implementieren: http://code.google.com/p/viewpagerexample/issues/list

Das Problem bei diesem Beispiel ist, dass ich nicht herausfinden kann, wie ich meine Startposition einstellen soll. Die Standardstartposition ist 0. Grundsätzlich möchte ich nicht steuern können, ob links oder rechts eine Ansicht verfügbar ist.

Gibt es eine Möglichkeit, die aktuelle Position des Kontrollzentrums anzuzeigen? Gibt es einen besseren Weg, dies zu tun? ist es möglich, es kreisförmig zu machen?

Kirill Kulakov
quelle
Überprüfen Sie diese stackoverflow.com/a/53031553/4797289
Rasoul Miri

Antworten:

169

Ich habe einen Weg gefunden, seine Position festzulegen, was außerhalb der Klasse geschieht:

 awesomePager = (ViewPager) findViewById(R.id.awesomepager);
 awesomePager.setAdapter(awesomeAdapter);
 awesomePager.setCurrentItem(CurrentPosition);

und es kann begrenzt werden, indem die Anzahl der Elemente berechnet wird, in die ich hineinpassen möchte

Kirill Kulakov
quelle
4
Beachten Sie, dass Sie, wenn Sie awesomeAdaptervon einem Cursor / LoaderManager unterstützt werden, vorsichtig sein müssen, wann Sie setCurrentItemaufgerufen werden, um zu vermeiden, dass Sie den Fokus stehlen (zu spät) oder die Seite überhaupt nicht verschieben (zu früh) - siehe dies
rymo
hat bei mir nicht funktioniert, da meine anderen Fragmente zu diesem Zeitpunkt noch nicht fertig sind und ich eine Ausnahme habe, da meine App versucht hat, eine Variable aus dem currentPositionFragment zu verwenden, das noch nicht erstellt wurde
Zvi
Perfekt arbeiten. Das Festlegen des Ansichtspagers, wenn das Fragment bereit ist, funktioniert einwandfrei. Versuchen Sie dies, wenn das Fragment bereit ist und Sie über die aktuelle Position verfügen. Danke @Kirill
Naeem Ibrahim
Gibt es eine Möglichkeit, ViewPager am Ende zu starten ? Ich meine, wie in RecyclerView , wenn Sie einrichten new LinearLayoutManager(..., inverse=true). Was ich will ist: ViewPager springt sofort zum letzten Gegenstand, ohne Fragmente in der Mitte
auszulösen
@murt es ist ziemlich spät, aber falls jemand das gleiche Problem hat, falsewürde das Übergeben dem Benutzer nicht den Übergang zeigen, der passiert: viewPager.setCurrentItem(newPosition, false);
Yousef Gamal
20

Ich habe festgestellt, dass der Adapter seine Fragmente wiederverwendet, wenn Sie Aktivität (Orientierungsänderung) mit ViewPager mit FragmentStatePagerAdapter neu erstellen. Der Weg, dies zu stoppen, ist:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    if (viewPager != null) {
        // before screen rotation it's better to detach pagerAdapter from the ViewPager, so
        // pagerAdapter can remove all old fragments, so they're not reused after rotation.
        viewPager.setAdapter(null);
    }
    super.onSaveInstanceState(savedInstanceState);
}

Nach der Neuerstellung der Aktivität öffnet ViewPager jedoch immer zuerst Seite 0 und setCurrentItem (CurrentPosition). funktioniert nicht Das Problem wird behoben, indem die Seite nach der Verzögerung geändert wird:

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        viewPager.setCurrentItem(newPosition);
    }
}, 100);
Malachiasz
quelle
Die Verzögerung wird in der Tat nach einem benötigt recreate() call! :)
Anni
17

Um mit dem letzten Fragment zu beginnen, habe ich Folgendes getan:

PagerAdapter pagerAdapter = new PagerAdapter();
viewPager.setAdapter(pagerAdapter);
viewPager.setCurrentItem(pagerAdapter.getCount() - 1);
Helali
quelle
9

Ich bin auf ein Problem gestoßen. Wenn ich das aktuelle Element vor dem Einstellen des Adapters einstelle, ist das erste Element, das ich zurück bekomme, immer das an Position 0.

Stellen Sie sicher, dass Sie Folgendes tun:

awesomePager.setAdapter(awesomeAdapter);
awesomePager.setCurrentItem(CurrentPosition);

und nicht:

awesomePager.setCurrentItem(CurrentPosition);
awesomePager.setAdapter(awesomeAdapter);
DaveB
quelle
6

Ich habe ein Array mit einer Größe von mehr als 1000 und im dymanischen Viewpager war ich beim ersten Laden mit einem Linkswisch konfrontiert. Der folgende Code löste dies und führte zu einem reibungslosen Bildlauf:

@Override
onResume(){
   super.onResume();
   viewPager.setCurrentItem(newPosition);
}
Suhail k khan
quelle
4

Ich verwende 3 Fragmente und beim Starten meiner App wird standardmäßig das zweite ( mittlere ) Fragment angezeigt. Ich benutze nur die onResume-Funktion und alles funktioniert großartig.

@Override
protected void onResume() {
    super.onResume();
    m_viewPager.setCurrentItem(1);
}
Leebeedev
quelle
Arbeitete für mich im Gegensatz zur Verwendung eines Timers in onCreate. Vielen Dank!
Gmeister4
hat bei mir nicht funktioniert, da mein 2. Fragment zu diesem Zeitpunkt noch nicht fertig ist und ich eine Ausnahme habe, da meine App versucht hat, eine Variable aus dem 2. Fragment zu verwenden, die noch nicht erstellt wurde
Zvi
Wie könnten Sie also eine Variable verwenden, die noch nicht einmal erstellt wurde ?!
Leebeedev
2

Ich bin auf dasselbe Problem gestoßen. Bei der Initialisierung von ViewPager war die Indikatorposition 0. Dies hängt möglicherweise von der Berechnung des Pager-Inhalts ab. Ich benutze ViewTreeObserver wie unten.

mGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        mViewPager.setCurrentItem(newPosition);
        removeOnGlobalLayoutListener(mSlidingTabLayout.getViewTreeObserver(), mGlobalLayoutListener);
    }
};
mSlidingLayout.getViewTreeObserver().addOnGlobalLayoutListener(mGlobalLayoutListener);

und,

private void removeOnGlobalLayoutListener(ViewTreeObserver observer, ViewTreeObserver.OnGlobalLayoutListener listener) {
       if (observer == null) return;
       if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
               observer.removeGlobalOnLayoutListener(listener);
       } else {
               observer.removeOnGlobalLayoutListener(listener);
       }
} 

Auf diese Weise auch nie mit Zeiteinstellung der Verzögerung zu stören.

Chanzmao
quelle
2

Indem ich viewPager.setCurrentItem(newPosition);dem Benutzer den Übergang von der Startseite zur Seite zeige newPosition, um dies zu verhindern und den newPositiondirekt als Startpunkt anzuzeigen, habe ich falsedem zweiten Parameter Folgendes hinzugefügt :

int newPosition = pages.size()-1; // Get last page position

viewPager.setCurrentItem(newPosition, false); // 2nd parameter (false) stands for "smoothScroll"
Yousef Gamal
quelle
1
@Override
public Object instantiateItem(ViewGroup container, int position) {
    View currentPage = null;
    switch(position){
        case 0:
            currentPage = LayoutInflater.from(context).inflate(R.layout.page0, null)    
            break;
        case 1:
            currentPage = LayoutInflater.from(context).inflate(R.layout.page1, null)    
            ///////////// This page will be default ////////////////////
            ((ViewPager)container).setCurrentItem(position);
            ////////////////////////////////////////////////////////////
            break;
        case 2:
            currentPage = LayoutInflater.from(context).inflate(R.layout.page2, null)    
            break;
    return currentPage;
}
Kvant
quelle