profesor: roberto mart nez rom n examen informando al mundo · 2020-04-01 · examen informando al...

19
Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos móviles Profesor: Roberto Martínez Román Ing. Roberto Martínez Román - [email protected] Problema Crear una app para Android que permita consultar el estado actual de cada país con respecto a la pandemia de Covid-19.

Upload: others

Post on 19-Apr-2020

9 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

ExamenInformando al mundo

Todo sobre el Covid-19

Proyectos de desarrollo para dispositivos móvilesProfesor: Roberto Martínez Román

Ing. Roberto Martínez Román - [email protected]

Problema• Crear una app para Android que permita consultar

el estado actual de cada país con respecto a la pandemia de Covid-19.

Page 2: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

Crear el proyecto

Ing. Roberto Martínez Román - [email protected]

RecyclerView

• Agrega un componente RecyclerView a la pantalla principal. Espera a que se sincronice el proyecto.

Page 3: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

Renglones del RecyclerView• Primero, diseñamos la vista para cada renglón.

Ing. Roberto Martínez Román - [email protected]

Diseñando el renglón

• Agrega un Layout Resource File al proyecto.

Page 4: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

Diseño del renglón• Agrega componentes como se ve a continuación.

1/4 3/4

Ambos LinearLayout:imgBandera

Ing. Roberto Martínez Román - [email protected]

Clase Pais• Esta clase sirve para crear objetos que representan

un país. Por ahora solo tendrá dos variables de instancia:• Nombre• Casos

Pais- nombre: String- casos: Int

<Interface>Comparable<T>

+ compareTo(otro:Pais) : Int

Page 5: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

Adaptador del RecyclerView• El componente RecyclerView toma los valores para

sus renglones de un adaptador.

class AdaptadorPais (private val contexto: Context, var arrPaises: Array<Pais>) : RecyclerView.Adapter<AdaptadorPais.RenglonMateria>(){}

Ing. Roberto Martínez Román - [email protected]

Adaptador

class AdaptadorPais (private val contexto: Context, var arrPaises: Array<Pais>) : RecyclerView.Adapter<AdaptadorPais.RenglonMateria>(){

}

Adaptador

2 variables de instancia

Constructor Clase Pais

AdaptadorPais- contexto: Context- arrPaises: Array<Pais>

Representa la vistadel renglón

Llama al constructorde la superclase

Page 6: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

• Crea la clase RenglonMateria

La clase RenglonMateria

inner class RenglonMateria (var vistaRenglon: View) : RecyclerView.ViewHolder(vistaRenglon){

}

Hereda de

Variable de instancia y Constructor

Ing. Roberto Martínez Román - [email protected]

Métodos del adaptador

Implementa los 3 métodos del adaptador.

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RenglonMateria { // Cuando se crea un renglón }

override fun getItemCount(): Int { // Regresa el número de renglones }

override fun onBindViewHolder(holder: RenglonMateria, position: Int) { // Cuando se llena de valores el renglón 'position' }

Page 7: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

Métodosoverride fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RenglonMateria { val vista = LayoutInflater.from(contexto).inflate(R.layout.renglon_pais, parent, false) return RenglonMateria(vista) }

override fun getItemCount(): Int { return arrPaises.size }

override fun onBindViewHolder(holder: RenglonMateria, position: Int) { val pais = arrPaises[position] holder.vistaRenglon.tvPais.text = pais.nombre holder.vistaRenglon.tvCasos.text = "${pais.casos}" holder.vistaRenglon.imgBandera.setImageResource(R.drawable.flag) }

Agrega un archivo en res/drawable

Ing. Roberto Martínez Román - [email protected]

Asignando el adaptador• Primero, declara la variable de instancia.var adaptadorPais: AdaptadorPais? = null

• En el método onCreate, creamos el adaptador y lo asignamos al RecyclerView.

var layout = LinearLayoutManager(this) layout.orientation = LinearLayoutManager.VERTICAL recyclerPaises.layoutManager = layout

adaptadorPais = AdaptadorPais(this, Pais.arrPaises) recyclerPaises.adapter = adaptadorPais

Page 8: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

Corriendo la app

Ing. Roberto Martínez Román - [email protected]

Algunos ajustes• Al hacer click sobre un renglón no hay

retroalimentación.android:background="?android:attr/selectableItemBackground" android:clickable="true" android:focusable="true"

• No se muestra una línea entre renglones.val divisor = DividerItemDecoration(this, layout.orientation) recyclerPaises.addItemDecoration(divisor)

Page 9: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

Networking• Vamos a usar un framework para simplificar la

descarga de información.

• https://amitshekhar.me/Fast-Android-Networking/

Ing. Roberto Martínez Román - [email protected]

Agrega la librería

Agrega la librería en el archivo build.gradle y sincroniza.implementation 'com.amitshekhar.android:android-networking:1.0.2'

Agrega el permiso de Internet en el manifiesto.<uses-permission android:name="android.permission.INTERNET" />

En el método onCreate de la clase principal inicializa la librería.AndroidNetworking.initialize(getApplicationContext());

Page 10: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

Descargar la información• Hay un servicio web que regresa la información en

formato JSON:https://corona.lmao.ninja/countries?sort=country

[{"country":"Zimbabwe","countryInfo":{"_id":716,"iso2":"ZW","iso3":"ZWE","lat":-20,"long":30,"flag":"https://raw.githubusercontent.com/NovelCOVID/API/master/assets/flags/zw.png"},"cases":8,"todayCases":0,"deaths":1,"todayDeaths":0,"recovered":0,"active":7,"critical":0,"casesPerOneMillion":0.5,"deathsPerOneMillion":0.07,"updated":1585713016367},{"country":"Zambia","countryInfo":{"_id":894,"iso2":"ZM","iso3":"ZMB","lat":-15,"long":30,"flag":"https://raw.githubusercontent.com/NovelCOVID/API/master/assets/flags/zm.png"},"cases":36,"todayCases":0,"deaths":0,"todayDeaths":0,"recovered":0,"active":36,"critical":0,"casesPerOneMillion":2,"deathsPerOneMillion":null,"updated":1585713016365},

Ing. Roberto Martínez Román - [email protected]

Descargar• Escribe el método descargarInformacion y lo llamas al

final del método onCreate.private fun descargarInformacion() { val direccion = "https://corona.lmao.ninja/countries?sort=country"

AndroidNetworking.get(direccion) .build() .getAsJSONArray(object: JSONArrayRequestListener { override fun onResponse(response: JSONArray?) { // Descarga exitosa }

override fun onError(anError: ANError?) { // Error en la descarga } }) }

Inicia la descarga en

segundo plano

Listener

Page 11: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

La función completaprivate fun descargarInformacion() { AndroidNetworking.get("https://corona.lmao.ninja/countries?sort=country") .build() .getAsJSONArray(object: JSONArrayRequestListener { override fun onResponse(response: JSONArray?) { if (response != null ) { var arrPaises = mutableListOf<Pais>() for (i in 0 until response.length()) { val dPais = response.get(i) as JSONObject val nombre = dPais.getString("country") val casos = dPais.getInt("cases") arrPaises.add(0, Pais(nombre, casos)) } adaptadorPais?.arrPaises = arrPaises.toTypedArray() adaptadorPais?.notifyDataSetChanged() } }

override fun onError(anError: ANError?) { println(anError) Toast.makeText(baseContext, "Error en la descarga", Toast.LENGTH_LONG).show() } }) }

Ing. Roberto Martínez Román - [email protected]

Corre la app

Page 12: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

Información del país• Crea una actividad para mostrar la información del

país.

• Click derecho sobre el paquete, New, Activity, Empty Activity.

Ing. Roberto Martínez Román - [email protected]

Diseño de la vista128x128

Page 13: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

Mostrar país

• Detectar click en el RecyclerView y lanzar la segunda pantalla.

• Crea la interface ListenerRecycler

interface ListenerRecycler { fun itemClicked(position: Int) }

Ing. Roberto Martínez Román - [email protected]

Implementando la interface• Implementa la interface y sobrescribe el método.class MainActivity : AppCompatActivity(), ListenerRecycler

• Funciónoverride fun itemClicked(position: Int) { val nombrePais = adaptadorPais.arrPaises.get(position).nombre val intDatosPais = Intent(this, DatosPaisActiv::class.java) intDatosPais.putExtra("PAIS", nombrePais) startActivity(intDatosPais) }

Page 14: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

¿Quién genera el evento?

• En la clase AdaptadorPais, agrega la variable de instancia.

var listener: ListenerRecycler? = null

• Agrega el listener del renglón en el método onBindViewHolder.

holder.vistaRenglon.setOnClickListener { listener?.itemClicked(position) }

• Asigna al adaptador el listener.adaptadorPais?.listener = this

Ing. Roberto Martínez Román - [email protected]

Corre la app

Page 15: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

Muestra nombre del país• En la clase DatosPaisActiv, en el método onCreate.val nombre = intent.getStringExtra("PAIS") tvNombrePais.text = nombre

Sigue descargar la bandera y los

datos

Ing. Roberto Martínez Román - [email protected]

• Los datos que se requieren ya se descargaron desde la actividad previa. Para simplificar y practicar la descarga lo haremos con un endpoint diferente.

https://corona.lmao.ninja/countries/:nombrePais

Descarga de los datos

Final del método onCreate

{"country":"Argentina","countryInfo":{"_id":32,"iso2":"AR","iso3":"ARG","lat":-34,"long":-64,"flag":"https://raw.githubusercontent.com/NovelCOVID/API/master/assets/flags/ar.png"},"cases":1054,"todayCases":0,"deaths":28,"todayDeaths":1,"recovered":248,"active":778,"critical":0,"casesPerOneMillion":23,"deathsPerOneMillion":0.6,"updated":1585759687308}

Page 16: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

Función descargarDatosPaisprivate fun descargarDatosPais(nombrePais: String?) { val direccion = "https://corona.lmao.ninja/countries/$nombrePais" AndroidNetworking.get(direccion) .build() .getAsJSONObject(object: JSONObjectRequestListener { override fun onResponse(response: JSONObject?) { val casos = response?.get("cases") tvCasosPais.text = "$casos" val recuperados = response?.get("recovered") tvRecuperadosPais.text = "$recuperados" val decesos = response?.get("deaths") tvDecesosPais.text = "$decesos" }

override fun onError(anError: ANError?) { Toast.makeText(this@DatosPaisActiv, "Error: $anError", Toast.LENGTH_LONG).show() } }) }

Ing. Roberto Martínez Román - [email protected]

Descargar la banderaprivate fun descargarDatosPais(nombrePais: String?) { val direccion = "https://corona.lmao.ninja/countries/$nombrePais" AndroidNetworking.get(direccion) .build() .getAsJSONObject(object: JSONObjectRequestListener { override fun onResponse(response: JSONObject?) { val casos = response?.get("cases") tvCasosPais.text = "$casos" val recuperados = response?.get("recovered") tvRecuperadosPais.text = "$recuperados" val decesos = response?.get("deaths") tvDecesosPais.text = "$decesos"

val dInfo = response?.get("countrInfo") as JSONObject val dirBandera = dInfo?.get("flag") as String? descargarBandera(dirBandera) }

override fun onError(anError: ANError?) { Toast.makeText(this@DatosPaisActiv, "Error: $anError", Toast.LENGTH_LONG).show() } }) }

Page 17: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

La función descargarBanderaprivate fun descargarBandera(dirBandera: String?) { if (dirBandera != null) { AndroidNetworking.get(dirBandera) .build() .getAsBitmap(object: BitmapRequestListener { override fun onResponse(response: Bitmap?) { imgBanderaPais.setImageBitmap(response) }

override fun onError(anError: ANError?) { Toast.makeText(this@DatosPaisActiv, "Error: $anError", Toast.LENGTH_LONG).show() } }) } }

👊👍

Ing. Roberto Martínez Román - [email protected]

Finalmente...• Para descargar los casos por día, usamos el

endpoint: https://corona.lmao.ninja/v2/historical/:country

• Para la gráfica, usamos el framework:

https://github.com/PhilJay/MPAndroidChart

Final del método onCreate

{"country":"Mexico","provinces":[],"timeline":{"cases":{..., "3/17/20":82,"3/18/20":93,"3/19/20":118,"3/20/20":164,"3/21/20":203,"3/22/20":251,"3/23/20":316,"3/24/20":367,"3/25/20":405,"3/26/20":475,"3/27/20":585,"3/28/20":717,"3/29/20":848,"3/30/20":993,"3/31/20":1094},

Page 18: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

descargarDatosGraficarprivate fun descargarDatosGraficar(nombrePais: String?) { val direccion = "https://corona.lmao.ninja/v2/historical/$nombrePais" AndroidNetworking.get(direccion) .build() .getAsJSONObject(object: JSONObjectRequestListener { override fun onResponse(response: JSONObject?) { val timeline = response?.get("timeline") as JSONObject? val casos = timeline?.get("cases") as JSONObject var indice = 0f for (fecha in casos.keys()) { val valor = casos.get(fecha) as Int if (valor>0) { val entrada = Entry(indice, valor+0f) entries.add(entrada) indice += 1 } } }

override fun onError(anError: ANError?) {

}

}) }

Definida en la librería para

graficar

Variable de instancia. Es un

ArrayList de Entry

Ing. Roberto Martínez Román - [email protected]

Agregar librería para graficar• En el archivo build.gradle del proyecto, agrega y

sincroniza (allprojects, repositories):maven { url 'https://jitpack.io' }

• En el archivo build.gradle de la app, agrega y sincroniza:implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'

• Agrega un componente para mostrar la gráfica. No olvides los constraints.

<com.github.mikephil.charting.charts.LineChart android:id="@+id/lineChart" />

Page 19: Profesor: Roberto Mart nez Rom n Examen Informando al mundo · 2020-04-01 · Examen Informando al mundo Todo sobre el Covid-19 Proyectos de desarrollo para dispositivos m viles Profesor:

Ing. Roberto Martínez Román - [email protected]

El método crearGrafica

Llama al método después de procesar todas las fechas de datos.private fun crearGrafica() { val datos = LineDataSet(entries, "Personas") datos.setDrawValues(true) datos.lineWidth = 3f

lineChart.data = LineData(datos) lineChart.description.text = "COVID-19" lineChart.animateX(1800, Easing.EaseInOutSine) }

Ing. Roberto Martínez Román - [email protected]

Resultado final

👊

👍