ViewPager con fragmentos anidados?
Mi problema
De acuerdo con los documentos de Google:
Ahora puede incrustar fragmentos dentro de fragmentos. Esto es útil para una variedad de situaciones en las que se desea ubicar componentes de interfaz de usuario dinámicos y reutilizables en un componente de interfaz de usuario que sea dinámico y reutilizable. Por ejemplo, si utiliza ViewPager para crear fragmentos que pasan a la izquierda y la derecha y consumen la mayoría del espacio de la pantalla, ahora puede insertar fragmentos en cada página de fragmentos. Para anidar un fragmento, simplemente llame a getChildFragmentManager () en el fragmento en el que desea agregar un fragmento. Esto devuelve un FragmentManager que puede utilizar como lo hace normalmente desde la actividad de nivel superior para crear transacciones de fragmentos. Por ejemplo, aquí hay algún código que agrega un fragmento dentro de una clase de fragmento existente:
- Java.lang.InstantiationException: no se puede instanciar clase ... sin constructor vacío
- Intentar invocar método virtual 'android.os.Handler android.support.v4.app.FragmentHostCallback.getHandler ()' en una referencia de objeto nulo
- ViewPager + FragmentPagerAdapter dentro de un DialogFragment obtiene "IllegalArgumentException: No se encontró ninguna vista ..."
- Actualizar imágenes en FragmentStatePagerAdapter al reanudar la actividad
- Cómo obtener fragmentos existentes cuando se utiliza FragmentPagerAdapter
Fragment videoFragment = new VideoPlayerFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.video_fragment, videoFragment).commit();
Así que creé mi propio PageFragment
. Y mi PageFragmentAdapter
consta de 3 páginas de PageFragment
. También tengo seis fragmentos: Fragment1
, Fragment2
, Fragment3
, FragmentA
, FragmentB
, FragmentC
. En mi MainActivity
inicializo mis seis fragmentos, mi ViewPager
y su PageFragmentAdapter
(que inicializa tres PageFragment
para sí mismo).
A continuación, utilizo este método para adjuntar Fragment1
, Fragment2
, Fragment3
a cada página (a cada PageFragment
) de PageFragmentAdapter
:
PageFragmentAdapter tPageFragmentAdapter = new PageFragmentAdapter(getSupportFragmentManager()); tPageFragmentAdapter.setFirstPage(tFragment1); tPageFragmentAdapter.setSecondPage(tFragment2); tPageFragmentAdapter.setThirdPage(tFragment3);
Puedo recive (a través de métodos en PageFragmentAdapter
) Fragmentos y hacer "fragmento anidado" en mi PageFragment
(por supuesto en onCreate()
) como:
getChildFragmentManager().beginTransaction() .add(R.id.framelayout_history, mFragment) .addToBackStack(null) .commit();
Nota: Utilizo PageFragment.setNestedFragment()
para establecer mFragment
en él.
Y funciona muy bien! Me ayudará (pero esta historia no es acerca de ello) simplemente reemplazar fragmentos en ViewPager como:
tPageFragmentAdapter.replaceFirstPage(tFragmentA);
Pero tengo un gran problema. Una vez más documentos de Google:
Implementación de PagerAdapter que representa cada página como un fragmento que se mantiene persistentemente en el administrador de fragmentos, siempre y cuando el usuario pueda volver a la página. Esta versión del buscapersonas es la mejor para usar cuando hay un puñado de fragmentos típicamente más estáticos para ser paginado a través de, como un conjunto de pestañas. El fragmento de cada página que visita el usuario se guardará en la memoria, aunque su jerarquía de vista se puede destruir cuando no esté visible. Esto puede resultar en el uso de una cantidad significativa de memoria ya que las instancias de fragmentos pueden mantenerse en una cantidad arbitraria de estado.
Como puede ver PageFragmentAdapter
puede destruir cada mi PageFragment
y por supuesto su fragmento anidado. Y cuando se va a recrear tendrá un valor NULL en vez mFragment
. Estoy intentando guardarlo a través de getChildFragmentManager().putFragment()
y luego get it getChildFragmentManager().getFragment()
. Pero no funcionó.
Pregunta
Así que mi pregunta es: ¿Cómo guardar mi fragmento anidado en mi fragmento padre? ¿Es posible?
Agradecería mucho su ayuda. Alex. PS Realmente lo siento por mi inglés 🙂
EDITAR
Thx @ AndroidBegin.com para la respuesta!
Esto parece ser un error en el soporte recién agregado para fragmentos anidados. Básicamente, el niño FragmentManager termina con un estado interno roto cuando se separa de la actividad. Una solución a corto plazo que lo arregló para mí es añadir lo siguiente a onDetach () de cada fragmento que se llama getChildFragmentManager () en:
@Override public void onDetach() { super.onDetach(); try { Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager"); childFragmentManager.setAccessible(true); childFragmentManager.set(this, null); } catch (NoSuchFieldException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } }
- ¿Cómo cambiar el color de ActionBar al pasar entre fragmentos (diseño de material)?
- Fragmento de Viewpager anidado no inicializado
- ¿Cómo uso FragmentPagerAdapter para tener pestañas con contenido diferente?
- Cómo actualizar dinámicamente el elemento TITLE del visor de vistas
- Cambia dinámicamente el título de un android.support.v4.view.PagerTitleStrip
- No se puede actualizar / actualizar listview en un fragmento de otro fragmento en ViewPager
- Cómo reemplazar Fragment dentro de ViewPager, usando PagerAdapter?
- Adición dinámica de elementos a FragmentGridPagerAdapter
Prueba esto en tu fragmento.
public class Fragment2 extends SherlockFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.viewpager_main, container, false); // Locate the ViewPager in viewpager_main.xml ViewPager mViewPager = (ViewPager) view.findViewById(R.id.viewPager); // Set the ViewPagerAdapter into ViewPager mViewPager.setAdapter(new ViewPagerAdapter(getChildFragmentManager())); return view; } @Override public void onDetach() { super.onDetach(); try { Field childFragmentManager = Fragment.class .getDeclaredField("mChildFragmentManager"); childFragmentManager.setAccessible(true); childFragmentManager.set(this, null); } catch (NoSuchFieldException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } }
- Cómo administrar varias ediciones de la misma aplicación android
- Fragmento de la transacción de animación personalizada – Android