8

Sto provando a creare un ViewPager che contiene 5 frammenti. 5 frammenti "contenitore", quindi ognuno di essi contiene 2 frammenti. I primi 4 frammenti hanno lo stesso layout e appartengono alla stessa classe. Il quinto è di un'altra classe e non c'è problema con quello.ViewPager con istanze di frammenti multipli della stessa classe

Il problema è che quando si avvia l'attività, sembra funzionare solo 1 frammento (quello in posizione 0 in viewPager). Ho provato a restituire il nuovo Fragment() nella posizione 0 nel mio PagerAdapter, ma quando lo faccio è il secondo frammento che funziona. (Lavorando intendo la visualizzazione della lista di sinistra, non ho ancora preso cura dei dettagli frammento a destra)

Ecco il codice

CustomPagerAdapter.java

public class CustomPagerAdapter extends FragmentPagerAdapter{ 

public CustomPagerAdapter(FragmentManager fm) { 
    super(fm); 
} 
public CustomPagerAdapter(FragmentManager fm, Context context) { 
    super(fm); 

} 

@Override 
public Fragment getItem(int pos) { 

    if(pos == 4) 
     return new OtherContainerFragment(); 
    else 
     return new ContainerFragment(pos); 

} 

@Override 
public int getCount() { 

    return 5; 
} 

ContainerFragment .java

public class ContainerFragment extends Fragment { 
private int CONTAINER_TYPE; 

public ContainerFragment(){ 

} 

public ContainerFragment(int type){ 
    CONTAINER_TYPE = type; 
} 



@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
} 


@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    return inflater.inflate(R.layout.fragment_container, container, false); 
} 

@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 


    FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction(); 
    CustomListFragment frag = new CustomListFragment(CONTAINER_TYPE); 

    ft.replace(R.id.replaceable_list, frag); 

    ft.commit(); 

CustomListFragment.java

public class CustomListFragment extends SuperCustomListFragment{ 

private ArrayList<Model> mModels; 
private int TYPE; 


public CustomListFragment(){ 

} 

public CustomListFragment(int type){ 
    TYPE = type; 
} 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
} 


@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    return super.onCreateView(inflater, container, savedInstanceState); 
} 


@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 

    mModels = new ArrayList<Model>(); 


    if(TYPE == AppConstants.FRAGMENT_TYPE_JOURNAL){ 
     mAdapter = AppUtils.getJournalListAdapter(getActivity(), mModels); 
     new syncPapers().execute(); 
    }else if(TYPE == AppConstants.FRAGMENT_TYPE_MOVIES){ 
     mAdapter = AppUtils.getMoviesListAdapter(getActivity(), mModels); 
     new syncMovies().execute(); 
    } 


    if(mAdapter != null) 
     mListView.setAdapter(mAdapter); //mListView is defined in the superClass 

Qui ci sono le costanti che uso:

public class AppConstants { 


public static final int FRAGMENT_TYPE_AGENDA = 0; //so Fragment at position 0 should be of type agenda 
public static final int FRAGMENT_TYPE_NEWS = 1; // position 1 should be of type news 
public static final int FRAGMENT_TYPE_MOVIES = 2; // ... 
public static final int FRAGMENT_TYPE_JOURNAL = 3; // ... 

} 

E l'XML per il contenitore:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="horizontal" > 

<LinearLayout 
    android:id="@+id/replaceable_list" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 
</LinearLayout> 

<LinearLayout 
    android:id="@+id/replaceable_details" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_weight="1" 
    android:background="@drawable/background" > 
</LinearLayout> 

</LinearLayout> 

quindi questo codice non funziona, sembra che la lista nel frammento sinistra il contenitore viene sostituito in ogni frammento e solo il frammento nella posizione 0 lo visualizza. (Attualmente visualizza l'elenco con l'adattatore di tipo "JOURNAL", ma dovrebbe visualizzare l'elenco di tipo "AGENDA".

------------------- - * MA ... * --------------------

Se creo differenti fragment_container di layout-files, e scrivere! Condizioni IF in onCreateView e onViewCreated in ContainerFragment.java, tutto funziona correttamente Quindi:

ContainerFragme nt.java

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle  savedInstanceState) { 
if(CONTAINER_TYPE == AppConstants.FRAGMENT_TYPE_JOURNAL) 
    return inflater.inflate(R.layout.fragment_container_journal, container, false); 
else if(CONTAINER_TYPE == AppConstants.FRAGMENT_TYPE_MOVIES) 
    return inflater.inflater(R.layout.fragment_container_movies, container, false); 
else 
    return super.onCreateView(LayoutInflater inflater, ViewGroup container, Bundle  savedInstanceState); 
} 


@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 


    FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction(); 
    CustomListFragment frag = new CustomListFragment(CONTAINER_TYPE); 

    if(CONTAINER_TYPE == AppConstants.FRAGMENT_TYPE_JOURNAL) 
     ft.replace(R.id.replaceable_journal_list, frag); 
    else if(CONTAINER_TYPE == AppConstants.FRAGMENT_TYPE_MOVIES) 
     ft.replace(R.id.replaceable_movies_list, frag); 
    else 
     return; 

    ft.commit(); 

credo che sia perché in ogni frammento, sostituisce la LinearLayout dello stesso ID? (replaceable_list) Ho pensato che fosse possibile condividere lo stesso file di layout per ogni frammento e non volevo creare 4 file di layout che sarebbero stati gli stessi. Ma sembra che devo farlo? O mi manca qualcosa qui?

Grazie per il vostro tempo,

+0

Non stai passando la posizione corretta al tuo frammento, vedi più upvoted di: http://stackoverflow.com/questions/9245408/best-practice-for-instantiating-a-new-android-fragment – cYrixmorten

+0

Sì, ho avuto già provato prima di pubblicare la mia domanda, ma non ha funzionato neanche. Penso che sia legato all'uso dello stesso layout, ma mi piacerebbe esserne sicuro. – Seb83

+0

Ok, beh mi sembra un po 'strano con i frammenti annidati. A quanto ho capito, dovresti fare lo switch direttamente in getItem del tuo CustomPagerAdapter, restituendo il frammento che vuoi mostrare (e non fare molte sostituzioni in mezzo). Saltare efficacemente la frittura del contenitore. – cYrixmorten

risposta

7

sono stato in grado di risolvere questo impostando l'id del layout che viene gonfiato all'interno di ogni frammento alla sua posizione.

Che cosa si dovrebbe fare è semplicemente cambiare il metodo onCreateView in voi classe ContainerFragment a:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View v = inflater.inflate(R.layout.fragment_container, container, false); 
    v.setId(CONTAINER_TYPE) 
    return v; 

Questo funziona a causa del modo in cui l'implementazione FragmentPagerAdapter gestisce tag frammento.

13

Anche se una risposta molto tardi, ma stavo affrontando lo stesso tipo di problema e ho risolto il problema utilizzando

getChildFragmentManager().beginTransaction() 

invece di

getActivity().getSupportFragmentManager().beginTransaction() 

Come in questo caso stiamo cercando di fare transazioni dall'interno di un frammento (uno fuori dall'elenco dei frammenti che sono collegati al ViewPager, quindi l'attività che contiene il ViewPager), quindi dobbiamo usare getChildFragmentManager() qui per i risultati desiderati.

Problemi correlati