CategoriasFlutterProgramación

? Como tomar una foto con Flutter o elegir una foto de la galería.

¡Hola! Ultimamente he estado trabajando en una app que requiere tomar una foto desde la app o de la galeria y mostrarla al usuario. He aprendido un par de cosas implementando esta feature y he querido compartirlo por acá. Existen varias formas de tomar una foto utilizando la cámara pero en esta oportunidad vamos a utilizar el imagePicker plugin.

Empecemos por las dependencias.

Como primer paso, vamos a agregar los plugins a nuestras dependencias. Abrimos nuestro pubspec.yaml y agregamos los siguientes plugins:

  • camera: Este plugin nos ayudará a trabajar con las cámaras de los dispositivos.
  • path_provider: Este plugin nos proporciona el path correcto para saber donde almacenar las imagenes en nuestro dispositivo, ya que cambian entre una plataforma y otra.
  • image_picker este nos ayuda a seleccionar una foto de la galería.

Despues de agregar estos plugins nuestro pubspec.yaml debería verse así.

name: fluttercamera
description: A Flutter project that takes a picture and shows the preview.
version: 1.0.0+1

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  camera:
  path_provider:
  path:
  image_picker:

  cupertino_icons: ^0.1.2

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:

  uses-material-design: true

Aumentamos la versión minima de Android

El plugin de camera en Flutter solo funciona con sdk 21 en adelante en Android, lo que quiere decir que solo dispositivos Android con sistema operativo Lollipop o superior pueden utilizar una app con este plugin.

Para esto vamos a abrir el archivo build.gradle ubicado en android/app/build.gradle y buscar la linea que dice «minSdkVerrsion«. Finalmente cambiamos la versión de 16 a 21.

Luego de cambiar la versión debería verse así

¡Creemos nuestro primer Screen!

Para empezar vamos a crear un StatefulWidget llamado PhotoPreviewScreen. Debería verse de esta manera.

class PhotoPreviewScreen extends StatefulWidget {
  @override
  _PhotoPreviewScreenState createState() => _PhotoPreviewScreenState();
}

class _PhotoPreviewScreenState extends State<PhotoPreviewScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(

    );
  }
}

Ahora, vamos a crear un Scaffold con un widget Column centrado el cual va a mostrar una vista previa de nuestra imagen después que tomemos una foto o la seleccionemos de la galería. Y como paso final vamos a agregar un floatingActionButton, que al tocar nos mostrará un dialogo con las opciones para elegir una foto de la galería o desde la cámara.

class PhotoPreviewScreen extends StatefulWidget {
  @override
  _PhotoPreviewScreenState createState() => _PhotoPreviewScreenState();
}

class _PhotoPreviewScreenState extends State<PhotoPreviewScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _setImageView()
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _showSelectionDialog(context);
        },
        child: Icon(Icons.camera_alt),
      ),
    );
  }

¡Genial! Ahora seguramente te estés preguntando qué hace el _setImageView() y el _showSelectionDialog(Context).

El _setImageView() es un método que devuelve un Image Widget en caso de que la imagen obtenida no sea nula, de lo contrarío devolverá un Text Widget con un mensaje de Error. El método _showSelectionDialog(Context) muestra un dialogo con dos opciones, seleccionar una imagen de galería o de la cámara.

Empecemos creando el último, este método debe usar la función showDialog() y pasarle el Context y un Builder el cual va crear un AlertDialog con un titulo y dos opciones.

En el constructor del AlertDialog, vamos a pasar como contenido un SingleChildScrollView el cual es un Widget que nos ayudará a hacer scroll en la lista, y como child de este Widget vamos a pasarle un ListBody con dos GestureDetector como hijos para detectar cuándo el usuario ha tocado el texto.

Cada GestureDetector va a tener un Text Widget con el texto «Galería» y «Cámara» respectivamente. Y cada Text widget tambíen tendrá como parámetro de su función onTap el método _openGallery() y openCamera() segun corresponda. Estos métodos los crearemos más adelante. Al terminar el método _showSelectionDialog(context) estará así.

Future<void> _showSelectionDialog(BuildContext context) {
    return showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
              title: Text("From where do you want to take the photo?"),
              content: SingleChildScrollView(
                child: ListBody(
                  children: <Widget>[
                    GestureDetector(
                      child: Text("Gallery"),
                      onTap: () {
                        _openGallery(context);
                      },
                    ),
                    Padding(padding: EdgeInsets.all(8.0)),
                    GestureDetector(
                      child: Text("Camera"),
                      onTap: () {
                        _openCamera(context);
                      },
                    )
                  ],
                ),
              ));
        });
  }

Ahora al tocar nuestro FloatingActionButton debería mostrar un Dialog como este.

Ahora a utilizar el plugin ImagePicker

Ahora vamos a agregarle la lógica a nuestro método _openGallery(context). Lo primero que vamos a hacer es crear un Field llamado imageFile, el cual va a ser una variable de tipo File en nuestro _LandingScreenState. Luego vamos a utilizar la función del ImagePicker, llamada pickImage() y le vamos a pasar como parámetro el enum ImageSource.gallery. Esta función es asíncrona así que vamos a tener que utilizar las palabras reservadas async y await. Luego vamos a almacenar esta variable y asignarla a nuestra variable imageFile. Como paso final, vamos a llamar al método setState() para notificar que el State ha cambiado. Y nuestra función deberá verse así.

void _openGallery(BuildContext context) async {
    var picture = await ImagePicker.pickImage(source: ImageSource.gallery);
    this.setState(() {
      imageFile = picture;
    });
    Navigator.of(context).pop();
  }

La función _openCamera(Context) es casi igual, la unica diferencía que tiene al respecto es que esta utiliza el enum imageSource.camera en lugar de gallery. Al realizar este cambio tu función de _openCamera() deberá verse así.

void _openCamera(BuildContext context) async {
    var picture = await ImagePicker.pickImage(source: ImageSource.camera);
    this.setState(() {
      imageFile = picture;
    });
    Navigator.of(context).pop();
  }

Previsualización

¿Recuerdas aquella función que mencionamos al principio llamada _setImageView()? Pues no podemos olvidarnos de ella. Para ello vamos a verificar si nuestra variable imageFile es distinta de null. Si lo es, devolvemos un Image Widget con la variable que teniamos almacenada y si aún es nula pues devolvemos un texto que diga que debemos seleccionar una imagen.

Así se vería la función terminada.

Widget _setImageView() {
    if (imageFile != null) {
      return Image.file(imageFile, width: 500, height: 500);
    } else {
      return Text("Please select an image");
    }
  }

Así es como se vería la app al final, luego de seleccionar una imagen de la galería.

Eso es todo

Espero que te haya gustado este artículo. Si te interesan mas contenido sobre Flutter o Dart puedes seguirme en las redes sociales.

Instagram.

Twitter.

?Adémas no te pierdas ningun artículo uniendote a mi newsletter

Puedes registrarte haciendo click acá debajo ?.

? Haz click aquí para unirte a la newsletter

CategoriasProgramación

Que es un unit test

Que es un unit test (Prueba unitaria)

Hola! Probablemente hayas visto en ofertas de trabajo la siguiente frase, «Experiencia con pruebas unitarias y TDD.» Pero si eres como yo y no tienes idea sobre tests, has oído de ellos, sabes que existen y sabes que las buenas compañías lo usan. Pero, ¿qué son y cómo funcionan?

? Empecemos con un test

Cuando alguien de QA (Quality assurance, aquellos que prueban tu app y encuentran fallos que tu no conocías) se acerca a mi y me pregunta si estoy seguro sobre lo que hace mi código, mi respuesta siempre es no, y no es porque no confié en mis habilidades de programación, es porque soy humano y como todo ser humano cometemos errores. Es por esto que empece a aprender sobre testing ya que los test pueden ayudarte a conseguir los errores que vas a introducir en el futuro.

Un test ayuda a probar algo, en nuestro caso, que nuestro código vaya como lo hemos planeado. Con mis simples palabras podría decir que un test es código que tu escribes para verificar que el código que vas a tener en producción funciona y hace lo que esperas que haga.

?‍??‍?Unidad

Una unidad es algo individual, digamos que un elemento, muchos elementos pueden crear algo mas grande que ellos. En nuestro caso, una unidad puede ser una clase o una función la cual junto con otras clases u otras funciones pueden crear una app mas compleja.

Al hacer pruebas de cada una de las unidades estamos haciendo pruebas unitarias.

?‍??‍? La prueba unitaria

Digamos que vamos a crear una nueva, nunca hecha, disruptiva app llamada calculadora. En esta app tendremos una función llamada sum(), la cual realiza la suma de dos números. Si lo hacemos en Kotlin, sería:

fun sum(int a,int b) : Int {
    return a+a;
}

Luego nos vamos a crear nuestra UI (Interfaz de usuario) la cual es fantástica y amamos hacer para que quede todo super lindo, pero cundo corremos la app y empezamos a probarla, nos damos cuenta de que la función de suma no funciona. ¿Por qué no funciona? Si los parámetros los he declarado bien y la suma va bien. Créeme, esto ocurre mucho mas de lo que imaginas.

Y es un problema si tus build times toman cierto tiempo. Ejecutar una compilación que tarde mucho puede romper el estado de concentración en el que te encontrabas, y espero que no seas como yo quien se distrae fácilmente y pierde el foco de que estaba haciendo. Por suerte, las pruebas unitarias pueden ayudarnos a solucionar estos dos problemas ya que los tests se encargan de verificar que el código haga lo que supone que debe hacer y como las pruebas unitarias son mas rápidas que compilar toda la app y probar cada cosa manualmente nos vienen de maravilla. Así que para empezar, vamos a crear nuestro primer test.

Casi todos los lenguajes tienen un framework para tests. Puedes revisar cual es el framework para test disponibles para tu lenguaje **aquí.** En nuestro caso como estoy usando Kotlin, vamos a usar JUnit.

Una prueba unitaria se parece a esto y por defecto está en la carpeta de tests del proyecto.

    @Test
    fun calculator_sum_shouldReturnTheSumBetweenTwoParameters() {
        //Given
        val calculator = Calculator()
        //When
        val result = calculator.sum(2, 1)
        //Then
        assertEquals(3,result)
    }

Analicemos un poco qué contiene este Test.

  • La anotación @Test que indica que es un Test.
  • El nombre de la función que indica [Unidad_NombreDeLoQueEstamosProbando_ResultadoEsperado], esto en ingles se hace de la siguiente forma: [Unit_WhatWeAreTesting_ExpectedBehavior].
  • El contenido del test.

Nuestro test debe seguir el patrón Arrange-Act-Assert (Organizar, actuar y afirmar) o el Given- When-Then (Dado que, cuando, entonces). A mi me gusta el patrón given, when, then debido a que me recuerda mucho a lo que suelo ver en las historias de usuario. Además, si te distraes puedes seguir los pasos y recordar el paso que te falta. Hablemos un poco sobre este patrón.

  • Given: En esta parte del patrón, los objetos que vas a necesitar son creados.
  • When: En este paso, llamamos a la función que queremos probar.
  • Then: Finalmente, en la ultima sección, hacemos la comprobación para evaluar el resultado.

Veamos un ejemplo:

Alt Text

En mi caso estoy usando Intellij Idea, en este IDE tengo un botón de play cerca de mi test y al hacerle click podremos ver en la siguiente imagen cómo el test falla.

Alt Text

Nuestro test ha fallado porque nuestra función está sumando dos veces el primer parámetro ?‍♂. Ahora que ya sabemos qué ocurre podremos cambiar nuestra función y ejecutar de nuevo el test para ver cómo pasa.

fun sum(int a,int b) : Int {
    return a+b;
}

Alt Text

Increíble. Tengo que admitir que ahora el verde se ha vuelto uno de mis colores favoritos ya que es el color de los tests al pasar.

Nota de Kotlin: En Kotlin, podemos utilizar las comillas invertidas como nombre de la función y hacer nuestro Test mas legible!

@Test
    fun `calculator sum should Return The Sum Between Two Parameters`() {
        //Given
        val calculator = Calculator()
        //When
        val result = calculator.sum(2, 1)
        //Then
        assertEquals(3,result)
    }

? La pirámide del testing

Hemos hablado sobre qué es un unit test, pero hay más tipos de test.

  • Unit Test, se encargan de probar una unidad en especifico.
  • Test de integración, verifica que dos o más unidades estén funcionando juntas correctamente como deberían.
  • End to End tests, verifican que todas las unidades están funcionando correctamente. En el caso de android esto incluye probar la UI.

Visto que tenemos varios tipos de test, debemos dividirlos razonablemente. No todos los tests pueden ser End to End o test de integración. Por suerte, hay una imagen que explica muy bien cómo debemos distribuir los tests y se llama la pirámide del testing.

Alt Text

La pirámide del testing fue creada por Mike Cohn en su libro, Succeeding with Agile. Y en este, comenta que los unit test deberían ser la base de la pirámide seguidos por los test de integración y finalmente los End to End.

? Otros beneficios del testing

Tener una test suite te puede hacer de malla protectora y ayudarte a detectar bugs que creas cuando estés programando una nueva funcionalidad o cuando estés haciendo un refactor. Además, tus tests pueden ayudar a futuros desarrolladores a entender mas el código que has creado ya que un test es la mejor documentación que hay.

¡Eso es todo por ahora! Espero que te haya gustado este post. Si te ha gustado, compártelo con tus amigos y compañeros de trabajo así todos podemos aprender un poco mas de testing.

Quieres saber más

Si te ha gustado este artículo y quieres saber sobre otros temas que te interesen puedes dejar un comentario o escribirme a cualquiera de mis redes sociales.

? Twitter

? Facebook

? Instagram

CategoriasDartProgramación

Funciones increibles que debes conocer al trabajar con Dart

Funciones increibles que debes conocer al trabajar con Dart

En los post anteriores sobre Dart, hablamos sobre las Collections. Hablamos sobre Lists,Maps y sets. Y en esta oportunidad vamos a hablar sobre funciones asombrosas y que nos pueden ayudar en muchos casos.

Nota:En este post usamos varios elementos que probablemente quieras repasar, como las funciones anónimas. Si es tu primera vez leyendo esta serie de artículos puedes aquí debajo te dejo el link para que leas sobre funciones en Dart.

Funciones en Dart

Map

The map function exists in many programming languages, and Dart is not an exception. This function creates a new list after transform every element of the previous list. This function takes as a parameter an anonymous function. Let’s see an example.

var list = List.of({1,2,3,4});
var mappedList = list.map( (number) => number *2);
print(mappedList);

Esta función existe en muchos lenguajes de programación y dart no es la excepción. Esta función crea una nueva lista después de transformar cada elemento de la lista anterior. Esta función recibe como parámetro una función anónima. Veamos un ejemplo.

En este ejemplo, hemos creado una función anónima que tiene un número como parámetro y hemos multiplicado este número por dos. El resultado de la función es
(2,4,6,8).

Sort

Muchas veces necesitamos recibir una lista desde el servidor y mostrarla al usuario. Pero ¿qué ocurre si necesitamos aplicar algunos filtros y ordenarla de forma ascendente? Esta función está aquí para ayudarnos con eso, veamos un ejemplo.

var randomNumbers = List.of({14, 51, 23, 45, 6, 3, 22, 1});
randomNumbers.sort();
print(randomNumbers);

El resultado es el siguiente.

[1, 3, 6, 14, 22, 23, 45, 51]

Generate

La función generate es genial cuando necesitas crear una lista de números para hacer una prueba rápida. Toma como parámetro un número el cual indica el tamaño de la lista y una función anónima.

var generatedList = List.generate(10, (number) => number * Random().nextInt(50));
  print(generatedList);

Dentro de la función anónima obtenemos un número y lo multiplicamos por un número aleatorio entre 0 y 50.

Take

Ya solo con su nombre en inglés te explica que hace esta función simplemente toma los primeros elementos de la lista. Puede ser útil cuando tengas una lista de competidores y quieras solo obtener el top tres de todos los competidores.

var list = List.from([1,2,3,4,5,6]);
var topThreeList = list.take(3);
print(topThreeList);

El resultado es: 1,2,3

Skip

Esta función es el opuesto de la función Take, está ignora la cantidad de elementos que se le indique. En caso de que se le indiquen 3 elementos obviara los primeros tres elementos de la lista.

var list = List.from([1,2,3,4,5,6]);
var skipList = list.skip(3);
print(skipList);

El resultado es: 4,5,6

Where

Esta función es una de mis favoritas ya que nos ayuda a crear una lista con los elementos que cumplan con el predicado que se le pasa como parámetro. Esto quiere decir que solo los elementos que cumplan con la condición dada se agregaran a la lista.

Digamos que tenemos una lista aleatoria de números en caso de que queramos una lista con solo numeros pares bastará realizar esa comprobación en la función anónima. Veamos el siguiente ejemplo.

var randomNumbers = List.of({14, 51, 23, 45, 6, 3, 22, 1});
var evenNumbers = randomNumbers.where((number => number.isEven));
print(evenNumbers);

El resultado del ejemplo anterior es el siguiente:
14,6,22.

Un buen tip

Estas funciones pueden combinarse para lograr una mejor solución. Puedes combinar la función where con la función sort para obtener los números pares ordenados de forma ascendente por ejemplo.

var randomNumbers = List.of({14, 51, 23, 45, 6, 3, 22, 1});
var evenNumbers = randomNumbers.where((number) => number.isEven);
evenNumbers = evenNumbers.toList()..sort();
print(evenNumbers);

En este ejemplo tomamos solamente los números pares de la lista randomNumberList, luego convertimos esos números a una Lista y finalmente usamos el operador de cascada .. para ordenar la lista de forma ascendente.

El resultado final es: [6, 14, 22]

Eso es todo

Espero que te haya gustado. Estoy creando nuevas CodingSlices sobre Flutter en Instagram, puedes seguirme en @codingpizza y en Twitter como @coding__pizza para aprender sobre Flutter.

Ahora es tu turno

Puedes probar estos conceptos en Entornos de desarrollo (IDE) como Intellij Idea Community, que es gratis e instalar el plugin de Dart, si te gusta Visual Studio Code tambien puedes probar estos conceptos en él y por último, si prefieres algo online puedes utilizar Dartpad.

¿Quieres saber más sobre Dart?

Si te ha gustado este post y estás interesado en aprender Dart, actualmente estoy escribiendo más artículos como este en un ebook, el cual es un curso básico de Dart que te ayudará a tener un buen conocimiento que luego podrás utilizar para empezar con Flutter ;). Puedes darte de alta en este link ya que el ebook será totalmente gratis.

Post anterior

Si estás interesado en más post como este puedesrevisar mis otros artículos sobre Dart.

CategoriasDartProgramación

Parámetros en Dart

¡Hola!, en los ultimos post he hablado sobre variables y funciones. Si te los has perdido, te dejo el link a ellos aqui debajo para que puedas echarle un ojo.

Ya hemos hablado un poco sobre ellos.

En el post anterior sobre funciones ya hablamos un poco sobre los parámetros. Hemos visto que funcionaban como ingredientes para hacer funcionar una «Maquina de Helado». Tambien podemos decir que los parámetros son dependencias que una función requiere para poder ejecutar su codigo.

Required parameters (Parámetros requeridos)

Los parámetros requeridos son los mas basicos que una función puede usar, solo hace falta especificar un tipo un nombre y hemos terminado.

Los parámetros requeridos los hemos visto ya en el caso de la función suma.

Integer suma(Integer a,Integer b) {
    return a+b;
}

El entero a y el entero b, son usados dentro de la función y posteriormente la función devuelve el valor de los dos sumados.

Optional parameters / Parámetros opcionales

Los parámetros opcionales no son requeridos por la función al momento de usarla. En ciertos casos podrías necesitar pasarle ese parámetro a la función, como en otros no.

Para hacer un parámetro opcional es necesario colocarlo al final de la firma de la función y entre corchetes. Para dejarlo mas claro veamos el siguiente ejemplo:

void imprimirNombreCompleto(String nombre, String apellido, [String segundoNombre]){
    print("Mi nombre es: $name $secondName $surname");
}

En esta función podemos ver como hemos situado el parámetro opcional despues de los parámetros requeridos, esto se debe a que los parámetros opcionales deben ir siempre despues de los requeridos, de lo contrario no compilará.

Te preguntuntaras, ¿Que ocurré con la variable segundoNombre , si no la hemos pasado a la función?. La variable segundoNombre será nula. Y nosotros no queremos mostrar «John null Wick», ¿Cierto?.

Para evitar esto podemos agregar un valor por defecto que va a ser utilizado en lugar del parámetro opcional cuando este sea nulo.

Para agregar un valor por defecto a un parámetro opcional, todo lo que necesitamos hacer es una asignación. Para entenderlo mejor puedes ver el siguiente ejemplo:

void imprimirNombreCompleto(String nombre, String apellido, [String segundoNombre = ""]){
    print("Mi nombre es: $nombre $segundoNombre $apellido");
}

Ahora el valor será un String vacio y el texto será mostrado correctamente.

Para usar la función con parámetros opcionales que hemos creado previamente hacemos lo siguiente.

imprimirNombreCompleto("John","Wick");
//O
imprimirNombreCompleto("Scarlett","Johansson","Ingrid");

En el caso que quieras utilizar todos los parámetros de la funcion como opcionales puedes encerrarlos entre corchetes como muestra el siguiente ejemplo.

void imprimirNombreCompleto([String nombre, String segundoNombre, String Apellido]){
    print("Mi nombre es: $nombre $segundoNombre $apellido");
} 

Named parameters / Parámetros nombrados

Este tipo de parámetros permite indicarle a la función cual es el parámetro que estas pasando. Para lograr esto tenemos que colocarlo entre llaves.

Ejemplo:

void imprimirParametrosNombrados(String nombre,String apellido,{String segundoNombre = ""}){
    print("$nombre $segundoNombre $apellido")
}

En este ejemplo hemos usado el nombre y el apellido como parámetros requeridos. Y el segundo nombre como parámetro nombrado ademas nos aseguramos de tener un valor por defecto por si no se proporciona ningun valor.

Cuando queremos utilizar una función con parámetros requeridos debemos hacerlo de la siguienta manera:

imprimirParametrosNombrados("Samuel","Jackson",segundoNombre: "Leroy");

En este ejemplo podemos ver que necesitamos indicar el nombre del parámetro dentro de la función y despues de los dos puntos indicamos el valor del parámetro.

En el caso en que necesitemos tener una función con solo parámetros nombrados lo que tenemos que hacer es incluir dentro de las llaves todos los parámetros.

void imprimirParametrosNombrados({String nombre,String apellido,String segundoNombre = ""}){
    print("$nombre $segundoNombre $apellido")
}

Cuando una función tiene unicamente parámetros nombrados no importa el orden en el que los utilicemos.

Por ejemplo:

imprimirParametrosNombrados(nombre: "Scarlett",segundoNombre:"Ingrid",apellido:"Johansson");

¿Genial, no?.

Ahora es tu turno

Puedes probar estos conceptos en Entornos de desarrollo (IDE) como Intellij Idea Community, que es gratis e instalar el plugin de Dart, si te gusta Visual Studio Code tambien puedes probar estos conceptos en él y por último si prefieres algo online, puedes utilizar Dartpad.

Post anterior

Si estás interesado en más post como este puedes revisar mis otros artículos sobre Dart.

¿Quieres saber mas sobré Dart?

Si te ha gustado este post y estás interesado en aprender Dart, actualmente estoy escribiendo más artículos como este en un ebook, el cual es un curso básico de Dart que te ayudará a tener un buen conocimiento que luego podrás utilizar para empezar con Flutter ;). Puedes darte de alta en este link ya que el ebook será totalmente gratis.

CategoriasDartProgramación

Variables en Dart

 

¿Qué son las variables?

En este articulo vamos a aprender sobre las variables en Dart, las variables son como cajas pequeñas que tienen una referencia a un valor. Y estas cajas pequeñas pueden tener un nombre para identificarlas facilmente.

¿Cómo podemos crear variables en Dart?

En Dart podemos crear variables de tres formas:

Usando la palabra reservada var

Podemos crear una variable utilizando la palabra reservada var antes del nombre de la variable, y luego del nombre de la variable el valor que le queremos asignar, veamos el siguiente ejemplo:

Nota: la instrucción print(año) imprime el valor de variable. (Se usa año como ejemplo, pero no es un tipo de variable aceptada en Dart)

Esto que acabamos de ver es una inferencia de tipos. La inferencia de tipos es una funcionalidad que tiene el compilador de Dart para poder deducir el tipo de la variable que estamos creando.

Declarando una variable especificando el tipo

También podemos declarar el tipo de la variable como en el ejemplo a continuación:

Usando la palabra reservada dynamic

La palabra reservada dynamic nos permite declarar una variable en la que el tipo puede cambiar en tiempo de ejecución y puede ser definida de la siguiente forma:

Ahora es tu turno

Puedes probar estos conceptos en Entornos de desarrollo (IDE) como Intellij Idea Community, que es gratis e instalar el plugin de Dart, si te gusta Visual Studio Code tambien puedes probar estos conceptos en él y por último si prefieres algo online, puedes utilizar Dartpad.

¿Quieres saber mas sobré Dart?

Si te ha gustado este articulo y estas interesado en aprender Dart, actualmente estoy escribiendo más articulos como este en un ebook, el cual es un curso básico de Dart que te ayudará a tener un buen conocimiento que luego podrás utilizar para empezar con Flutter ;). Puedes darte de alta en este link ya que el ebook será totalmente gratis.

 

CategoriasAndroidProgramación

Como usar el Android Navigation Component

Android Architecture components - Navigation Component

El problema de la navegación

A lo largo de los años los desarrolladores Android han buscado una forma de hacer más fácil la navegación entre los fragments y las activities dentro de las aplicaciones que creaban. Muchos inventaron una cantidad de clases y variantes llamadas Navigation, Base Navigation, Navigation Manager.

Entre cualquier cantidad de ingeniosos nombres que el ser humano se puede inventar, cada uno tenía sus peculiaridades con sus ventajas y sus desventajas, muchas de estas necesitaban que el desarrollador heredara de una clase base o agregara manualmente constantes a una clase para así identificar a donde iría y de a donde vendría, esto solía generar muchos bugs respecto a la navegación de la app.

Por ejemplo, si una App que mostraba el detalle de una compra al ir hacia atrás lo que se espera es que te llevara al paso anterior a ese detalle de compra, es decir a los objetos que habías seleccionado para comprar, y en algunos casos estas famosas clases de navegación fallaban enviando al usuario a la pantalla principal de la aplicación o peor aún a otra pantalla que no tenía nada que ver con este flujo, esto suponía un problema.

Entra en escena el Navigation Component de Android

En el Google I/O de 2018 fue anunciada la creación de este componente para así tener un standard en el cual se basaran las aplicaciones Android, la versión estable de este component fue liberada hace aproximadamente un mes y actualmente existe una versión 1.0 que es compatible con AppCompat y una versión 2.0 que está disponible para Android Jetpack. Si quieres saber qué es Android Jetpack he hablado de él previamente en este articulo.

El uso de este componente está basado en crear un grafo en el cual estén conectados todos los activities y fragments de tu aplicación ademas de las «actions» que permiten cambiar de fragments.

Muéstrame el código

Para empezar a utilizar nuestro Navigation Component en nuestros proyectos es necesario agregar las siguientes dependencias a nuestro build.gradle del modulo app y del proyecto.

Java

build.gradle del proyecto


build.gradle del modulo app

1. Crear el Navigation Graph

Para esto debemos abrir nuestra pestaña de Project en Android Studio y hacer click derecho en la carpeta «res», seleccionar Android Resource File, escribir el nombre del navigation graph que queremos y luego seleccionar Navigation.

2. Agregar el NavHostFragment en el layout de nuestro MainActivity.

Esto nos servirá para hospedar nuestros fragments. Para esto agregamos el siguiente código a nuestro layout.

Luego, hay que abrir nuestro archivo de navegación nav_graph.xml y seleccionar nuestro host fragment.

3. Agregar nuestros fragments al Navigation Graph

Basta hacer click en el icono de la pantalla con un signo + verde, luego hacer click en «Create new destination» desde ahí podremos agregar nuestros Fragments previamente creados o crear nuevos.

4. Conectar nuestros fragments utilizando actions

Para conectarlos basta hacer click en un fragment y «arrastrar» una flecha hacia nuestro segundo fragment. Y ya habríamos creado una acción.

5. Moverse entre fragments

Para movernos entre fragments utilizando el Navigation Component tenemos varias opciones. La principal siempre es obtener el NavigationController, dependiendo del contexto en el que te encuentres puedes realizarlo de una manera distinta.
En nuestro caso cambiaremos a otro fragment cuando se haga click en una imagen. Para esto utilizaremos el método de la clase Navigation FindNavController que acepta como parámetro una View o una Activity, luego utilizamos el método navigate y le pasamos como parámetro el id de nuestro action quedando de esta manera:

Java:

Kotlin:

Pasar objetos de un fragment a otro

Para poder pasar objetos de un fragment solo tenemos que crear nuestro Bundle como se hacía tradicionalmente y agregarlo como parámetro al método .navigate() que vimos antes de esta forma:
Java:

Kotlin:

Para obtener el drawableId en nuestro fragment de detalles lo hacemos de la siguiente manera:

Java:

Kotlin:

Pasar objetos de un fragment a otro usando el plugin de safe-args

El Navigation Component utiliza un plugin de Gradle llamado safe-args que ayuda al momento de pasar objetos de un Fragment A a un Fragment B. Este ayuda a generar clases que se encargan de que los objetos sean type-safe.

Nota: Type-safe significa que el objeto es evaluado en tiempo de compilación y el compilador nos dará un error en caso de que intentemos pasar un tipo que sea erróneo.

Ademas de esto, nos ayuda a quitarnos el problema de estar asignando constantes como claves del bundle para luego usarlas y recuperar así los objetos.

Primero necesitamos ir a nuestro nav_graph.xml y hacer click en el fragment que va a recibir el objeto, en nuestro caso vamos a pasar el id del drawable que vamos a mostrar en nuestro Fragment de detalle. Así que hacemos click en el detailFragment, luego en el símbolo + que se encuentra a la derecha de «Arguments» y creamos nuestro nuevo argumento. Rellenamos los campos y hacemos click en «Add».

Necesitamos crear una instancia del objeto NavDirections, esta la obtenemos desde una clase que fue generada por el plugin de safeArgs. El plugin de safeArgs lo que hace es agregar un sufijo al nombre del fragment, en nuestro caso:
Si tu Fragment se llama MainFragment, esta clase se llamará MainFragmentDirections, luego utilizamos el método que nos provee y como podrás ver tiene como parámetro un entero que es el id del drawable que vamos a pasar al otro Fragment. Luego se llama al método que vimos antes de navigate() pero esta vez le vamos a pasar el NavDirections que hemos creado previamente.

Java:

Kotlin:

Para obtener el drawableId que hemos pasado al fragment de DetailFragment lo hacemos de la siguiente forma:

Java:

Kotlin:

Final

Esto es el uso básico del Navigation Component. También puede ser usado en el caso que quieras con un Drawer o con un Bottom Navigation View, pero eso da para otro artículo ?.
Y con esto hemos terminado. En los próximos artículos hablaré un poco acerca de otros Android Architecture components. Si te ha gustado este artículo compartelo en las redes sociales. No olvides seguirme en mi twitter seguirme en twitter para que seamos amigos ? y sigue tambíen el twitter y el instagram de codingpizza que lo encontrarás al final del sitio.

Aquí puedes encontrar todo el codigo que ha sido utilizado en este articulo.

CategoriasAndroidProgramación

El camino del desarrollador Android #10 – PizzaList

¡Hola! Finalmente hemos llegado a la segunda aplicación de esta serie de tutoriales que estamos realizando para aprender a programar en Android. En este post, vamos a implementar todo lo que hemos ido aprendiendo en los post anteriores y poder crear nuestra primera aplicación que obtiene datos de un servicio y los muestra al usuario. La aplicación en sí lo que hará es mostrar una lista de pizzas y de sus ingredientes, porque todos sabemos que la pizza es vida?.

Las dependencias que utilizaremos para este proyecto serán las siguientes:

-Fragments
-RecyclerView
-Retrofit
-Glide

Resultado final

app-screenshot
Captura de pantalla de la aplicación terminada.

 

Agregando dependencias

Como en todas las aplicaciones que creamos, necesitamos empezar agregando las dependencias a nuestro build.gradle.

Creando nuestra Activity

Vamos a iniciar creando nuestro Activity que va a gestionar nuestro Fragment de lista de pizza. En el último Google I/O, el cual es el evento anual de Google donde hablan acerca del futuro del framework de Android, nuevas tecnologías y todo lo que se viene; los encargados del desarrollo del framework de Android han comentado que la mejor forma de tener una aplicación hoy en día es una Activity con muchos Fragments. Por eso vamos a realizar nuestras aplicaciones de esta manera de ahora en adelante.

Para empezar, crearemos el layout de nuestro Activity y su respectiva clase. Además, para hacer el post un poco más corto agregaremos de una vez la llamada a un Fragment que vamos a crear luego.

Java

Kotlin

Creando nuestro Fragment

Ahora procederemos a crear nuestro Fragment donde mostraremos nuestro RecyclerView con la lista de pizzas. Para empezar, vamos a agregar directamente el RecyclerView a nuestro layout.

Java

Kotlin

Luego procederemos a crear el layout para la fila que mostrará la información de cada pizza.

Creando nuestro POJO

Como ya se ha mencionado en el post anterior (puedes revisarlo haciendo click aquí), para crear un objeto a partir de un JSON es necesario realizar un Plain Old Java Object. Para esto crearemos nuestra clase Pizza, que es muy parecida a la que hicimos anteriormente solo que en esta oportunidad tiene una url donde está almacenada la imagen.

Java

Kotlin

Creando nuestro CustomAdapter y ViewHolder

Ahora crearemos nuestro CustomAdapter el cual extiende de RecyclerView.Adapter y vamos a crear dentro del mismo una clase con un viewHolder. Dentro de este último vamos a asignar la información de cada pizza.

Java

Kotlin

Agregando Glide

Para poder mostrar las imágenes de cada pizza necesitaremos utilizar Glide. Usar Glide es bastante sencillo solo debemos indicarle en cuál View va a buscar la ImageView en la que queremos mostrar la imagen .with(), luego desde dónde va a cargar la imagen con el método .load(), y finalmente, con el método .into() pasamos nuestro ImageView quedando de la siguiente manera:

Java

Kotlin

Obteniendo datos con Retrofit

Antes de crear el RecyclerView vamos a empezar creando la llamada a la API para obtener la información que le vamos a pasar a este. Esta parte también es muy parecida al post anterior con la única diferencia que aquí la parte final de la url es /v2/pizzas/, ya que esta url contiene la listas de pizzas con imágenes.

Java

Kotlin

Rellenando el RecyclerView

Para llenar nuestra lista de pizzas vamos a necesitar crear en nuestro Fragment, un RecyclerView y una instancia de Retrofit. Luego de esto vamos a crear un Service con Retrofit que nos permitirá realizar una llamada a la URL que ya hemos definido previamente y al obtener los datos vamos a asignarlos a nuestro nuevo CustomAdapter.

Java

Kotlin

Con esto ya tendremos nuestra simple aplicación para ver Pizzas y sus ingredientes.

Conclusión

En estos últimos post hemos hablado de cómo realizar llamadas a servicios que ya existen y obtener sus datos para mostrarlo en una aplicación. La mayoría de las aplicaciones necesitan hacer esto.

Próximamente, hablaremos sobre cómo integrar mapas a tus aplicaciones, recibir notificaciones y muchas cosas de las que seguro te querrás enterar.

Síguenos en las redes sociales que puedes encontrar al final de la página y comparte este artículo con tus amigos desarrolladores o con aquellos que estén empezando a programar. 😉

CategoriasAndroidProgramación

El camino del desarrollador Android #9 – Cargar imagenes con Glide v4

¡Hola! Hoy vamos a seguir con la serie de tutoriales de desarrollo Android, estas guías que a cualquier desarrollador le pueden servir para aprender y usar en su trabajo. En esta oportunidad hablaremos de Glide, la cual es una librería que se utiliza para cargar imágenes en nuestras aplicaciones Android.

Agregando Glide a nuestro proyecto

Como la mayoría de las librerías, empezamos agregando lineas a nuestro archivo build.gradle.

Añadimos el permiso de Internet (Opcional)

Si nuestra aplicación va a cargar imágenes desde Internet, vamos a necesitar el permiso correspondiente. En caso de que la aplicación que estés desarrollando no necesite cargar imágenes, puedes obviar este paso.

El permiso de internet se incluye en el AndroidManifest.xml, dentro de la etiqueta de Manifest y fuera de la etiqueta de Application. Quedando de la siguiente manera:

Añadiendo el permiso de escritura y lectura.

Para leer imágenes del usuario de la app vas a necesitar agregar el siguiente permiso, el cual se agrega igual que el anterior.

<uses-permission android:name=»android.permission.READ_EXTERNAL_STORAGE» />

Si quieres utilizar la cache de Glide para almacenar datos en la microSD vas a necesitar el permiso de escritura, si agregas los dos permisos al AndroidManifest quedaría así:

<uses-permission android:name=»android.permission.WRITE_EXTERNAL_STORAGE» />

Puedes usar el de Internet y estos que hemos mencionado anteriormente no son excluyentes, solo debes agregar uno debajo el otro. Con esto hemos terminado de incluir esta librería en nuestro proyecto usando Java, en caso de que uses Kotlin aun te falta algo mas por hacer.

Agregar el Plugin kapt (Solo en caso de Kotlin)

En este caso, no vamos a utilizar la linea de annotationProcessor que tenemos en el primer paso. En su lugar vamos a agregar el Plugin de kapt

En el build.gradle agregamos:

dependencies {
kapt ‘com.github.bumptech.glide:compiler:4.8.0’
}

Y luego tenemos que incluir también el plugin al inicio del build.gradle:

apply plugin: ‘kotlin-kapt’

Quedándonos así:

Creando el layout para mostrar la imagen

Para hacer esto solo tenemos que seguir unos sencillos pasos. Simplemente un botón con un ImageView en el que se cargara la imagen, el cual seria.

Nada que no hayamos visto antes ni que sea muy complicado, una View que es un ImageView y un botón el cual tendremos que tocar para que se cargue la imagen.

Finalmente, utilizamos Glide

Para utilizar Glide vamos a agregar un listener al botón que hemos creado previamente y llamar al método loadImage que crearemos ahora, y luego dentro de este ultimo haremos la llamada a Glide.

Cuando utilizas Glide basta con llamar al método with() y pasarle como parámetro un Context, un Activity o un Fragment. Luego indicamos la URL que vamos a utilizar para cargarla en el imageView y para finalizar utilizamos el método .into para cargarla en el imageView que hemos declarado anteriormente.

Java

Kotlin

La única diferencia que tenemos en Kotlin es el uso de .let.

Recuerda que el repositorio del proyecto lo puedes encontrar Aquí. Para alternar entre el proyecto en Java y en Kotlin basta cambiar de rama ?.

Qué hacer ahora

Glide tiene muchísimo más potencial de lo que hemos hablado hasta ahora, así que si quieres conocer más de sus capacidades puedes leer su documentación haciendo click aquí.

Con esto terminamos este post; si te ha servido no olvides compartirlo con tus amigos programadores ? y recuerda seguirnos en nuestras redes sociales para estar al tanto de todas las publicaciones que hacemos.

CategoriasAndroidProgramación

El Camino del Desarrollador Android #8 – Conectividad con Apis y Retrofit

Nuestras tareas de cada día en la mayoría de las aplicaciones que creamos son las llamadas a servicios,APIs y otras fuentes donde podamos consumir datos para mostrar al usuario en nuestra aplicación. En estos casos existen muchas maneras de realizar estas tareas pero gracias a Retrofit, una librería para la capa de comunicación de nuestra aplicación se nos hace fácil esta tarea.

Integrar Retrofit a tu aplicación es bastante sencillo, solo necesitas seguir los siguientes pasos:

  1. Integrar Retrofit a las dependencias a tu proyecto de Android Studio en el build.gradle.
  2. Crear nuestros POJO (Plain Old Java Object) para la llamada.
  3. Luego necesitas crear una interfaz donde vas a definir todas las llamadas que se van a realizar a una API utilizando sus anotaciones especiales.
  4. Crear una instancia de Retrofit donde indicar la URL de la API.
  5. Crear una implementación de la clase que hemos creado previamente en el paso 2.
  6. Realizar la llamada.
  7. Hacer uso de los datos de la forma que prefieras, por ejemplo mostrarlos en un RecyclerView.

Integrando Retrofit a nuestro proyecto

Para integrar Retrofit lo unico que necesitamos realizar es agregar las siguientes lineas al build.gradle

Creando nuestros POJOS

Aquí es donde viene unas de las mejores funcionalidades que tiene Retrofit, la conversión a nuestros POJOS haciendo uso de la librería de Google, GSON. Podemos convertir un JSON en objetos Java.

En nuestro caso he preparado una API de pizzas a la cual consultaremos y mostraremos su resultado por consola, recuerda que luego podemos utilizar esta información para mostrarla en un RecyclerView.

La URL de nuestra API a la cual llamaremos es: http://private-3cc5a4-codingpizza.apiary-mock.com/pizzas

Con el JSON que nos devuelve nuestra API de pizzas iremos a esta pagina http://www.jsonschema2pojo.org/ , la cual es genial para convertir JSON a clases de Java (En el caso de que estemos creando un proyecto con Kotlin, puedes convertir la clase de Java a Kotlin utilizando la opción de convertir archivo Java a Kotlin en la pestaña de «Code» de Android Studio.

En la siguiente imagen podemos ver como obtener nuestra clase Java, solo basta pegar el JSON y luego hacer click en Preview si queremos ver una vista previa o descargar todo en un zip que contenga las clases que necesitamos.

JsonToPojo

Ahora solo falta pegar estas clases dentro de nuestro proyecto y hemos terminado con este paso.

Creando la interfaz

Luego procedemos a crear una interfaz donde definiremos todas las llamadas que realizaremos y lo haremos de la siguiente manera:

Kotlin

Podemos ver que tenemos varias anotaciones las cuales indican lo siguiente:

@Get: Realiza una llamada Get (Si, es un poco obvio). Pero existen otras anotaciones que podrán conocer en la pagina oficial de Retrofit.

Creando nuestra instancia de Retrofit

Creamos nuestra instancia de Retrofit en nuestra clase usando su Builder e indicamos a la URL que vamos a llamar

Kotlin

Indicandole a Retrofit de que interfaz hablamos

Ahora tenemos que crear un Objeto de PizzaService, con la clase que necesitábamos y para terminar este paso tenemos que crear una Call, especificando que método de la clase PizzaService vamos a utilizar.

Kotlin

Agregar el permiso de Internet

Esto es de vital importancia si no lo agregas no podrás realizar conexiones desde tu aplicación y esta se cerrara.

Realizando las llamadas

Ahora vamos a realizar una simple llamada a un servicio utilizando nuestras clases nuevas de la siguiente manera:

Kotlin

En esta parte, creamos un objeto Call el cual nos traerá un objeto Response el cual verificamos si ha sido exitoso y de ser así obtenemos el Body de la llamada el cual es una lista de objetos de Pizza donde obtendremos toda la información que necesitamos para mostrar en un Log, esta lista podemos utilizarla también en un RecyclerView y mostrar estos datos pero esto lo haremos cuando creemos la aplicación completa. Así que si no quieres perderte cuando creemos la aplicación no olvides seguirnos en nuestras redes sociales y suscribirte a nuestra newsletter.

Ventajas de Retrofit

Retrofit es muy versátil y así como puedes convertir llamadas a JSON puedes convertir a XML,Jackson,Moshi hasta puedes obtener un JSON «Crudo», Llámese «Crudo» a la misma respuesta JSON que puedes obtener realizando una llamada a la API desde otro medio como Postman (¿Conoces Postman No?, de no ser así deberías es una gran aplicación para realizar llamadas a API y ver como funcionan los servicios de la API).

Otra de las grandes ventajas de Retrofit 2 es que te permite modificar el Header (Cabecera) de una llamada, utilizando la anotación @Header. Hay mucha tela que cortar con el Retrofit, por el momento utilizaremos solo las GET. Luego iré actualizando este Post con todas las llamadas posibles que utilicemos en otros post de el Camino del Desarrollador Android.

¿Que hacer ahora?

Empieza probando con diferentes llamadas a servicios que te llamen la atención y practica con ellos, si tienes alguna duda o quieres hacer algo en especifico pero tienes una duda. Puedes comentarlo aquí abajo y no olvides seguirnos en nuestras redes sociales, las cuales encontraras al final de la pagina ademas compartir esto con alguien que necesite aprender a usar Retrofit. Ademas en caso de que necesites el código del proyecto lo puedes ver y descargar de aquí si lo quieres en Java y para Kotlin aquí.

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.

ACEPTAR
Aviso de cookies