Actividades e Intents en Android
Actividades e Intents en Android
El usuario puede ir navegando entre las diferentes Activity. En concreto, Android suele disponer de un botón
(físico o en pantalla) que nos permite volver a la Activity anterior.
Toda actividad ha de tener una View o vista asociada, que será utilizada como interfaz de usuario. Esta vista
suele ser de tipo Layout, aunque también puede ser una view simple.
A la aplicación se accede a través de la actividad principal (main activity) que suele estar accesible desde el
menú de aplicaciones.
Cuando se navega a través de las Activities, éstas se guardan en una pila. Al pulsar el botón de retroceso, la
Activity actual se destruye y se recupera la Activity anterior de la pila.
Cuando una Activity pasa a la pila (back stack), debe guardar su estado para recuperarlo cuando vuelva a
primer plano.
Desde el momento en que aparece una actividad en la pantalla hasta el momento en que se oculta, pasa por una serie de
pasos o estados conocidos como el ciclo de vida de la actividad.
En ejecución (resumed): la activity se está ejecutando, está en primer plano y se puede interactuar con ella.
Pausada (paused): la activity es aún visible aunque está parada, porque otra activity está en primer plano.
Detenida (stopped): la activity está parada y no es visible, ha pasado a segundo plano.
1
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
La transición entre estados se controla mediante la llamada a los siguientes métodos de la clase Activity:
onCreate(): la actividad se está creando. Llamado cuando la activity se crea por primera vez.
onStart(): la actividad va a hacerse visible. Llamado cuando la activity se encuentra visible para el usuario
onResume(): la actividad se ha hecho visible. Llamado cuando la activity empieza a interaccionar con el
usuario.
onPause(): otra actividad va a tomar el foco y se va a pausar la activity actual. Llamado cuando la actividad
actual se detiene y la actividad anterior se reanuda.
onStop(): la actividad ya no es visible y va a ser parada. Llamado cuando la actividad ya no es visible por el
usuario.
onDestroy(): la actividad va a destruirse. Llamado antes de que el sistema destruya la actividad.
onRestart(): llamado cuando la actividad se ha detenido y se reinicia de nuevo
Las actividades pausadas y detenidas pueden ser destruidas por el sistema si necesita liberar memoria. Es muy
importante salvar los datos de forma adecuada ya que podrían perderse si la actividad es destruida
Observaciones
Cuando se inicia una activity, lo métodos onStart() y onResume() siempre se invocan (con independencia de si
la actividad se restaura desde segundo plano, o es de nueva creación). Cuando una actividad se crea por
primera vez, se llama al método onCreate().
Una actividad se destruye cuando se hace clic en el botón Atrás o de retroceso. Es crucial saber esto, ya que
cualquiera que sea el estado en el que esté la actividad se perderá; de ahí que se necesite escribir código
adicional para preservar su estado cada vez que esto ocurre (nos ocuparemos de ello más adelante a lo largo del
curso). En este punto, observa que el método onPause() se llama cuando una activity se envía a segundo plano.
El método onCreate() debe utilizarse para crear e instanciar los objetos que utiliza la actividad.
El método onResume() debe utilizarse para iniciar cualquier servicio o código que se tenga que ejecutar
mientras que la actividad esté en primer plano.
El método onPause() debe utilizarse para detener cualquier servicio o código que no se tenga que ejecutar
cuando la actividad no esté en primer plano y salvar datos que puedan perderse si la activity es destruida.
El método onDestroy() debe utilizarse para liberar recursos antes de que la actividad se destruya.
2
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
Para saber más sobre el Ciclo de Vida de una Activity puedes consultar los enlaces:
[Link]
3
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
Recuerda que al crear una aplicación Android desde Eclipse, por defecto se han creado varios de estos elementos.
[Link]
import [Link]
........
public class Hola extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_hola);
.... .... ....
}
[Link] (extracto)
<activity
android:name=".Hola"
android:label="@string/title_activity_hola" >
<intent-filter>
<action android:name="[Link]" />
<category android:name="[Link]" />
</intent-filter>
</activity>
activity_hola.xml (extracto)
<RelativeLayout xmlns:android="[Link]
xmlns:tools="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
tools:context=".Hola" />
</RelativeLayout>
Podemos iniciar una Activity esperando un resultado de vuelta con la llamada a startActivityForResult().
o Debemos implementar el método onActivityResult() que recibirá un objeto Intent con los datos que la
actividad devolverá.
Para finalizar una Activity incluiremos al final el método finish().
4
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
Cuando el usuario pulsa el botón HOME, las actividades son paradas y pasan a segundo plano pero la pila permanece
intacta. Por tanto, cuando se vuelve a ejecutar la aplicación la pila se recupera completamente.
Cuando se vuelve a llamar a una actividad ya iniciada, ésta no se recupera de la pila sino
que se vuelve a iniciar una nueva instancia.
Es posible modificar este comportamiento, por ejemplo que una actividad se inicie en una
tarea diferente o que solo haya una instancia de la misma actividad en la pila, aunque no
es lo usual y recomendable.
2. Intents
Un Intent es un mensaje abstracto que describe una operación que ha de realizarse, o una acción que ha ocurrido
en el sistema. Puede contener información extra necesaria para atender o realizar la acción.
Los componentes de Android que utilizan estos mensajes son: Activity, Service, BroadcastReceiver.
Estos componentes se lanzan a través de Intents, bien:
de forma implícita por parte del SO y los datos del fichero de manifiesto.
de forma explícita creando un objeto Intent y usando los métodos apropiados.
Los Intents no solo se utilizan para activar componentes, sino que también permiten intercambiar información
entre componentes de una misma aplicación o de aplicaciones diferentes.
Los Intents iniciados para un tipo de componente son atendidos única y exclusivamente por ese tipo de
componente. Es decir, un Intent que debe ser resuelto por una Activity no será resuelto por un Service ni por un
BroadcastReceiver.
5
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
Ejemplo:
Intent ia = new Intent(this, [Link]);
startActivity(ia);
Para propagar un Intent entre los diferentes componentes se utilizan los siguientes métodos:
Activity: a través de startActivity() o startActivityForResult(). Para este último la información devuelta se
establece con el método setResult() y la actividad la consultará a través del método onActivityResult().
Service: a través de los métodos startService() y bindService() para iniciar o modificar un servicio, y para
establecer un vínculo entre el componente que lanza el Intent y el servicio.
BroadcastReceiver: a través de los métodos sendBroadcast(), sendOrderedBroadcast(),
sendStickyBroadcast(), sendStickyOrderedBroadcast().
Nos centramos en esta Unidad, en los Intents asociados a las Activity.
Intents implícitos. No hay un componente específico al que vayan dirigidos, y son usados para activar
componentes de otras aplicaciones
Uno de los aspectos clave de la programación de Android es utilizar un Intent para llamar a Activities desde otras
aplicaciones. En particular, tu aplicación puede llamar a muchas aplicaciones incorporadas que están incluidas en un
dispositivo Android. Por ejemplo, si tu aplicación necesita cargar una página Web, puede utilizar el objeto Intent para
invocar el navegador Web incorporado en lugar de crear su propio navegador Web para este propósito.
Algunas acciones de Intent predefinidas para ejecutar Aplicaciones Google instaladas normalmente en el sistema, son
las siguientes:
De forma colectiva, el par acción-datos describe realmente lo que se va a realizar, Por ejemplo:
- Para abrir el navegador se utilizará ACTION_VIEW - [Link] web
- Para mostrar dirección en mapa se utilizará ACTION_VIEW - geo: cadena localización
- Para marcar un teléfono se utilizará ACTION_DIAL – tel: número de teléfono
Habrá que:
- Crear un objeto Intent, pasándole al constructor la acción y los datos (como objeto Uri)
- Propagar el Intent
Los datos también se pueden pasar utilizando el método setData(). En este caso las sentencias anteriores quedarán así:
En el siguiente ejemplo puedes ver cómo llamar a las aplicaciones incorporadas que se encuentran comúnmente en un
dispositivo Android.
6
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
Para conocer todas las acciones predefinidas, así como el comportamiento de la clase Intent consulta la dirección:
[Link]
Intents explícitos. Van dirigidos a un componente por su nombre. Se usan por ejemplo para lanzar a otras
Activity de la misma aplicación.
Si construimos una aplicación con dos Activity (Actividad1 y Actividad2) para cada una de ellas deben existir los
siguientes componentes:
Un interfaz de usuario (activity_actividad1.xml y activity_actividad2.xml)
Un componente de clase ([Link], [Link])
7
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
Y una declaración en el manifiesto de la aplicación ([Link]) para cada una de ellas.
Para lanzar desde la Actividad1 a la Activity Actividad2 de la misma aplicación debes proceder de la siguiente manera:
En la Activity1
- Crear una objeto Intent asociado al componente a lanzar
- Lanzar la nueva actividad con el Intent creado
En el manifiesto:
- Declarar la nueva Activity, como mínimo con la siguiente entrada dentro de la etiqueta <application>
<activity android:name=".Actividad2"></activity>
Como las Activities de una aplicación se pueden llamar desde otras aplicaciones, si es este el caso que nos interesa,
la invocación se haría entonces indicando explícitamente el nombre completo del componente:
El nombre del filtro de Intent para la nueva activity es [Link].Actividad2. Otras Activity que deseen
llamar a esta actividad, la invocarán por medio de este nombre.
La categoría para el filtro de Intent [Link], es necesaria para que esta
Activity se pueda iniciar por otra actividad.
Además, las actividades pueden intercambiar datos a través de los Intents, por ejemplo la Activity1 pude pasarle datos a
la Activity2 cuando la lanza a través de un Intent; y la Activity2 puede devolver datos a la Activity1.
En el siguiente ejemplo puedes ver como una Activity le pasa datos a otra.
8
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
Si la Actividad1 pasa datos a la Actividad2, habría que lanzar la activity Actividad2 de la siguiente forma: (como
has visto en el ejemplo anterior)
9
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
Si la Activity1 debe recibir datos de la Activity2, habrá que lanzar la activity2 mediante startActivityForResult().
En la Actividad1
- Crear una objeto Intent asociado al componente a lanzar
- Lanzar el intent con startActivityForResult(intent, rec_code); donde además de pasar el intent, hay que pasar
un código de petición. El código es un valor entero que identifica una actividad que está llamando. Es
necesario, porque cuando una Activity devuelve un valor, debe tener una forma de identificarlo. (Si el código
se establece a -1, no devuelve ningún resultado)
- Dentro de esta misma Activity se implementará el método onActivityResult() que se invoca siempre que se
reciben datos de una Activity lanzada mediante startActivityForResult(). Comprobará el código de petición y
el código de resultado (satisfactorio si es RESULT_OK, o bien RESULT_CANCELLED) y obtendrá el valor
asociado al resultado mediante getExtras() del Intent.
10
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
//información pasada:clave:"NOMBRE",
valor=[Link]().toString()
[Link]("NOMBRE", [Link]().toString());
@Override
protected void onActivityResult (int requestCode, int resultCode,
Intent data){
if(requestCode==cod && resultCode==RESULT_OK){
String res=[Link]().getString("resultado");
11
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
Acción. Es una cadena de caracteres con la acción que se debe realizar o que ha tenido lugar (broadcast
Intent).
o La clase Intent define una serie de constantes para acciones genéricas como ACTION_VIEW,
ACTION_CALL, ACTION_DIAL…..) y nosotros podemos crear la nuestras.
o Podemos definir nuestras propias acciones. Debemos hacer que el nombre de la acción incorpore el
nombre del paquete de la aplicación: “[Link].ACTION_CAMBIAR_FONDO”
o Se establece con el método setAction() y se obtiene con getAction().
o La acción va a determinar el resto del contenido del Intent, en concreto de los campos de datos y extra
Datos y tipos de datos. Referencia a los datos con sobre los que el componente que reciba el Intent debe
trabajar, y su tipo.
o Se compone de la URI y el tipo MIME de los datos.
o Hay que expresar los datos por medio de una URI. Ejemplos de URIs son: [Link]
[Link]
o El tipo MIME especifica el tipo de dato que el objeto Intent incorpora (audio, video, texto, etc). Con
este propósito se indica el tipo MIME asociado a la URI, es decir, se utiliza el mismo mecanismo que
en Internet. Ejemplos de tipos MIME son text/txt, image/jpeg, audio/mp3,…..
o El componente que realiza una determinada acción puede ser diferente en función del dato y el tipo
de dato que se incorpora en el Intent. Por ejemplo, la acción ACTION_VIEW será diferente si se
asocia como dato una dirección web, una imagen o un fichero de audio.
o Se establece con los métodos setData(), setType() y setDataAndType() y se consulta con getData() y
getType().
12
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
Categoría. Es una cadena de texto con información adicional sobre el componente que atenderá el Intent y
complementa a la acción.
o Indica información adicional sobre el tipo de componente que ha de ser lanzado. El número de
categorías puede ser arbitrariamente ampliado. No obstante, en la clase Intent se definen una serie de
categorías genéricas que podemos utilizar, como: CATEGORY_BROWSABLE,
CATEGORY_GADGET, CATEGORY_HOME, CATEGORY_LAUNCHER.
o Se pueden añadir y borrar categorías con addCategory() y removeCategory() y consultarlas con
getCategories().
Algunos ejemplos de categorías predefinidas en la clase Intent son:
Constante Significado
CATEGORY_GADGET La activity puede ser embebida dentro de otra activity que aloja gadgets.
CATEGORY_HOME La activity muestra la pantalla de inicio, la primera pantalla que ve el usuario cuando
el dispositivo está encendido o cuando se presiona la tecla HOME.
CATEGORY_LAUNCHER La activity puede ser la activity inicial de una tarea y se muestra en el lanzador de
aplicaciones de nivel superior.
CATEGORY_PREFERENCE La activity a lanzar es un panel de preferencias
Una categoría suele utilizarse con una acción para aportar información adicional. Por
ejemplo, indicaremos ACTION_MAIN a las activity que pueden utilizarse como punto de
entrada de una aplicación. Indicaremos además CATEGORY_LAUNCHER en la activity que será
escogida por defecto para ser lanzada en primer lugar.
Extras. Dependiendo de la acción a llevar a cabo puede ser necesario incorporar información adicional que
será recibida por el componente lanzado. Por ejemplo, si lo que se desea es enviar un sms deberemos añadir
información acerca del número de teléfono del receptor y el mensaje a enviar
o Estará formada por un conjunto de pares: clave-valor o variable-valor. Estas colecciones de valores se
manejan internamente con objetos Bundle.
o Se utilizan los métodos put...() y get...() de Intent para establecer y obtener la información extra. Son
métodos paralelos a los de un objeto Bundle.
o También se puede manejar a través de un objeto Bundle con los métodos getExtras() y putExtras().
Flags. Permiten indicar un comportamiento especial del componente que atienda el Intent.
o Por ejemplo:
FLAG_ACTIVITY_SINGLE_TOP: se evita que se cree una nueva Activity si esta ya existe en la pila.
FLAG_ACTIVITY_NEW_TASK: la nueva Activity se crea en una nueva pila de tareas.
FLAG_ACTIVITY_CLEAR_TOP: si la nueva Activity existe en la pila de actividades, todas aquellas
actividades que estuvieran por encima en la pila son eliminadas de la misma.
o Se manejan con los métodos setFlag() y getFlag().
El sistema Android debe encontrar el mejor componente o componentes que puedan atender un Intent implícito. Esto lo
hace comparando las características del Intent con los filtros (intent filter) establecidos por los componentes en el
manifiesto. Por ejemplo, si se quiere abrir un fichero de audio, es posible que haya más de una aplicación en el sistema
que pueda abrir ese fichero, es por esto que se tiene que tener en cuenta la manera en la que el sistema Android
establece el componente a utilizar.
Un filtro designa las capacidades de un componente en gestionar una acción, delimitando los tipos de Intent que puede
gestionar. Si un elemento no declara filtros, sólo podrá recibirlos explícitos.
Para determinar el tipo de componente a lanzar, el SO comprobará la acción, datos y tipo, y categoría, para encontrar el
componente adecuado, en caso de que haya varias coincidencias se preguntará al usuario por cual ejecutar.
13
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
En los casos que nos interese, cuando creamos una nueva activity podemos informar al sistema que tipo de Intents
implícitas pueden ser resueltas con nuestro componente. Para conseguir esto utilizaremos un filtro de Intents mediante
la etiqueta <intent-filter> dentro de [Link].
Cada Activity del manifiesto puede llevar un <intent-filter>, en el que comunica a Android cuando debe ser ejecutada
la activity.
Cuando una aplicación pregunta al sistema para completar un Intent, el sistema busca entre todas las activity y
servicios.
Para que un componente sea reconocido como posible para un Intent, tiene que pasar el filtro de los tres elementos:
acción, datos y categoría.
Para tal fin se pueden definir los tres dentro de la etiqueta <intent-filter>
<action>: Debe existir al menos una. El nombre de la acción puede ser una creada por nosotros, anteponiendo
el nombre del paquete, o una definida por el sistema.
<category>: para pasar este test, cada categoría que aparezca en el Intent tendrá que estar enumerada dentro
del filtro. Todo Intent lanzado desde la función startActivity(), tendrá al menos la categoría
“[Link]”, con lo que será la primera que tendremos que poner en todos nuestros
filtros. Solo hay una excepción a esta afirmación, los filtros que incluyan a la vez
“[Link]” y “[Link]” que indica que la actividad se
mostrará en el gestor de aplicaciones del dispositivo, y es la principal de la aplicación, en este caso no hace
falta incluir DEFAULT.
<data>: Usada una o varias veces, indica el tipo de datos que puede gestionar el componente. Indicará el tipo
MIME que soporta y la URI separada en elementos separados para cada componente.
Este filtro puede no aparecer en el manifiesto, es opcional.
El tipo MIME tiene la forma: “tipo/subtipo”
La URI tiene la forma: “scheme://host:port/path”
Ejemplos.
Filtro que incluye action MAIN y category LAUNCHER
<activity>
android:name=".Saludo2Activity"
android:label="@string/title_activity_saludo2" >
<intent-filter>
<action android:name="[Link]" />
<category android:name="[Link]" />
</intent-filter>
</activity>
Filtro que indica que la Activity de nombre MyBrowser responde a los Intents que invocan:
Al componente por su nombre
El tipo VIEW del sistema
Con datos cuyo esquema (scheme) es http
<activity
android:name=".MiBrowser"
android:label="@string/app_name" >
<intent-filter>
<action android:name="[Link]" />
<action android:name="[Link]" />
<category android:name="[Link]" />
<data android:scheme="http" />
</intent-filter>
</activity
14
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
Filtro que incluye para la misma Activity dos filtros: uno sin datos y otro con datos
<activity
android:name="[Link]"
android:label="@string/title_activity_second" >
<intent-filter>
<action android:name="[Link]" />
<category android:name="[Link]" />
</intent-filter>
<intent-filter>
<action android:name="[Link]" />
<category android:name="[Link]" />
<data android:mimeType = "text/plain"/>
</intent-filter>
</activity>
3. Fragmentos
Imagina que quieres mostrar los detalles de un elemento seleccionado en una lista. Hasta ahora nuestra única opción ha
sido programar dos actividades: una para la lista, y otra para los detalles, como en el ejemplo EquiposFutbol.
Si la pantalla es pequeña, ésta es una buena opción. Después de todo, no hay espacio suficiente para mostrar la lista y
los detalles del elemento seleccionado a la vez.
Pero si se trata de una tableta, la cosa cambia. Porque entonces, sí que hay espacio suficiente para mostrar la lista y los
detalles en una única actividad que ocupe toda la pantalla. De hecho, hacerlo en dos implica desperdiciar un montón de
espacio al mostrar cada una de ellas. Entonces, ¿tenemos que hacer un diseño diferente de la interfaz de usuario para
cada situación?
Precisamente, para evitar esta duplicidad es para lo que se introdujo el concepto de fragmento, mediante la
incorporación de la clase Fragment a partir de la API 11 (Android 3.0), pero todavía quedaba un pequeño escollo para
superar la programación en diferentes tamaños y se ha intentado solucionar con la aparición de la versión 4 del SO. En
esta versión se quiere conseguir que el aspecto de un interfaz de usuario no cambie a través de dispositivos de distintos
tamaños.
Un fragmento (objeto Fragment) Siempre está integrado en una Activity. Se pueden combinar múltiples fragmentos en
una actividad para crear un interfaz multipanel en una gran pantalla. O en una pantalla pequeña, se pueden repartir esos
mismos fragmentos entre dos o más actividades para mostrar sólo un fragmento cada vez.
Para añadir fragmentos a una actividad se pueden seguir básicamente dos procedimientos:
Indicar en el archivo XML del layout de la Activity los fragmentos mediante <fragment>
De forma dinámica en tiempo de ejecución
Al diseñar con fragmentos hay que tener en cuenta que su funcionamiento es muy similar al de las Activity. Tanto es así
que cada actividad posee una pila de fragmentos en donde poder ser apilados (como las actividades que se hace de
forma automática) para después regresar con simplemente cerrar el fragmento o con el botón ‘Atrás’.
Los fragmentos tienen un ciclo de vida similar al de las Activity, excepto que para poner un fragmento en la pila
tendremos que hacerlo de forma manual, mediante addToBackStack(), tal y como veremos en un ejemplo posterior.
Puedes ver algunos vídeos sobre “Fragmentos en la presentación de Android 3.0 Honeycomb (febrero 2011)”
[Link]
15
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
Los fragmentos heredan de la clase Fragment: public class Fragment1 extends Fragment
Como mínimo, el método que deberemos implementar es:
onCreateView (): El sistema lo llama para dibujar la interfaz de usuario del fragmento. Este método
devuelve el View o vista base (raíz) de la distribución del fragmento. Si retorna null, el fragmento no proporciona
una interfaz de usuario.
Para dibujar la interfaz de usuario para un fragmento, hay que sobrescribir el método OnCreateView(). Este método
retorna un objeto View de esta forma:
El objeto LayoutInflater crea la interfaz de usuario desde el archivo XML especificado ([Link].fragment1
en este caso). El argumento container hace referencia al padre ViewGroup, que es la actividad a la que se va a
incorporar el fragmento. El Bundle (savedIntanceState) permite restaurar el fragmento en su estado previamente
guardado.
Al poner false como tercer parámetro en la llamada a inflate() se indica que el contenedor padre sólo se utiliza crear la
interfaz desde el XML.
A continuación vemos un sencillo ejemplo de creación de dos fragmentos dentro una Activity.
Cada fragmento tendrá una interfaz definida en ficheros xml: [Link] y [Link]
En el archivo xml de la interfaz de la Activity principal, se incluye cada fragmento con una etiqueta
<fragment> y con un id para poder referenciarlos desde código.
Cada fragmento será na clase java: [Link], [Link]
Es muy importante especificar en la entrada min SDK Version el API 11 (Honeycomb), ya que existen
muchas características que solamente están disponibles en esa versión. Incluso poner la API 13
para incluir nuevas características ya obsoletas en versiones anteriores.
16
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
2. En la carpeta res/layout, añade un nuevo archivo y nómbralo [Link]. Complétalo con el código
siguiente:
3. También en la carpeta res/layout, añade otro archivo y llámalo [Link]. Complétalo de la siguiente
forma:
Recuerda:
Para añadir un fragmento a una actividad, se utiliza la marca <fragment>:
Cada fragmento necesita un identificador único. Puedes asignarlo mediante el atributo android:id.
5. Bajo el nombre del paquete ([Link] en nuestro ejemplo) añade dos archivos de clase Java y
nómbralos [Link] y [Link], tal y como se ilustra en la siguiente figura:
17
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
6. Añade el siguiente código a [Link]:
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
8. Ejecuta la aplicación en un emulador compatible. Observarás dibujados los dos fragmentos en la pantalla.
En el apartado anterior hemos visto cómo añadir fragmentos a una actividad mediante un fichero XML. Pero en
realidad, es mucho más útil crear los fragmentos y añadirlos a las actividades en tiempo de ejecución. Esto permite crear
una interfaz de usuario muy flexible.
Para añadir fragmentos a una actividad en tiempo de ejecución se tiene que realizar obligatoriamente con
transacciones. Éstas vienen a simular las típicas de SQL, en donde hasta que no se confirma no se realizan los cambios,
haciéndose todos de una vez.
Tenemos que tener los siguientes puntos en cuenta para manejar correctamente las transacciones de fragmentos:
Conseguir un objeto FragmentTransaction usando FragmentManager, y utilizar los siguientes métodos para
la gestión: add, replace, remove, commit.
Para añadir un fragmento a la correspondiente pila hay que usar addtoBackStack() necesariamente, si no se
destruirá completamente.
18
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
Solo se llamará al método commit una vez finalizadas todas las modificaciones y es obligatorio hacerlo.
Además, solo se puede llamar a este método cuando la actividad está en primer plano.
El ejemplo consistirá en crear de forma dinámica el fragmento que se debe visualizar según el dispositivo esté en
vertical u horizontal.
Para ello, en el ejemplo vamos a utilizar WindowManager para determinar si el dispositivo está actualmente en modo
vertical u horizontal. Una vez determinado, añade el fragmento apropiado a la Activity al crear el fragmento y, luego,
llama al método replace() del objeto FragmentTransaction para añadir el fragmento al contenedor de vista
especificado.
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
Display d = [Link]();
if ([Link]() > [Link]()) //se puede sustiuir a partir API 13 por (ver nota**)
{
//---si modo horizontal, crea el fragmento1---
Fragment1 fragment1 = new Fragment1();
// [Link] hace referencia a la vista de contenido de la actividad
[Link]([Link], fragment1);
}
19
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
else
{
//---si modo vertical: crea el fragmento2---
Fragment2 fragment2 = new Fragment2();
[Link]([Link], fragment2);
}
//---añadir a la pila de nuevo---
[Link](null);
3. Ejecuta la aplicación en un emulador compatible. Observa que cuando el emulador está en modo vertical se
muestra el fragmento 2 (amarillo). Si pulsas Control-F12 para cambiar la orientación del emulador a
horizontal, el fragmento 1 (verde) se muestra en lugar del fragmento 2.
Recuerda que hemos dicho que los fragmentos tienen un ciclo de vida similar al de las Activity, excepto que para poner
un fragmento en la pila tendremos que hacerlo de forma manual, mediante addToBackStack(), tal y como has visto en
el ejemplo anterior.
El siguiente ejemplo muestra cómo un fragmento puede acceder a las vistas (View) contenidas dentro de otro
fragmento. Para ello se utilizan los métodos:
- getActivity(): devuelve la Activity con la que está asociado el fragmento actual.
- findViewById(): localiza o referencia las vistas contenidas dentro del fragmento.
20
Unidad 3. Actividades, Intents y Fragmentos 2º DAM - PMDM
<Button
android:id="@+id/btnGetText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text = "Obtener texto de Fragment #1"
android:textColor="#000000"
/>
2. En el archivo activity_fragmentos.xml, deben aparecer de nuevo los dos fragmentos. Revísalo y descomenta
el código que comentaste en el apartado anterior.
3. Modifica el archivo [Link] (comenta el texto que añadiste anteriormente para la generación dinámica de
fragmentos) de manera que solo sea código ejecutable el siguiente:
@Override
public void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_fragmentos_3);
}
}
4. Modifica el archivo [Link] añadiendo las siguientes líneas, después de finalizar el método
onCreateView().
}
});
}
6. Ejecuta la aplicación en un emulador compatible y comprueba que al pulsar sobre el botón del fragmento 2 se
obtiene el texto asociado al componente TextView del fragmento 1 en una tostada.
4. Bibliografía
- ‘Android 4, Desarrollo de Aplicaciones’, Wei-Meng Lee, Ed. Anaya Multimedia
- ‘Programación Multimedia y dispositivos móviles’, César San Juan Pastor, Ed. Garceta
- [Link]
- [Link]
- [Link]
- [Link]
- [Link]
- [Link]
- [Link]
21