Esta lección te enseñará a
También deberías leer
Para reutilizar los componentes Fragment, deberías desarrollar cada uno de ellos de forma totalmente autocontenida, como componentes modulares que definen su propia interfaz y comportamiento. Una vez hayas definido estos fragmentos reutilizables, puedes asociarlos con una Activity y conectarlos con la lógica de la aplicación para crear una interfaz de usuario compuesta.
A menudo querrás que un Fragment se comunique con otro, por ejemplo para cambiar el contenido basándote en un evento del usuario. Toda comunicación fragmento-a-fragmento se lleva a cabo a través de la actividad asociada. Dos fragmentos nunca deberían comunicarse directamente.
Definir una interfaz
Para permitir a un fragmento comunicarse con su actividad, puedes definir una interfaz en la clase Fragment e implementarla en la actividad. El fragmento captura la implementación de la interfaz durante su método de ciclo de vida onAttach() y puede luego llamar a los métodos de la interfaz para comunicarse con la actividad.
A continuación se muestra un ejemplo de comunicación entre un fragmento y una actividad:
public class HeadlinesFragment extends ListFragment { OnHeadlineSelectedListener mCallback; // La actividad contenedora debe implementar esta interfaz public interface OnHeadlineSelectedListener { public void onArticleSelected(int position); } @Override public void onAttach(Activity activity) { super.onAttach(activity); // Nos aseguramos de que la actividad contenedora haya implementado la // interfaz de retrollamada. Si no, lanzamos una excepción try { mCallback = (OnHeadlineSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " debe implementar OnHeadlineSelectedListener"); } } ... }
Ahora el fragmento puede enviar mensajes a la actividad llamando al método onArticleSelected()
(o cualquier otro método de la interfaz) usando la instancia mCallback
de la interfaz OnHeadlineSelectedListener
.
Por ejemplo, el siguiente método del fragmento se llama cuando el usuario pulsa sobre un elemento de la lista. El fragmento usa la interfaz de retrollamada para enviar el evento a la actividad padre.
@Override public void onListItemClick(ListView l, View v, int position, long id) { // Envía el evento a la actividad contenedora mCallback.onArticleSelected(position); }
Implementar una interfaz
Para recibir retrollamadas de eventos de un fragmento, la actividad que lo contiene debe implementar la interfaz definida en el fragmento.
Por ejemplo, la siguiente actividad implementa la interfaz del ejemplo anterior.
public static class MainActivity extends Activity implements HeadlinesFragment.OnHeadlineSelectedListener{ ... public void onArticleSelected(int position) { // El usuario seleccionó el encabezado de un artículo del fragmento HeadlinesFragment // Haz algo para mostrar ese artículo } }
Enviar un mensaje a otro fragmento
La actividad contenedora puede enviar mensajes a un fragmento capturando la instancia de Fragment
con findFragmentById()
, y llamando directamente a los métodos públicos del fragmento.
Por ejemplo, imagina que la actividad del ejemplo anterior contuviera otro fragmento que se utilizara para mostrar el elemento especificado por los datos devueltos en el método de retrollamada anterior. En ese caso, la actividad puede pasar la información recibida en el método de retrollamada al fragmento que mostrará el elemento:
public static class MainActivity extends Activity implements HeadlinesFragment.OnHeadlineSelectedListener{ ... public void onArticleSelected(int position) { // El usuario seleccionó el encabezado de un artículo del fragmento HeadlinesFragment // Haz algo para mostrar ese artículo ArticleFragment articleFrag = (ArticleFragment) getSupportFragmentManager().findFragmentById(R.id.article_fragment); if (articleFrag != null) { // Si el fragmento de artículos está disponible, estamos en una interfaz // con dos paneles... // Llama a un método de ArticleFragment para actualizar su contenido articleFrag.updateArticleView(position); } else { // En caso contrario, estamos en una interfaz con un solo panel y tenemos // que intercambiar fragmentos... // Crea un fragmento y le pasa como argumento el artículo seleccionado ArticleFragment newFragment = new ArticleFragment(); Bundle args = new Bundle(); args.putInt(ArticleFragment.ARG_POSITION, position); newFragment.setArguments(args); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // Reemplazamos lo que haya en la vista fragment_container con este fragmento, // y añadimos la transacción a la pila de vuelta para que el usuario pueda volver transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); // Aplica la transacción transaction.commit(); } } }