Curso Android
A medida que nuestra aplicación crezca va a ser imprescindible crear nuevas actividades.
Este proceso se puede resumir en cuatro pasos:
Android nos permite este intercambio de datos utilizando el mecanismo
Intent intent = new Intent(this, MI_CLASE.class);
intent.putExtra("usuario", "Pepito Perez");
intent.putExtra("edad", 27);
startActivity(intent);Bundle extras = getIntent().getExtras();
String s = extras.getString("usuario");
int i = extras.getInt("edad");Cuando lances una actividad usa el siguiente código:
En la actividad lanzada podemos recoger los datos:
Intent intent = new Intent(this, MI_CLASE.class);
startActivityForResult(intent, 1234);
...
@Override protected void onActivityResult (int requestCode,
int resultCode, Intent data){
if (requestCode==1234 && resultCode==RESULT_OK) {
String res = data.getExtras().getString("resultado");
}
}Intent intent = new Intent();
intent.putExtra("resultado","valor");
setResult(RESULT_OK, intent);
finish();Cuando la actividad lanzada termina también podrá devolver datos que podrán ser recogidos por la actividad lanzadora de la siguiente manera.
En la actividad llamada has de escribir:
Ejercicio
1- Para crear un nuevo menú, usa File > New > Android resource file. En el campo File name: selecciona menu_main y en el campo Resource type: selecciona Menu.
NOTA: Es posible que este fichero de menú ya esté creado. Esto ocurre cuando se crea un nuevo proyecto seleccina Add an activity: Basic Activity o Scrolling Activity.
2-Completa el archivo creado con la estructura que indica el siguiente ejemplo
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/ tools"
tools:context=".MainActivity">
<item android:id="@+id/action_settings"
android:title="Preferencias"
android:icon="@android:drawable/ic_menu_preferences"/>
<item android:title="Acerca de..."
android:id="@+id/acercaDe"
android:icon="@android:drawable/ic_menu_info_details"/>
</menu>Tres atributos principales:
3- Para activar el menú, has de introducir el siguiente código java de tu actividad.
@Override public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true; /** true -> el menú ya está visible */
}
@Override public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
if (id == R.id. acercaDe) {
lanzarAcercaDe(null);
return true;
}
return super.onOptionsItemSelected(item);
}La Action bar, o App bar como se la ha rebautizado con la llegada de Material Design y Android 5.0, es la barra de título y herramientas que aparece en la parte superior de la gran mayoría de aplicaciones actuales de la plataforma Android.
En caso de disponer de menos tamaño de pantalla el sistema puede redistribuir los elementos y pasar alguna acción al menú de «Overflow». Por ejemplo, en un móvil la barra de acciones anterior se podría ver de la siguiente manera:
Antes de la llegada de Material Design, a la izquierda del título también podía (y solía) aparecer el icono de la aplicación, aunque esto último ya no se recomienda en las últimas guías de diseño de la plataforma. Lo que sí puede aparecer a la izquierda del título son los iconos indicativos de la existencia de menú lateral deslizante (navigation drawer) o el botón de navegación hacia atrás/arriba.
Pero, en caso de disponer de una versión 3.0 o superior, se mostrará en la barra de acciones.
En la actualidad, Android proporciona este componente a través de la librería de soporte appcompat-v7, que podemos incluir en nuestro proyecto añadiendo su referencia en la sección dependencies del fichero build.gradle:
dependencies {
...
compile 'com.android.support:appcompat-v7:22.1.1'
}De cualquier forma, en versiones actuales de Android Studio, esta referencia viene incluida por defecto al crear un nuevo proyecto en blanco.
A partir de aquí, podemos hacer uso de la action bar de dos formas diferentes.
1. Asegúrate de que en tu proyecto esté la librería appcompat-v7.
2. Haz que tu actividad herede de ActionBarActivity o AppCompatActivity en lugar de Activity. Hasta la versión 21 de la librería appcompat-v7 la clase base de la que debían heredar nuestras actividades era ActionBarActivity, pero esto cambió con la versión 22, donde la nueva clase a utilizar como base será AppCompatActivity.
3. En AndroidManifest has de aplicar un tema adecuado a la actividad o a toda la aplicación. Estos temas han de pertenecer a Theme.AppCompat.* o ser descendientes de estos.
Tan sólo con esto, si ejecutamos el proyecto podremos comprobar como nuestra actividad muestra la action bar en la parte superior
La action bar por defecto tan sólo contiene el título y el menú de overflow.
Segunda opción
Una forma más flexible y personalizable de añadir una action bar a una aplicación es utilizar el nuevo componente Toolbar proporcionado por la librería appcompat. De esta forma podemos incluir de forma explícita la action bar en nuestros layouts XML como si fuera cualquier otro control, y no sólo en la parte superior de la pantalla a modo de app bar, sino también en cualquier otro lugar de la aplicación donde queramos utilizar esta funcionalidad de barra de acciones.
1- Asegurar es que nuestro proyecto incluye la última versión de la librería de soporte appcompat-v7, en la sección de dependencias del fichero build.gradle.
2- A continuación necesitamos “desactivar” la funcionalidad por defecto, configurando un tema para nuestra aplicación que no incluya la action bar. Para ello, editaremos el fichero /res/values/styles.xml para hacer que nuestro tema extienda de alguno de los siguientes (dependiendo si queremos partir del tema oscuro o claro):
3- También que nuestras actividades deben extender a AppCompatActivity.
4- Hecho esto, ya podemos modificar el layout de nuestra actividad para incluir la action bar utilizando el nuevo componente Toolbar.
<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="vertical"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/appbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" >
</android.support.v7.widget.Toolbar>
<!-- Resto de la interfaz de usuario -->
</LinearLayout>
5- En nuestro código debemos indicar que esta Toolbar actuará como action bar de la actividad. Para ello, en el método onCreate() de la actividad haremos una llamada a setSupportActionBar() con la referencia a la toolbar:
import android.support.v7.widget.Toolbar;
//...
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.appbar);
setSupportActionBar(toolbar);
}
//...
}
Para no tener que reescribir la definición completa del toolbar en todas nuestras actividades también podemos hacer uso de la cláusula include. Para ello, declaramos primero el toolbar en un layout XML independiente, por ejemplo en un fichero llamado /res/layout/toolbar.xml.
Y posteriormente incluir este fragmento en el layout de nuestras actividades haciendo referencia a él mediante include:
<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="vertical"
tools:context=".MainActivity">
<include android:id="@+id/appbar"
layout="@layout/toolbar" />
<!-- Resto de la interfaz de usuario -->
</LinearLayout>Visualiza una lista deslizable verticalmente de varios elementos, donde cada elemento puede definirse como un Layout
Definir un ListView conlleva los siguientes cuatro pasos:
1- Para utilizar un ListView dentro de un Layout usamos la siguiente estructura:
<FrameLayout>
<ListView
android:id="@android:id/list"... />
<TextView
android:id="@android:id/empty"
... />
</FrameLayout>Donde tenemos un FrameLayout que permite visualizar dos posibles elementos, uno u otro, pero no los dos simultáneamente.
2- Indicar al sistema cada uno de los Layouts individuales que contendrá el ListView. Esto lo haremos llamando al método setListAdapter(). Existen varias alternativas con diferentes grados de dificultad.
3- Una vez creado el Layout que contiene el ListView tendremos que visualizarlo en una actividad. Para este propósito utilizaremos un tipo de actividad especial, ListActivity.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1">>
<ListView android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@android:id/empty"
android:text="No hay elementos"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>final String[] datos = new String[]{"Elem1","Elem2","Elem3","Elem4","Elem5"};
ArrayAdapter<String> adaptador =new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, datos);
setListAdapter(adaptador);setListAdapter(new ArrayAdapter(this,
R.layout.elemento_lista,
R.id.titulo,
array));this: es el contexto, con información sobre el entorno de la aplicación.
R.layout.elemento_lista: es una referencia de recurso a la vista que será utilizada repetidas veces para formar la lista.
R.id.titulo: identifica un id de la vista anterior que ha de ser un TextView. Su texto será reemplazado por el que se indica en el siguiente parámetro.
array: vector de String con los textos que serán visualizados en cada uno de los TextView.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight">
<ImageView android:id="@+id/icono"
android:layout_width="?android:attr/listPreferredItemHeight"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:src="@drawable/asteroide2"/>
<TextView android:id="@+id/titulo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/icono"
android:layout_alignParentTop="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:singleLine="true" />
<TextView android:id="@+id/subtitulo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Otro Texto"
android:layout_toRightOf="@id/icono"
android:layout_below="@id/titulo"
android:layout_alignParentBottom="true"
android:gravity="center"/>
</RelativeLayout>Si queremos algo más adaptable tendremos que escribir nuestro propio adaptador extendiendo la clase BaseAdapter. En esta clase habrá que sobreescribir los siguientes cuatro métodos:
View getView(int position, View convertView, ViewGroup parent)
Este método ha de construir un nuevo objeto View que será visualizado en la posición position .
int getCount()
Devuelve el número de elementos de la lista.
Object getItem(int position)
Devuelve el elemento en una determinada posición de la lista.
long getItemId(int position)
Devuelve el identificador de fila de una determinada posición de la lista.
Una intención representa la voluntad de realizar alguna acción o tarea, como realizar una llamada de teléfono o visualizar una página web. Una intención nos permite lanzar una actividad o servicio de nuestra aplicación o de una aplicación diferente.
Ilustración de la forma en que se entrega una intent implícita mediante el sistema para iniciar otra actividad.
[1] La actividad A crea unaIntent con una descripción de acción y la pasa a startActivity().
[2] El sistema Android busca en todas las apps un filtro de intents que coincida con la intent. Cuando se encuentra una coincidencia,
[3] el sistema inicia la actividad coincidente (actividad B) invocando su método onCreate() y pasándolo a la Intent.
Un filtro de intents es una expresión en el archivo de manifiesto de una aplicación que especifica el tipo de intents que el componente podría recibir. Por ejemplo, declarando un filtro de intents para una actividad, permite que otras aplicaciones inicien directamente la actividad con cierto tipo de intent. Así mismo, si no declara ningún filtro de intent para una actividad, solo se la puede iniciar con una intent explícita.
<activity android:name="MainActivity">
<!-- This activity is the main entry, should appear in app launcher -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="ShareActivity">
<!-- This activity handles "SEND" actions with text data -->
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>En concreto se utilizan intenciones cada vez que queramos:
Cuando se crea una Intención (es decir, se instancia un objeto de tipo Intent) esta contiene información de interés para que el sistema trate adecuadamente la intención o para el componente que recibe la intención. Puede incluir la siguiente información:
Nombre del componente: Esto es opcional, pero es la información clave que hace que una intent sea explícita, lo que significa que la intent debe enviarse solamente al componente de la aplicación definido en el nombre del componente. Sin un nombre de componente, la intent es implícita y el sistema decide qué componente debe recibir la intent conforme la información restante que esta contiene (como la acción, los datos y la categoría, que se describen a continuación). Por lo que si necesita iniciar un componente específico en su aplicación, debe especificar el nombre del componente.
Acción: Una cadena de caracteres donde indicamos la acción a realizar o en caso de un Receptor de anuncios (Broadcast receiver), la acción que tuvo lugar y que queremos reportar. La clase Intent define una serie de constantes para acciones genéricas que se enumeran a continuación:
Categoría: Complementa a la acción. Indica información adicional sobre el tipo de componente que ha de ser lanzado. El número de categorías puede ampliarse arbitrariamente. No obstante, en la clase Intent se definen una serie de categorías genéricas que podemos utilizar.
Datos: Referencia a los datos con los que trabajaremos.
Ejemplos de URIs son: tel:963228525, http://www.androidcurso.com, content://call_log/calls…
Ejemplos de tipos MIME son text/xml, image/jpeg, audio/mp3…
Extras: Información adicional que será recibida por el componente lanzado.
Está formada por un conjunto de pares variable/valor.
Estas colecciones de valores se almacenan en un objeto de la clase Bundle. Su utilización ha sido descrita en la sección Comunicación entre actividades.
intent.putExtra("usuario", "Pepito Perez")
intent.putExtra("edad", 27);Lanzar una actividad de forma explícita: utilizando el constructor Intent(Context contexto, Class<?> clase)
Intent intent = new Intent(this, AcercaDe.class);
startActivity(intent);Lanzar una actividad de forma implícita: podemos usar el constructor Intent(String action, Uri uri)
Intent intent = new Intent(Intent.ACTION_DIAL,URI.parse("tel:962849347");
startActivity(intent);Tabla con intenciones que podemos utilizar de aplicaciones Google