Curso de Android Studio
En esta entrada nos vamos a centrar en los fundamentos básicos de Android Studio, aprenderemos a manejar el entorno y a crear nuestro primer proyecto (videojuego) para plataformas móviles.
1 – Crear un proyecto
En el paso de nombrar el proyecto, se necesita crear un package name único para que Play Store pueda crear una URL única. Por lo que rellenaremos el campo Company Domain siguiendo la estructura:
jorge.example.com.likonet.aplicaciondeejemplo
2 – Elegir SDK
En el paso siguiente, se habla de los SDK. En principio no necesitamos ni saber qué son (aunque tenemos nociones). Tiene que ver con la versión de Android. Se facilita un enlace para ver las versiones ideales para nuestra aplicación. Les muestro un fragmento de una captura de pantalla de lo que muestra a fecha de este artículo:
La mejor versión es la 4.0 – Ice Cream Sandwich, que nos asegura más de un 90% de la cuota de mercado.
En el siguiente paso elegiremos una plantilla para nuestra aplicación. Seleccionamos Basic Activity para nuestro proyecto.
3 – Customize the Activity
Un Activity es una ventana de una aplicación, nos quedaremos con esa idea básica (aunque errónea). Al pulsar siguiente nombraremos esa ventana. Normalmente los valores están por defecto como sugiere la convención.
4 – Finish
Al pulsar finish, si es la primera vez, puede que se descarguen archivos necesarios de internet. Suele tardar un poco, y un poco más aún la primera vez.
5 – Mirando la interfaz
Aparecen dos archivos por defecto: MainActivity.java y content_main.xml. En la captura se ve dónde se hace click para observar mejor el contenido de ambos archivos, es en una pestaña vertical llamada Project a la izquierda – (el cursor en la captura está sobre ella).
6 – Estructura básica de un proyecto
Directorio Gradle scripts – Segundo directorio que aparece. Lo que se utiliza para compilar la aplicación. Sólo nos interesan los dos primeros archivos. El primero es importante para el proyecto, el segundo además, tendremos que modificarlo en el futuro para indicar la versión (importante) y otros datos, o para indicar las dependencias que necesita nuestra aplicación.
Directorio app – (6% tutorial completado)
- manifest
- AndroidManifest.xml: columna vertebral de la aplicación.
- java
- MainActivity.java: El código de nuestra aplicación
- res
- mimap: iconos, por densidades
- values:
- drawable: recursos gráficos, a tener en cuenta si hay más densidades, porque habrá que estructurar
- layout: representaciones gráficas de las activities. Por cada activity, un xml
- values
- strings: todas las strings de nuestra aplicación deberán estar aquí
- styles: estilos, temas.
7 – Emulador
Debido a las caracterísitcas de nuestra máquina, emular en cualquier dispositivo nos será complicado. Por suerte tenemos a mano varios dispositivos físicos con distintas dimensiones de pantalla y densidades. Esta reflexión me lleva a listar los que son los dos aspectos fundamentales de la compatibilidad de nuestras aplicaicones:
- Diseño: en cuanto a dimensiones de pantalla y densidades, entre otras cosas
- Versión de Android
Nosotros simplemente construimos la aplicación y luego la guardamos en una carpeta de nuestro smartphone, desde el que lo instalamos. Desde allí podemos borrarla cada vez que actualizamos la aplicación. No es muy elegante, se pierde algo de tiempo y es poco instructivo, pero nos sirve para al menos ver nuestros avances y poder seguir el tutorial.
Nos queda pendiente aprender cómo se administran las versiones de nuestra aplicación, pero llegaremos a eso al momento de subir la aplicación a PlayStore.
8 – Activity (9%)
- Concepto de Activity: una activity son, por decirlo toscamente, dos archivos relacionados, un .java y un .xml.
- Nuestras MainActivity es una clase que se extiende de la clase principal, Activity.
- El concepto de Activity procede del entorno Android, no existe fuera como tal.
- Fragmento de código del XML: tools:context=»aplicaciondeejemplo.likonet.com.example.jorge.myapplication.MainActivity»
- Fragmento de código del .java: tools:context=»setContentView(R.layout.activity_main);»
9 -10 LinearLayout y RelaviteLayout(12%)
Enumeramos los conceptos necesarios para instruirnos en esta parte del tutorial. La mayoría son pareceidos en otros entornos de programación y diseño.
- Concepto de layout
- Por qué elegir al principio LineraLayout para desarrollo de aplicaciones sencillas
- Orientación en LinearLayout
- Concepto de padding – por unas líneas añadidas por defecto
- match_parent y wrap_content en width y height – atributos indispensables
- Diferencias con RelativeLayout.
11 – TextView
- id – debe ser único
- strings – las cadenas de texto que tengan los textviews serán las que tengamos almacenadas en strings. En nuestro ejemplo, «saludo» (que devuelve «Hola Mundo»)
- grativy – parece el float del css
<TextView android:id="@+id/estaid" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/saludo" android:gravity="center_horizontal" />
En MainActivity.java, añadimos al principio del código:
public class MainActivity extends AppCompatActivity { // 1 declaramos un textview con un nombre TextView nombretexto;
Estas líneas cambiarán el texto del TextView el texto cuando se abra la aplicación:
// 2 Hacemos referencia al textview del html, asociándolo // con el creado más arriba, en 1 nombretexto = (TextView) findViewById(R.id.estaid); nombretexto.setText("Hola de nuevo");
La aplicación mostrará el texto «Hola de nuevo», no «Hola Mundo».
12 – EditText
Es un input. Ejemplo del código del layout de EditText. Tiene que tener un ancho y un alto. Obsérvese que uno de ellos utiliza android:hint para establecer el texto.
<EditText android:id="@+id/input1" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/escribe_aqui" /> <EditText android:id="@+id/input2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/pass" />
Hacemos lo mismo que hicimos con TextView en el .java
// 1 declaramos un textview con un nombre TextView nombretexto; //3 declaramos 2 inputs EditText et1; EditText et2; [...] // 2 Hacemos referencia al textview del html, asociándolo // con el creado más arriba, en 1 nombretexto = (TextView) findViewById(R.id.estaid); nombretexto.setText("Hola de nuevo"); // 4 Hacemos referencia et1 = (EditText) findViewById(R.id.input1); et2 = (EditText) findViewById(R.id.input2); // 5 podría escribir ahora et1. // y ver qué sugiere, como por ejemplo getText, setText... // lo que haremos será un mero cambio del texto por defecto del input et2.setText("Elige contraseña");
13 – ImageView (15%)
Después de guardar la imagen en /drawable, nuestro ImageView:
<ImageView android:id="@+id/idimagenfondo" android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/back3"/>
Así quedaría el MainActivity.java:
[...] public class MainActivity extends AppCompatActivity { // 1 declaramos un textview con un nombre TextView nombretexto; //3 declaramos 2 inputs EditText et1; EditText et2; // 6 esa imagen ImageView imagenuno; [...] // 2 Hacemos referencia al textview del html, asociándolo // con el creado más arriba, en 1 nombretexto = (TextView) findViewById(R.id.estaid); nombretexto.setText("Hola de nuevo"); // 4 Hacemos referencia et1 = (EditText) findViewById(R.id.input1); et2 = (EditText) findViewById(R.id.input2); // 7 referencia imagenuno = (ImageView) findViewById(R.id.idimagenfondo); // 5 podría escribir ahora et1. // y ver qué sugiere, como por ejemplo getText, setText... // lo que haremos será un mero cambio del texto por defecto del input et2.setText("Elige contraseña"); // 8 lo que queramos con la imagen. Se llama "imagenuno"...
14 – Botones (18%)
Primero debemos añadir el método OnclickListener a nuestra clase, escribiéndolo en MainActivity.java.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Al añadir lo que está en negrita nos paarecerá un error, porque no hemos escrito el método en neustro Main. El programa lo escribirá por nosotros, abajo del todo, si dejamo el ratón sobre las palabras subrayadas en rojo y luego hacemos click en el aviso y luego en «Implement Method». Este es el código que se añadirá:
@Override public void onClick(View v) { }
Nombrar los elementos:
EditText et2; Button botonuno; Button botondos; TextView textoesto;
Hacer referencias:
textoesto = (TextView) findViewById(R.id.texto); botonuno = (Button) findViewById(R.id.botonuno); botondos = (Button) findViewById(R.id.botondos); et2 = (EditText) findViewById(R.id.input2); // habilitar la opción para los botones botonuno.setOnClickListener(this); botondos.setOnClickListener(this);
Luego nosotros lo personalizaremos para que escuche nuestros botones:
@Override public void onClick(View v) { switch (v.getId()) { case R.id.botonuno; break; case R.id.botondos break; } }
Justo antes de los dos break, añadiremos lo que queremos que hagan nuestro botones:
public void onClick(View v) { switch (v.getId()) { case R.id.botonuno String dato = et2.getText().toString(); textoesto.setText(dato); break; case R.id.botondos textoesto.setText("Botón 2!!!!"); break; } }
Así quedaría la parte de XML, utilizaremos uno de los EditText (el de id «input2») anteriores:
<EditText android:id="@+id/input2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/pass" /> <TextView android:id="@+id/texto" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="texto a cambiar por botón 1 ó 2"/> <Button android:id="@+id/botonuno" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/boton1"/> <Button android:id="@+id/botondos" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/boton2"/>
15 – Toast
Mensajes de alerta al usuario. En el ejemplo, al pulsar un botón se muestra un mensaje de ese tipo.
Así se declara el botón en el XML.
<Button android:id="@+id/botontoast" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Toast it!!"/>
No olvidemos el .java:
Button boton_toast; [...] boton_toast = (Button) findViewById(R.id.botontoast); boton_toast.setOnClickListener(this);
Tenemos que añadir otro caso al switch:
public void onClick(View v) { switch (v.getId()) { // en el caso en el que pulsemos el botón invocar, // se mostrará una string de nuestra lista llamada "jimmibla4" case R.id.esteboton: message_skull.setText(R.string.jimmybla4); // para hacer aparecer el toast // Toast.makeText(contexto, texto, duración).show() case R.id.botontoast: Toast.makeText(getApplicationContext(),"Esto es toast",Toast.LENGTH_SHORT).show(); } }
Para nuestro ejercicio, eliminaremos el botón toast y añadiremos el mensaje emergente al botón que ya teníamos creado.
16 – Referencias a string.xml
Para acceder al contenido de un string a través del código, se usa la clase R
de la siguiente forma:
R.string.nombre_string
Por otro lado, en una definición XML se accede así:
@string/nombre_string
Un array de string puede declararse así:
–
Para acceder a la información de un array de strings desde el código:
–
17 – Crear nuevas actividades
En este paso del tutorial nos vamos a entretener para, además de crear un botón que abra una nueva actividad, crear otro botón en la nueva actividad para volver a la anterior.
No explicaremos la manera de crear los botones. Tan sólo los nombraremos para tener en cuenta su id. Crearemos un botón en nuestra activity con id idbotonnueva.
El «case» de este botón en el switch sería así:
case idbotonnueva: Intent miintent = new Intent(MainActivity.this,SecondActivity.class); startActivity(miintent); break;
Se puede trabajar de varias formas. El método Intent puede recibir un número variable de parámetros y tipos. En nuestro caso, lo usamos así: Intent(actividad actual, clase de la actividad objetivo).
Necesitamos hacer un par de cosas que hasta ahora no habíamos hecho:
- Hacer click derecho sobre el directorio app y buscar «crear actividad» en los desplegables, elegir una plantilla de actividad vacía y listo. Se habrán creado los dos archivos correspondientes. La llamamos SecondActivity
- Abrir AndroidMAnifest.xml y añadir la siguiente actividad, copiando-pegando-modificando el de la actividad anterior. Ya veremos los tags de la Secondactivity, incluimos dentro el mismo <intent-filter> de la mainactivity, sólo modificamos la línea del launcher, quitando LAUNCHER y poniendo DEFAULT:
<activity android:name=".SecondActivity" android:label="@string/title_activity_second" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>
3 Podemos crear el botón en el XML de la segunda activity, además de añadir el código necesario para el el botón funcione. Si este botón tiene de id idbotonvolver, este sería su «case»:
case idbotonvolver: Intent miintent2 = new Intent(SecondActivity.this,MainActivity.class); startActivity(miintent2); break;
18 – Pasar datos entre distintas activities.
En este capítulo se nos explica cómo pasar datos entre las dos ventanas ya creadas, usando un EditText para establecer qué datos se pasarán. Se explica el uso del «intent» para realizar estas acciones.
De momento dejamos este capítulo en blanco, lo vemos sencillo y no aplicable a nuestro proyecto actual.
19 – Eliminar la barra con el nombre en la aplicación
Añadir al Activity principal de la aplicación dentro del método onCreate(), en cada Activity:
requestWindowFeature(Window.FEATURE_NO_TITLE);
Quedando más o menos así, siempre delante el Request del SetContentView :
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main); }
Sin embargo, este método no funciona.
Encontramos el código relativo a la barra del nombre de la aplicación y el botón de acción con el símbolo del mail en el archivo: activity_nombre_dela_activity.xml. Eliminando Comentando el código XML que hace referencia a los elementos no deseados, no aparecen en el preview. Imaginamos que en values/styles deberemos cambiar los estilos heredados, porque estamos heredando cosas que no utilizamos. Si sólo comentamos, la aplicación se construye pero no se abre en el dispositivo de pruebas…
Dejamos aparcado este punto 19.
20 – Aplicaciones multi-idioma
Se gestionan de la misma manera que algunas aplicaciones web, creando subdirectorios con extensiones de idiomas en su nombre.
Crearemos dos carpetas con nombres values-es y values-fr al mismo nivel que la carpeta /values (dentro de /res, recursos). Pretendemos tener la aplicación en tres idiomas.
Dentro de las mismas, tendremos los mimos archivos que en /values, la carpeta del idioma por defecto (que suele ser el inglés). En los archivos de las carpetas de idiomas, en strings, traduciremos sólo las frases que están dentro de los tags XML, ya que los name de los tags <string> son para identificarlos.
El dispositivo se encargará de detectar el idioma adecuado y mostrar los valores del idioma correspondiente, siempre que los nombres de los directorios de las traducciones tengan la extensión adecuada según la convención.
21 – Sensores
Sensor de proximidad. Suele estar en la parte superior, es el encargado de tareas como apagar la pantalla cuando se acerca el teléfono a la oreja. Parece una cámara, aparece como un pequeño orificio en el dispositivo.
A nuestro layout principal (en nuestro ejemplo, LinearLayout) es necesario añadirle una id como la que sigue:
android:id=»@id+/linear»
Además, tendremos que extender la clase principal con implements SensorEventListener (del mismo modo que hicimos con el listener de los botones). Así se implementarán dos métodos que necesitaremos. Además habrá que declarar el sensor y el manager del sensor.
Podríamos hacer cambiar de color un elemento dependiendo de la proximidad, por ejemplo. Esta parte del ejercicio no es aplicable a nuestro proyecto. No profundizaremos.
22 – ListView
Elemento muy útil. Es básicamente una lista de elementos.
- Creamos ListView en XML. Le añadimos la id «idlista»
- Declaramos Listview en el código. Lo llamaremos «mi_lista». Después de hacer esto, ya vemos la lista en nuestro Preview.
- Asociamos «mi_lista» al elemento del XML con id «idlista» en el código, del mismo modo que lo hicimos con cada
malditoelemento. - Creamos un array de strings:
String[] nombrestring = new String[]{"elemento1","elemento2","elemento3","elemento4"};
- (Suponemos que podemos crear una función que rellene una string a partir del contenido de strings.xml, suponemos además que esto es una práctica común que aún no se ha explicado en el tutorial. No nos queremos adelantar demasiado para no adquirir malos hábitos, pero contemplamos la posibilidad de acceder a strings.xml en nuestro proyecto actual usando el conocimiento adquirido en el curso, creando nuestro propio método).
- Concepto de adaptador (para este ejercicio): la manera que tenemos de mostrar los elementos de una lista. El primer valor que debemos pasarle al adaptador es el entorno, para lo cual usaremos this. Hay varias maneras predefinidas, deberíamos consultar la documentación de Android Studio para elegir el adecuado. Usaremos uno muy básico para el ejercicio (y para casi cualquier proyecto simple). Al escribir en el código R.layout…. se nos muestran los formatos disponibles. Elegiremos simple_expandable_list_item_1 . El tercfer valor corresponde al array que queremos mostrar.
// Bajo las últimas líneas relativas a nuestras asociaciones, // creamos el adaptador de la string: this, formato, array ArrayAdapter<String> miadaptador = new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1,nombrestring); // aquí lo asociamos al LisView mi_lista mi_lista.setAdapter(miadaptador);
- Hasta el punto 6, si probamos la aplicación, se muestran los valores de la lista en el ListView
- Para que cada elmento de la lista muestre un Toast:
- Después de la última línea que hemos añadido, al escribir mi_lista.setOnclickListener… podemos escribir dentro del paréntesis la palabra «new» y pulsar Ctrl+Espacio. Aparecerá una lista de métodos que, al ser elegidos, rellenarán nuestro código con la implementación del método necesario (como se hizo más arriba al usar implements).
- El que ahora nos interesa es AdapterView.OnItemClickListener. El siguiente código es el necesario para que cada elemento de la lista muestre un Toast con un poco de texto y su posición:
mi_lista.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(getApplicationContext(),"Posición: "+position,Toast.LENGTH_SHORT).show(); } });
23 – Personalizar ListView
En realidad, este capítulo podría titularse cómo crear un adaptador para un tipo de dato concreto, y cómo crear ese tipo de dato. Igual que en el punto anterior, crearemos un adaptador, pero esta vez no le «pasaremos» como argumento un tipo de dato predefinido, sino una plantilla que crearemos, un archivo XML independiente. Además, programaremos el código necesario para que cada elemento de la lista tenga una imagen como encabezado. Llaman a esto «inflar» las vistas, por el uso de inflate.
En esta parte del ejercicio ampliamos el concepto de adaptador y su uso, así como descubrimos el potencial de las «plantillas» (como las llamamos por aquí): sólo con dos archivos HTML definimos el estilo de todos los elementos de la lista.
Para este ejercicio crearemos un proyecto nuevo, ya que esta implementación requiere mucho código. No obstante, vemos que esta es la manera más eficiente de dar aspecto personalizado a los elementos de nuestra aplicación. Lo llamaremos Adapterinflate.
Deja una respuesta