Mostrar fragmento viewpager dentro de un fragmento

Tengo un fragmento que contiene un ViewPager. ViewPager está asociado con un adaptador que contiene un conjunto de fragmentos.

Al cargar el fragmento padre, me encuentro con una IllegalStateException con el mensaje: java.lang.IllegalStateException: Recursive entry to executePendingTransactions .

Algunas investigaciones me han llevado a la conclusión de que el sistema es incapaz de mostrar fragmentos dentro de otro fragmento, sin embargo, parece haber alguna indicación de que es posible hacer exactamente esto con el uso de un ViewPager ( un error en ViewPager con otro fragmento ).

De hecho, si agrego un botón a mi fragmento padre que llama a mPager.setAdapter(mAdapter) en mi ViewPager cuando se presiona, ViewPager se carga correctamente. Esto no es ideal.

El problema entonces debe estar relacionado con el ciclo de vida de los fragmentos. Mi pregunta, por lo tanto, es esta: ¿Alguien más ha encontrado una manera de evitar este problema, y ​​si es así, ¿cómo?

¿Hay alguna manera de retrasar la configuración del adaptador en el ViewPager hasta después de la transacción de fragmento?

Aquí está mi código de fragmento padre:

  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mView = inflater.inflate(R.layout.team_card_master, container, false); mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager); final Button button = (Button)mView.findViewById(R.id.load_viewpager_button); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mViewPager.setAdapter(mAdapter); button.setVisibility(View.GONE); } }); mAdapter = new ViewPagerAdapter(getFragmentManager()); // mViewPager.setAdapter(mAdapter); return mView; } 

Y el adaptador:

 public class ViewPagerAdapter extends FragmentPagerAdapter { public ViewPagerAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { if (mCursor == null) return 0; else return mCursor.getCount(); } @Override public Fragment getItem(int position) { Bundle b = createBundle(position, mCursor); return TeamCardFragment.newInstance(b); } } 

Utilice AsyncTask para establecer el adaptador para viewPager. Esto funciona para mi. El asyncTask es hacer que el fragmento original complete su transición. Y luego procedemos con fragmentos viewPager, básicamente para evitar la recursión.

  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mView = inflater.inflate(R.layout.team_card_master, container, false); mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager); final Button button = (Button)mView.findViewById(R.id.load_viewpager_button); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mViewPager.setAdapter(mAdapter); button.setVisibility(View.GONE); } }); mAdapter = new ViewPagerAdapter(getFragmentManager()); new setAdapterTask().execute(); return mView; } private class setAdapterTask extends AsyncTask<Void,Void,Void>{ protected Void doInBackground(Void... params) { return null; } @Override protected void onPostExecute(Void result) { mViewPager.setAdapter(mAdapter); } } 

Jords, creo que puedes usar FragmentStatePagerAdapter lugar de FragmentPageAdapter . Se eliminará fragmentos para usted.

PD. Lo siento por usar respuesta en lugar de comentario, pero mi reputación es demasiado baja.

Me encontré con el mismo problema. Tuve un Fragment que necesitaba para alojar un ViewPager de Fragments . Cuando apilado otro Fragment en la parte superior de mi ViewPagerFragment , y luego golpeó de nuevo, me gustaría obtener una IllegalStateException . Después de comprobar los registros (al apilar un nuevo Fragment ), encontré que mi ViewPagerFragment iría a través de sus métodos de ciclo de vida para detener y destruir, sin embargo sus Fragments en el ViewPager se quedaría en onResume . Me di cuenta de que los Fragments los niños deben ser administrados por el FragmentManager para el ViewPagerFragment , no el FragmentManager de la Activity .

Entiendo en el momento, las respuestas anteriores fueron para evitar las limitaciones de Fragments no ser capaz de tener Fragments hijos. Sin embargo, ahora que la última biblioteca de soporte tiene soporte para la anidación de Fragment , ya no necesitará hackear la configuración del adaptador para ViewPager y pasar getChildFragmentManager() es todo lo que necesita. Esto ha funcionado perfectamente para mí hasta ahora.

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mView = inflater.inflate(R.layout.team_card_master, container, false); mViewPager = (ViewPager) mView.findViewById(R.id.team_card_master_view_pager); mAdapter = new ViewPagerAdapter(getChildFragmentManager()); mViewPager.setAdapter(mAdapter); return mView; } 

He utilizado Handler.post() para configurar el adaptador fuera de la transacción de fragmento original:

 @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mHandler.post(new Runnable() { @Override public void run() { mViewPager.setAdapter(mAdapter); } }); } 

He hecho frente a este problema al intentar inicializar el adaptador del viewPager en el TabIndicator en encendido ViewCreated. Después de leer sobre él en línea me di cuenta de que esto podría ser sólo porque el fragmento no se agregó aún a la actividad. Así que moví el código de inicialización a onStart () del fragmento, esto debería resolver su problema. Pero no para mí todavía estaba recibiendo el mismo problema de nuevo.

Pero eso era porque en mi código estaba intentando el bypass la ejecución asíncrona normal de la tarea pendiente por llamada explícita a executePendingTransactions (), después de bloquear que todo funcionó bien

Al cargar el fragmento padre, me encuentro con una IllegalStateException con el mensaje: java.lang.IllegalStateException: Entrada recursiva para ejecutarPendingTransactions.

Algunas investigaciones me han llevado a la conclusión de que el sistema no puede mostrar fragmentos dentro de otro fragmento, sin embargo, parece que hay alguna indicación de que es posible hacer exactamente esto con el uso de un ViewPager (Un error en ViewPager con otro fragmento ).

Establece Id para ViewPager explícitamente.

  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mView = inflater.inflate(R.layout.team_card_master, container, false); mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager); mViewPager.setId(100); final Button button = (Button)mView.findViewById(R.id.load_viewpager_button); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mViewPager.setAdapter(mAdapter); button.setVisibility(View.GONE); } }); mAdapter = new ViewPagerAdapter(getFragmentManager()); mViewPager.setAdapter(mAdapter); return mView; } 

Puede utilizar id en sus recursos xml en lugar de un número mágico 100.

 <resources> <item name="Id_For_ViewPager" type="id"/> </resources> 

Y setId (R.Id_For_ViewPager).

Vea la fuente FragmentManager.java para más detalles.

https://github.com/android/platform_frameworks_support/blob/master/v4/java/android/support/v4/app/FragmentManager.java#L900

O vea esta página (en japonés). La idea original es de ella, en realidad, no yo. http://y-anz-m.blogspot.jp/2012/04/androidfragment-viewpager-id.html

Usando este brillante post de Thomas Amssler: http://tamsler.blogspot.nl/2011/11/android-viewpager-and-fragments-part-ii.html

Iv'e creó un adaptador que se puede utilizar para crear todo tipo de fragmentos. El propio adaptador se ve así:

 public abstract class EmbeddedAdapter extends FragmentStatePagerAdapter { private SparseArray<WeakReference<Fragment>> mPageReferenceMap = new SparseArray<WeakReference<Fragment>>(); private ArrayList<String> mTabTitles; public abstract Fragment initFragment(int position); public EmbeddedAdapter(FragmentManager fm, ArrayList<String> tabTitles) { super(fm); mTabTitles = tabTitles; } @Override public Object instantiateItem(ViewGroup viewGroup, int position) { mPageReferenceMap.put(Integer.valueOf(position), new WeakReference<Fragment>(initFragment(position))); return super.instantiateItem(viewGroup, position); } @Override public int getCount() { return mTabTitles.size(); } @Override public CharSequence getPageTitle(int position) { return mTabTitles.get(position); } @Override public Fragment getItem(int pos) { return getFragment(pos); } @Override public void destroyItem(ViewGroup container, int position, Object object) { super.destroyItem(container, position, object); mPageReferenceMap.remove(Integer.valueOf(position)); } public Fragment getFragment(int key) { WeakReference<Fragment> weakReference = mPageReferenceMap.get(key); if (null != weakReference) { return (Fragment) weakReference.get(); } else { return null; } } @Override public int getItemPosition(Object object) { return POSITION_NONE; } 

}

Para utilizar el adaptador tendrá que hacer lo siguiente:

 private void setAdapter() { if(mAdapter == null) mAdapter = new EmbeddedAdapter(getActivity().getSupportFragmentManager(), mTabTitles) { @Override public Fragment initFragment(int position) { Fragment fragment; if(position == 0){ // A start fragment perhaps? fragment = StartFragment.newInstance(mBlocks); }else{ // Some other fragment fragment = PageFragment.newInstance(mCategories.get((position))); } return fragment; } }; // Have to set the adapter in a handler Handler handler = new Handler(); handler.post(new Runnable() { @Override public void run() { mViewPager.setVisibility(View.VISIBLE); mPagerTabStrip.setVisibility(View.VISIBLE); mAdapter.notifyDataSetChanged(); } }); } 

Tenga en cuenta que todos los fragmentos utilizan:

 setRetainInstance(true); 

De acuerdo con la documentación: https://developer.android.com/reference/android/app/Fragment.html#getChildFragmentManager ()

Si desea administrar el fragmento de anidamiento, debe utilizar getChildFragmentManager lugar de getFragmentManager .

  • Cambiar el color de las pestañas de navegación mediante programación
  • ANDROID: ViewPager con diferentes fragmentos en el método instantiateItem
  • El relleno de la barra de estado de CoordinatorLayout desaparece de ViewPager 2ª página
  • ViewPager en TabFragment no se carga por segunda vez
  • Cómo iniciar la actividad en una nueva ventana Utilización de WebView?
  • Error al cargar fragmentos cuando las pestañas + viewpager dentro de scrollview?
  • Custom ViewPager dentro de ObservableScrollView no se mide correctamente la altura
  • Cómo hacer que PagerAdapter cargue todas las páginas
  • Cómo reemplazar fragmento a otro fragmento en TabLayout y ViewPager
  • ViewPager con fragmentos - onPause (), onResume ()?
  • SearchView con múltiples fragmentos usando viewpager en android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.