Utilizar NestedFragments o cómo cargar Fragments dentro de Fragments en Android

En otros artículos como «Buenas prácticas usando Fragments» o «Introducción a los Fragments en Android» os contaba cómo cargar Fragments desde el Activity, intercambiarlos, y pasar mensajes entre ellos. Pero, ¿qué pasa si dentro de un Fragment que está mostrando la interfaz necesitamos incluir otro Fragment, como por ejemplo, un mapa de Google Maps?

Para esto en Android 4.2 se introdujeron los «NestedFragments», es decir, Fragments que se cargan dentro de Fragments. Luego los incluyeron en la librería de compatibilidad, con lo cual pueden usarse en todas las versiones de Android.

Imaginad que tenemos un MainFragment con el siguiente Layout:

	<?xml version="1.0" encoding="utf-8"?>
	<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
		xmlns:tools="http://schemas.android.com/tools"
		android:orientation="vertical"
		android:layout_width="match_parent"
		android:layout_height="match_parent">
		
		<EditText
			android:id="@+id/et_latitud"
			android:layout_width="wrap_content"
			android:layout_height="match_parent"
			android:hint = "Introduce latitud"/>
			
		<EditText
			android:id="@+id/et_longitud"
			android:layout_width="wrap_content"
			android:layout_height="match_parent"
			android:hint = "Introduce longitud"/>
			
		<Button
			android:id="@+id/bt_vermapa"
			android:layout_width="wrap_content"
			android:layout_height="match_parent"
			android:text = "Ver mapa"/>

		<FragmeLayout
			android:weigth="1"
			android:layout_width="wrap_content"
			android:layout_height="match_parent"
			android:id= "@+id/content"
			class="com.gpmess.app.MainFragment"
			tools:layout="@layout/fragment_reset">

		</fragment>

	</LinearLayout>
	

Tenemos dos EditText para ver la latitud y la longitud y luego queremos que al pulsar el botón «Ver Mapa» nos muestre el Mapa dónde tenemos el FragmeLayout.

Pues bien, en el código del MainFragment, sólo tendríamos que hacer lo siguiente:

		public class MainFragment extends Fragment{
		
			public static final String TAG = "MainFragment";
			private Button button;
			
		
		
			public static MainFragment newInstance(Bundle params){
				MainFragment mf = new MainFragment();
				mf.setArguments(params);
				return mf;
			}
			
			@Override
			public void onCreateView(Bundle saveInstanceState, LayoutInflater inflater, ViewGroup container){
				super.onCreateView(saveInstanceState, inflater, container);
				View v =  inflater.inflate(R.layout.fragment_main, container, false);
				button = (Button) v.findViewById(R.id.bt_vermapa);
				button.setOnClickListener(new View.OnClickListener(){
				
					@Override
					public void onClick(View v){
						FragmentTransaction ft = getChildFragmentManager.beginTransaction();
						ft.replace(R.id.content, new MapFragment(), MapFragment.TAG);
						ft.commit();
					}
				});
			}
		
		}
	

Como veis, el proceso de la FragmentTransaction es el mismo que hemos visto en otros artículos, salvo que utilizamos el getChildFragmentManager en lugar de getFragmentManager. Además, no ponemos android.R.id.content, si no R.id.content, que es el id del FrameLayout que vamos a sustituir por el MapFragment, y que podría ser cualquier otro. Por lo demás, el MapFragment es un Fragment totalmente normal y no necesita dentro ninguna implementación particular.