Introducción Fragments en Android

Buenos días, a continuación vamos a ver un ejemplo en el que podemos introducirnos en los Fragments para Android.


Como ya sabemos, una Activity ocupa normalmente el tamaño de una pantalla en un smartphone, mostrando las diferentes views que generan la interfaz gráfica de usuario en una aplicación. La activity es esencialmente un contenedor para las vistas.

Sin embargo, cuando una activity es mostrada en un dispositivo con una pantalla larga, como en una tablet, es algo fuera de lugar. Como la pantalla es mucho mas grande, todas las views harán lo posible para hacer uso completo de este espacio sobrante, lo que hace que se produzcan cambios en la jerarquía de las views. Un enfoque mejor es el uso de “mini-activities”, la cual contiene cada uno su set de views. En tiempo de ejecución, una activity puede tener una o mas mini-activities, dependiendo de la orientación de pantalla del dispositivo. En Android 3.0 y después, estas mini-activities son conocidas como fragments.

Vamos a pensar que un Fragment es otra forma de Activity. Creamos Fragments que contienen views, al igual que una activity, solo que los Fragments siempre están dentro de una Activity.

En el ejemplo que vamos a hacer, vamos a crear 2 Fragments los cuales irán metidos dentro de un FragmentActivity.

Para comenzar, vamos a crear un proyecto, el cual podemos llamar como queramos.

Cuando nuestro proyecto esté creado, vamos a ir punto por punto para lograr lo que queremos.

  • FragmentsExample

    Esta es nuestra Activity principal, la cual contendrá los 2 Fragment posteriores. En realidad no tiene demasiada complicación, ya que es mas que nada un simple contenedor para nuestros 2 Fragments.

    		<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    		    xmlns:tools="http://schemas.android.com/tools"
    		    android:layout_width="match_parent"
    		    android:layout_height="match_parent"
    		    android:orientation="horizontal"
    		    tools:context=".FragmentsActivity" >
    		
    		    <fragment
    		        android:id="@+id/fragment1"
    		        android:name="sekth.droid.fragments.Fragment1"
    		        android:layout_width="0dp"
    		        android:layout_height="fill_parent"
    		        android:layout_weight="1" />
    		
    		    <fragment
    		        android:id="@+id/fragment2"
    		        android:name="sekth.droid.fragments.Fragment2"
    		        android:layout_width="0dp"
    		        android:layout_height="fill_parent"
    		        android:layout_weight="1" />
    		
    		</LinearLayout>
    		

    Como vemos en el código, nuestra pantalla principal estará partida en 2, y cada una de las mitades está ocupada por un Fragment, como veremos posteriormente.

    En el código java de nuestra activity, no tenemos que cambiar demasiado, solo un pequeño detalle que tiene que ver con las versiones de Android, ya que los Fragment fueron introducidos a partir de la versión de Android 3.0 HoneyComb, y por tanto si queremos usarlo en versiones anteriores, nuestra Activity debe heredar de la clase FragmentActivity, que está dentro del package de soporte.

    		public class FragmentsActivity extends FragmentActivity {
    
    			@Override
    			protected void onCreate(Bundle savedInstanceState) {
    				super.onCreate(savedInstanceState);
    				setContentView(R.layout.activity_fragments);
    			}
    		}
    		
  • Fragment1

    Con la Activity terminada, vamos a hacer nuestro primer Fragment. Para ello crearemos una nueva clase Java que hereda de la clase Fragment. Una vez creada nuestra clase, creamos un nuevo archivo xml en la carpeta res/layout, al cual llamaremos fragment1.xml

    		<?xml version="1.0" encoding="utf-8"?>
    		<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    		    android:layout_width="match_parent"
    		    android:layout_height="match_parent"
    		    android:orientation="vertical"
    		    android:background="#00FF00" >
    		    <TextView 
    		        android:layout_width="fill_parent"
    		        android:layout_height="wrap_content"
    		        android:text="Este es el Fragment 1"
    		        android:textColor="#000000"
    		        android:textSize="25sp" />
    		
    		</LinearLayout>
    		

    Este fragment es muy básico y solo hemos añadido un TextView con un texto que nos indica que fragment es. Hemos definido un color de background para el LinearLayout muy llamativo, para poder ver luego la diferencia en la aplicación en ejecución.

    A continuación vamos al código java el cual tendrá todo el código de nuestro Fragment, como si de una Activity se tratara:

    		public class Fragment1 extends Fragment {
    
    			@Override
    			public View onCreateView(LayoutInflater inflater, ViewGroup container,
    					Bundle savedInstanceState) {
    				// TODO Auto-generated method stub
    				
    				// Inflamos el Layout con el fragment
    				return inflater.inflate(R.layout.fragment1, container, false);
    			}
    			
    		}
    		

    En el método onCreateView retornamos un objeto de la clase View. Este View será nuestro fragment, y como podemos ver lo hemos rellenado con nuestro archivo fragment1.xml

    Con esto, ya tendríamos nuestro primer Fragment listo.

  • Fragment2

    El Fragment2 no difiere demasiado del Fragment1, cambiaremos un poco en su archivo xml y poco mas en su Fragment2.java.

    		<?xml version="1.0" encoding="utf-8"?>
    		<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    		    android:layout_width="match_parent"
    		    android:layout_height="match_parent"
    		    android:orientation="vertical"
    		    android:background="#FFFE00" >
    		    <TextView 
    		        android:layout_width="fill_parent"
    		        android:layout_height="wrap_content"
    		        android:text="Este es el Fragment 2"
    		        android:textSize="25sp"
    		        android:textColor="#000000"/>
    		    
    		
    		</LinearLayout>		
    		

    En este caso, la interfaz de nuestro fragment2.xml es igual, excepto por el color de fondo, que es amarillo, y el texto, que nos informa de que pertenece al Fragment2.

    En la clase Fragment2.java, lo único que cambiamos es la referencia al archivo layout que hemos usado, ya que el Fragment2 tiene su propio layout:

    		public class Fragment2 extends Fragment {
    
    			@Override
    			public View onCreateView(LayoutInflater inflater, ViewGroup container,
    					Bundle savedInstanceState) {
    				// TODO Auto-generated method stub
    				
    				// Inflamos el layout con el fragment
    				return inflater.inflate(R.layout.fragment2, container, false);
    			}
    		
    		}
    		

Una vez tenemos todo realizado, las piezas encajan, y podemos ejecutar nuestra aplicación, la cual al ejecutarse veremos como nuestra actividad principal está partida en 2, y en cada mitad tenemos un Fragment, el Fragment1 a la izquierda, y el Fragment2 a la derecha, y con los colores tan llamativos nos daremos cuenta inmediatamente.

FragmentsPortrait FragmentsLandScape

Aquí vemos un vídeo, para verlo en ejecución:



En esta entrada, hemos podido introducirnos un poco en los Fragment, lo cual como veremos en futuras entradas, pueden ser muy reutilizables y pueden comunicarse entre sí por tanto tendremos pequeñas actividades funcionando dentro de una misma actividad.

El Código de este ejemplo podeis bajarlo de aquí

Sin mas, cualquier aporte o corrección son bienvenidos. Saludos!!!

  • beto

    buenas como puedo hacer para mostrar dentro de un dialog dos controles un datepicker y un button??
    quiero mostrar el dialog para seleccionar una fecha y el boton aceptar para cerrar el dialog y regresar la fecha a un edit text

    saludos

    • Pues una forma fácil de hacerla, y de hecho es la mas actual (ya que el método onCreateDialog en las Activity está siendo dejado de usar) es mediante el uso de DialogFragment, aquí tienes el Fragment que puedes usar para implementar esto que quieres:

      public class DatePickerFragment extends DialogFragment implements
      		OnDateSetListener {
      
      	@Override
      	public Dialog onCreateDialog(Bundle savedInstanceState) {
      		// TODO Auto-generated method stub
      		final Calendar c = Calendar.getInstance();
      		int day = c.get(Calendar.DAY_OF_MONTH);
      		int month = c.get(Calendar.MONTH);
      		int year = c.get(Calendar.YEAR);
      		return new DatePickerDialog(getActivity(), this, year, month, day);
      
      	}
      
      	@Override
      	public void onDateSet(DatePicker arg0, int year, int month, int day) {
      		// TODO Auto-generated method stub
      		String fecha = day + "/" + month + "/" + year;
      		((MainActivity) getActivity()).actualizarFecha(fecha);
      	}
      
      }
      

      En la FragmentActivity, debes crear un método, el cual usará el DialogFragment para actualizar el EditText:

      public class MainActivity extends FragmentActivity {
      
      	private Button btnMostrar;
      	private EditText etFecha;
      
      	@Override
      	protected void onCreate(Bundle savedInstanceState) {
      		super.onCreate(savedInstanceState);
      		setContentView(R.layout.activity_main);
      
      		btnMostrar = (Button) findViewById(R.id.btnMostrarDialog);
      		btnMostrar.setOnClickListener(new View.OnClickListener() {
      
      			@Override
      			public void onClick(View v) {
      				// TODO Auto-generated method stub
      				DatePickerFragment datepicker = new DatePickerFragment();
      				datepicker.show(getSupportFragmentManager(), "datepicker");
      			}
      		});
      
      		etFecha = (EditText) findViewById(R.id.etFecha);
      	}
      
      	public void actualizarFecha(String fecha) {
      		etFecha.setText(fecha);
      	}
      
      }
      

      No es dificil, y queda bastante bien.

      Espero que te sea de ayuda.

      Saludos!!!

      • Aldo

        Hola Por Favor Podrias Hacer Un Tuto Para Una App Al Estilo Ajustes De Un Tablet Con Una Lista En Un Fragment Y Al Pulsar Un Elemento Inicie Una Actividad En Otro Fragment Al Lado Del Primero Con Su Propia Logica Como Se Haria?? Solo He Visto Que Pasan Textos Pero No Actividades Independiente Repito Como En La Aplicacion Ajustes No Se Me Ocurre Nada. Gracias.
        O Donde Podria Encontrar El Codigo Fuente De La Aplicaion Ajustes Para Analizarlo Seguro Que Viene Comentado…

  • beto

    gracias si me sirvio y es mas fasil y menos codigo que de la otra manera en qe lo estaba haciendo
    saludos

  • beto

    hola quiero que mi aplicacion me muestre una imagen de forma similar a la que muestra el calendario (sobre mi activity), sin abrir otra activity solo para mostrar la imagen o tener que agregar un imagen view y me mueva los demas controles que ya tengo agregados
    al precionar un boton “ver imagen” como puedo hacerlo ya que solo e encontrado
    gracias espero puedas ayudarme

    • No sé exactamente lo que quieres hacer, que salga una imagen de un calendario pero que aparezca sobre la Activity (sin cerrarla) no?