8

Sto provando ad avere lo stesso design view pager + tabs come PlayStore 5.1.x. Ecco il mio layout:Il primo frammento di ViewPager mostrato è sempre errato con FragmentStatePager

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_gravity="center_vertical|center_horizontal" 
    android:gravity="center_vertical|center_horizontal" 
    android:orientation="vertical"> 

    <com.astuetz.PagerSlidingTabStrip 
     android:id="@+id/tabs" 
     android:layout_width="match_parent" 
     android:layout_height="50dp" 
     android:background="@drawable/background_tabs" /> 

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

</LinearLayout> 

mio adattatore:

public class MainPagerAdapter extends FragmentStatePagerAdapter { 

    private ArrayList<FakeFragment> fragments; 

    public MainPagerAdapter(FragmentManager fm) { 
     super(fm); 
     // TODO Auto-generated constructor stub 
     fragments = new ArrayList<FakeFragment>(); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     // TODO Auto-generated method stub  
     if(position < getCount()) { 
      FakeFragment fragment = FakeFragment.newInstance(position); 
      fragments.add(fragment); 
     } 
     return fragments.get(position); 
    } 

    @Override 
    public int getCount() { 
     // TODO Auto-generated method stub 
     return Category.values().length; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     // TODO Auto-generated method stub 
     return Category.values()[position].getTitle(); 
    } 

    @Override 
    public int getItemPosition(Object object) { 
     // TODO Auto-generated method stub 
     return POSITION_NONE; 
    } 
} 

mie schede e cercapersone stanno dimostrando correttamente! ma ho notato che il primo frammento mostrato nella visualizzazione del cercapersone è sempre lo stesso del secondo. Quindi quando faccio scorrere una volta, due volte e torno alla prima pagina, scopro che il frammento corretto ora viene mostrato !!

Non riesco a capire perché questo comportamento, per favore ho bisogno di alcune spiegazioni.

SOLUZIONE

Il problema era dovuto alla mia definizione FakeFragment.newInstance() metodo.

private static int position; 

public static FakeFragment newInstance(int position) { 
    // TODO Auto-generated method stub 
    FakeFragment.position = position; 
    return new FakeFragment(); 
} 

ho cambiato utilizzando un setArguments(args) al mio FakeFragment esempio, e quindi recuperare in onCreate metodo. Ora tutto funziona bene!

Qualcuno può spiegarmi perché ??

Penso che, in questo modo, il valore della posizione dipenderà interamente dal ciclo di vita del frammento, quindi sarà sempre la posizione prevista, Giusto ??

+1

Sbarazzarsi di 'private ArrayList frammenti' e avere semplicemente' getItem() 'restituisce una nuova istanza del frammento. Il ** punto completo e completo * dietro a 'FragmentStatePagerAdapter' è ** NON ** da conservare su tutti i frammenti in memoria. Se questo è quello che vuoi, allora sbarazzarsi di 'ArrayList ' e cambiare l'adattatore in "FragmentPagerAdapter', piuttosto che in FragmentStatePagerAdapter'. Inoltre, sbarazzarsi di 'getItemPosition()'. [FWIW, qui ci sono una serie di esempi di applicazioni di utilizzo di ViewPager] (https://github.com/commonsguy/cw-omnibus/tree/master/ViewPager). – CommonsWare

+0

Grazie a @CommonsWare. Ho scelto 'FragmentStatePagerAdapter' perché ho 6 pagine nel mio' ViewPager', in ogni pagina ho un 'GridView' con molti dati da mostrare.Ecco perché volevo usare questo tipo di adattatore, ricreare una pagina o aggiornare il suo contenuto solo se necessario. Ecco perché ho anche provato a sovrascrivere 'getItemPosition'. Questo è possibile con 'FragmentPagerAdapter'? grazie ancora per aver risposto! –

+1

L'implementazione dovrebbe funzionare correttamente in entrambi i casi, l'unica cosa diversa potrebbe essere la velocità. Se il caricamento dei dati è costoso e non è necessario farlo ogni volta che si usa 'FragmentStatePagerAdapter', usare' Fragment.onSaveInstanceState' per memorizzare il set di dati caricato. –

risposta

6

1) Non implementare getItemPosition(Object) se non lo si gestisce. Non sei tenuto a implementarlo e potresti rompere alcune altre funzionalità implementandolo in modo errato.

2) Il punto di getItem(int) è quello di restituire un nuovo frammento. Elimina l'array di frammenti perché non ha senso.

3) Rendere la classe di advisor static (Promuove la riusabilità, l'adattatore non deve dipendere dalla classe genitore per ottenere il suo set di dati, giusto?) E passare il Category s come parametro costruttore. Memorizzalo in una variabile e crea nuovi frammenti in base a questo set di dati. Probabilmente vorrai anche passare un Category[position] come parametro al costruttore di frammenti invece di solo position.

+0

Grazie a @Eugen, si può dare ulteriori informazioni sul 3): 'l'adattatore non dovrebbe dipendere dalla classe genitore per ottenere il suo set di dati? –

+1

È consigliabile dichiarare 'static' le classi annidate. Ciò rimuove la loro connessione implicita alla loro classe genitore (si noti che non è possibile accedere alle variabili di campo del genitore). In alcuni casi ciò potrebbe impedire perdite di memoria. Usa solo classi interne non statiche se sai cosa stai facendo. Prova a leggere [questo] (http://stackoverflow.com/a/70358/2444099). –

+0

Ho accettato la tua risposta e ti ho dato i premi in quanto la tua risposta e il tuo commento mi hanno portato ad altre informazioni utili. –

3

L'implementazione getItem() è il problema.

@Override 
public Fragment getItem(final int position) { 
    return FakeFragment.newInstance(position); 
} 

Non si dovrebbe mai modificare i dati in questo metodo get: non chiamatelo add() in esso. Dubito che il Adapter sappia a questo punto che hai aggiunto un elemento.

Problemi correlati