android - tutorial - ViewPager con varias instancias de fragmentos de la misma clase
fragment lifecycle (2)
Pude resolver esto al establecer el id del diseño que está inflado dentro de cada fragmento en su posición.
Lo que tendría que hacer es simplemente cambiar el método enCreateView en su clase ContainerFragment por:
@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;
Esto funciona debido a la forma en que la implementación de FragmentPagerAdapter maneja etiquetas de fragmentos.
Intento crear una ViewPager que contiene 5 fragmentos. 5 fragmentos de "contenedor", por lo que cada uno de ellos contiene 2 fragmentos. Los 4 primeros fragmentos tienen el mismo diseño y pertenecen a la misma clase. El quinto es de otra clase, y no hay problema con eso.
El problema es que cuando la actividad se inicia, solo 1 fragmento parece estar funcionando (el que está en la posición 0 en viewPager). Traté de devolver el nuevo Fragment () en la posición 0 en mi PagerAdapter, pero cuando lo hago es el segundo fragmento que está funcionando. (Al trabajar me refiero a mostrar la lista de la izquierda, todavía no me he ocupado del fragmento de detalles a la derecha)
Aquí hay un código
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
Aquí están las constantes que 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; // ...
}
Y el xml para el contenedor:
<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>
ASÍ QUE este código no funciona, parece que la lista de la izquierda en el contenedor de fragmentos se reemplaza en cada fragmento, y solo el fragmento en la posición 0 lo muestra. (Actualmente muestra la lista con el adaptador de tipo "JOURNAL", pero debe mostrar la lista de tipo "AGENDA".
-------------------- * PERO! ... * --------------------
Si creo diferentes archivos de diseño de contenedor de fragmento y escribo condiciones de IF en onCreateView y onViewCreated en ContainerFragment.java, todo funciona bien. Asi que :
ContainerFragment.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();
Supongo que es porque en cada fragmento, reemplazo el LinearLayout de la misma ID. (replaceable_list) Pensé que era posible compartir el mismo archivo de diseño para cada fragmento y no quería crear 4 archivos de diseño que serían los mismos. Pero parece que debo hacerlo? ¿O me estoy perdiendo algo aquí?
Gracias por tu tiempo,
Aunque fue una respuesta muy tardía pero me enfrentaba al mismo tipo de problema y solucioné el problema mediante el uso de
getChildFragmentManager().beginTransaction()
en lugar de
getActivity().getSupportFragmentManager().beginTransaction()
Como en este caso, estamos tratando de realizar una transacción desde un fragmento (uno de la lista de fragmentos que se adjunta al ViewPager, por lo tanto, la Actividad que contiene el ViewPager) por lo que tenemos que usar getChildFragmentManager () aquí para los resultados deseados.