Beruflich Dokumente
Kultur Dokumente
Introducción
A través de los siguientes pasos, crearemos una aplicación en Android Studio que presente una vista de
tipo Dashboard con indicadores sobre consumo de combustible. Esta aplicación permitirá además
registrar una nueva entrada de consumo de combustible.
¡Vamos a codificar!
Creando el proyecto
Estando ubicados en la vista inicial de Android Studio seleccionamos la opción Start a new Android
Studio project.
Observaremos que de forma automática se establece pe.edu.upc.carcare como nombre de package para
la aplicación.
En la siguiente vista de la ventana seleccionamos los dispositivos objetivo para la aplicación. En nuestro
caso marcamos la casilla
Luego indicamos el nivel de API que utilizaremos como base mínima para la aplicación:
Minimum SDK: API 18: Android 4.3 (Jelly Bean)
Si hacemos click en la opción Help me choose, notaremos que se muestra una vista con los niveles de
API y la lista de features de Android que se encuentran disponibles a partir de dicha versión.
Se presentará en la siguiente vista una galería de Activities bajo el título Add and Activity to Mobile. De
dicha galería seleccionamos Basic Activity.
Con ello se presenta la vista con el título Customize the Activity. En los campos completamos los
siguientes valores:
Activity Name: MainActivity
Layout Name: activity_main
Title: Car Care Dashboard
Menu Resource Name: menu_main.
Dejamos los demás campos en sus valores por defecto y presionamos el botón Finish.
Organizando el proyecto
A continuación, vamos a realizar modificaciones sobre la nomenclatura de paquetes de java de tal forma
que se refleje una arquitectura organizada en capas. En el árbol del proyecto, dentro del nodo java y el
paquete pe.edu.upc.carcare, hacemos clic derecho y seleccionamos New > Package.
Realizamos esta acción dos veces para crear los siguientes sub-paquetes dentro de
pe.edu.upc.carcare:
activities
models
Hacemos doble click en el archivo de layout content_main.xml de tal forma que se pueda visualizar su
contenido si éste no se encuentra aún abierto.
Vamos a realizar las modificaciones de tal forma que la interfaz se aprecie de la siguiente manera:
Seleccionamos la pestaña Text en la parte inferior de la ventana del archivo content_main.xml.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"/>
</RelativeLayout>
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="2"
android:rowCount="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="AVG Km/Gal"
android:id="@+id/textView"
android:gravity="start"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Total Logs"
android:id="@+id/textView2"
android:layout_gravity="right"
android:gravity="end"/>
</GridLayout>
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:rowCount="1"
android:columnCount="2">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="30"
android:id="@+id/avgKilometersPerGallonTextView"
android:gravity="start"
android:textSize="@dimen/indicator_size"
android:textStyle="bold"
android:textColor="@color/colorAccent"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/totalLogsTextView"
android:gravity="end"
android:layout_gravity="right"
android:textSize="@dimen/indicator_size"
android:text="14"
android:textStyle="bold"
android:textColor="@color/colorAccent"/>
</GridLayout>
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="2"
android:rowCount="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LAST Km/Gal"
android:id="@+id/textView5"
android:gravity="start"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Total Gallons"
android:id="@+id/textView6"
android:gravity="right"
android:layout_gravity="right"/>
</GridLayout>
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="2"
android:rowCount="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="8.9"
android:id="@+id/lastKilometersPerGallonTextView"
android:textSize="@dimen/indicator_size"
android:textStyle="bold"
android:textColor="@color/colorAccent"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="102"
android:id="@+id/totalGallonsTextView"
android:textSize="@dimen/indicator_size"
android:layout_gravity="right"
android:textStyle="bold"
android:textColor="@color/colorAccent"/>
</GridLayout>
</LinearLayout>
Tal como hemos realizado antes, adicionamos al proyecto un Nuevo Activity, haciendo clic derecho
sobre el subpaquete activities y seleccionando desde el menú contextual la opción New > Activity >
Empty Activity. En el diálogo New Android Activity establecemos el valor de NewFuelUpActivity en
Activity Name. Validamos que el Layout Name tenga el valor activity_new_fuel_up y que Package
name tenga el valor de pe.edu.upc.carcare.activities. Hacemos clic en Finish para que se cierre el
diálogo y se cree el Activity.
Abrimos para edición el archivo activity_new_fuel_up.xml. Vamos a realizar los cambios en el archivo
de tal forma que la interfaz se aprecie de la siguiente manera.
Para ello nos ubicamos en la parte inferior y seleccionamos la pestaña Text. Estando activo el editor de
código de layout, realizamos los siguientes cambios de tal forma que el archivo se aprecie de esta
manera.
Así hemos diseñado la interfaz de la vista que nos permitirá adicionar una nueva entrada de registro de
combustible.
Nos corresponde en los siguientes pasos trabajar en la capa modelo que concentrará la funcionalidad de
persistencia de información.
Antes de proceder con la implementación de la capa de persistencia, vamos a integrar al proyecto una
biblioteca que contiene un orm framework que nos será de gran utilidad en dicha labor. Dicha biblioteca
es SugarORM y podemos revisar su documentación en http://satyan.github.io/sugar/.
Abrimos para edición el archivo gradle del módulo app, ubicado en el árbol de proyecto dentro de la
sección Gradle Scripts.
Dentro del archivo agregamos la siguiente línea de código al final del bloque dependencies:
compile 'com.github.satyan:sugar:1.5'
Una vez realizado el cambio notamos un mensaje de Android Studio en la parte superior con un enlace
Sync now. Hacemos clic en el enlace para que se descargue e integre la biblioteca en el proyecto.
Agregando el modelo Entry
A continuación, procedemos con la creación de la clase que representa a una entrada de registro de
combustible. Apoyándonos en la funcionalidad que nos ofrece SugarORM, vamos a hacer que esta clase
se vuelva persistente cumpliendo con dos requisitos: será un descendiente de SugarRecord y además
tendrá una versión del método constructor sin parámetros.
Ubicados en el árbol de proyecto, en el subpaquete models previamente creado, hacemos clic derecho
en el subpaquete models y desde el menú contextual seleccionamos New > Java Class. En el diálogo
Create New Class, establecemos el valor de Name: en Entry. Dejamos los demás valores por defecto y
hacemos clic en OK para que se cierre el diálogo y se cree la clase.
Verificamos que el archivo Entry.java esté abierto para edición. Realizamos los siguientes cambios en el
archivo de tal forma que se aprecie de la siguiente manera
package pe.edu.upc.carcare.models;
import com.orm.SugarRecord;
import java.util.Date;
public Entry() {
Con ello, dejamos definida una clase que nos permite registrar la fecha en que se produce la carga de
combustible, el valor en dicho momento del odómetro, el precio por galón y la cantidad de galones
consumidos.
Ahora que tenemos representada como clase una entrada de registro, podemos avanzar un paso más e
implementar una clase que encapsule la funcionalidad de persistencia. Para ello vamos a crear una clase
CarCareService que contenga la siguiente funcionalidad.
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
Guardamos los cambios en CarCareService.java.
Tal como hemos realizado anteriormente, vamos a adicionar una clase de Java al proyecto. Para ello nos
ubicamos en el árbol del proyecto, en el paquete raíz pe.edu.upc.carcare, hacemos clic derecho y
del menú contextual seleccionamos New > Java Class. En el diálogo New Android Class,
establecemos como valor para Name: en CarCareExpressApplication. Dejamos los valores por defecto
y seleccionamos OK para cerrar el diálogo y proceder con la creación de la clase.
Verificamos que esté abierto para edición el archivo CarCareExpressApplication.java. Realizamos las
siguientes modificaciones sobre el código de declaración de la clase, de tal forma que se aprecie como
sigue.
Ahora que tenemos creada la clase de tipo Application, necesitamos configurar la aplicación para que
Android instancie nuestra clase Application y no la clase por defecto. Para ello, abrimos para edición el
archivo AndroidManifest.xml.
android:name="pe.edu.upc.carcare.CarCareExpressApplication"
De esta manera le decimos a Android que, al momento de instanciar la aplicación para ejecutarla, tome
nuestra clase CarCareExpressApplication como la clase Application.
En los siguientes pasos nos enfocaremos en los activities, los cuales van a interactuar con la
funcionalidad que hemos implementado en las clases del modelo.
TextView avgKilometersPerGallonTextView;
TextView totalLogsTextView;
TextView lastKilometersPerGallonTextView;
TextView totalGallonsTextView;
avgKilometersPerGallonTextView = (TextView)
findViewById(R.id.avgKilometersPerGallonTextView);
totalLogsTextView = (TextView) findViewById(R.id.totalLogsTextView);
lastKilometersPerGallonTextView = (TextView)
findViewById(R.id.lastKilometersPerGallonTextView);
totalGallonsTextView = (TextView) findViewById(R.id.totalGallonsTextView);
Las líneas adicionadas líneas arriba nos permiten vincular los widgets que existen en la interfaz de
usuario con variables que nos permitan establecer los valores para los indicadores en base a la
información en la base de datos.
A continuación, modificamos el bloque de código para el cuerpo del método onClick() de la clase
View.OnClickListener para el Floating Action Button fab, tal como se aprecia a continuación.
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(getApplicationContext(), NewFuelUpActivity.class));
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
Ello nos permite invocar al activity NewFuelUpActivity cuando el usuario toca el Floating Action
Button.
Luego de ello, vamos a adicionar un método refreshDashboard() que nos servirá para presentar los
valores de indicadores en pantalla. Utilizaremos una variable local service de tipo CarCareService y
los métodos que hemos implementado previamente para obtener indicadores.
this.avgKilometersPerGallonTextView.setText(String.valueOf(service.getAvgKilometersPer
Gallon()));
this.lastKilometersPerGallonTextView.setText(String.valueOf(service.getLastKilometersP
erGallon()));
this.totalGallonsTextView.setText(String.valueOf(service.getTotalGallons()));
this.totalLogsTextView.setText(String.valueOf(service.getTotalLogs()));
Log.d("CarCareExpress", "Total Gallons: " +
this.totalGallonsTextView.getText().toString());
Log.d("CarCareExpress", "Avg Km/Gal: " +
this.avgKilometersPerGallonTextView.getText().toString());
Log.d("CarCareExpress", "Last Km/Gal: " +
this.lastKilometersPerGallonTextView.getText().toString());
Log.d("CarCareExpress", "Total Logs: " +
this.totalLogsTextView.getText().toString());
Nos corresponde ahora adicionar un Override del método onResume(), que se encargue de actualizar
el Dashboard de indicadores cada vez que se hace visible el activity. Adicionamos antes del cierre de
declaración de la clase MainActivity el siguiente método.
@Override
protected void onResume() {
super.onResume();
refreshDashboard();
Button addButton;
EditText lastOdometerEditText;
EditText costPerGallonEditText;
EditText gallonsEditText;
A continuación, ubicamos el método onCreate() y adicionamos al final del método las siguientes líneas.
@Override
public void onClick(View v) {
((CarCareExpressApplication) getApplication()).getCarCareService().addFuelUpEntry(
lastOdometerEditText.getText().toString(),
costPerGallonEditText.getText().toString(),
gallonsEditText.getText().toString());
finish();
}
});
Como podemos apreciar, estas líneas de código realizan lo siguiente. Por un lado se establecen los
vínculos entre las variables previamente declaradas y los widgets de la UI. Por otro lado, se establece el
comportamiento cuando el usuario hace touch en el Button addButton, que incluye el invocar al método
addFuelEntry() para realizar una adición de registro a la base de datos. Finalmente se invoca al método
finish() del activity para cerrarlo y retornar a MainActivity.
Presionamos Ctrl+R (ó Cmd+R en Mac) para iniciar la ejecución de la aplicación. Luego de seleccionar el
AVD (Android Virtual Device) de ejecución, notamos que el comportamiento de la aplicación se
desarrolla como hemos previsto.
Se presenta MainActivity mostrando los valores actuales de indicadores y al hacer touch sobre el
Floating Action Button, se presenta NewFuelUpActivity para permitir al usuario registrar una entrada de
consumo de combustible. Al retornar a MainActivity observamos que los indicadores se actualizan en
base a la nueva información.