• Saltar a la navegación principal
  • Saltar al contenido principal

CARLOSZR.COM

Mi blog personal, CarlosZR

  • Blog
  • Contacto
  • Curso de SwiftUI por CarlosZR

Curso de Flutter / 28/08/2020

Hola mundo con Flutter (Dart) y tipos de datos

En este curso utilizamos Flutter con el lenguaje de programación Dart, ambos desarrollados por Google.

Vamos a ver cómo hacer el Hola Mundo con Flutter, digo Dart.

Para ello vamos a ir al DartPad.

Antes de seguir quiero comentarte que este artículo es algo más que un Hola Mundo con Dart, es una pequeña introducción a este lenguaje con el que después haremos nuestras apps en Flutter. Por algo hay que empezar, iremos poco a poco.

Como vemos, tenemos un método main. Sin él no podemos trabajar, nos devuelve un error. Mejor dicho, nos devuelve tres errores. Veámoslos:

Error compiling to JavaScript:
Error: No 'main' method found.
Error: Compilation failed.

El método malin generalmente no retorna nada, por eso le ponemos delante ‘void‘.

También, una de las cosas importantes a saber ahora que estamos comenzando es que las sentencias terminan con punto y coma «;».

Así quedaría nuestro primer «Hola mundo» con Dart:

void main() {
  print('Hola mundo');
}
hola mundo con dart
Hola mundo con Dart

En mi Curso de Dart gratis puedes ver más vídeos para aprender Dart. Vídeos nuevos cada semana.

Los comentarios en Dart

Los comentarios en Dart son muy fáciles:

  • Comentario de una línea: usar doble barra //.
  • Comentario multilínea: /* código comentado */.

Concatenación de datos con Dart

Siguiendo el ejemplo anterior, veamos la concatenación de datos con Dart.

void main() {
  var nombre = 'Carlos';
  print('Hola ' + nombre);
}

El resultado de esto sería «Hola Carlos». Pero también se puede hacer de otra forma. Veamos cómo podemos inyectar un String (cadena de texto) con Dart.

void main() {
  var nombre = 'Carlos';
  print('Hola $nombre');
}

Esto que hemos realizado es la interpolación de String.

Ahora veamos un poco los tipos de datos en Dart y comencemos a picar código y familiarizarnos con él.

Tipos de datos en Dart, Números y String

Muy simple, veamos un ejemplo de String.

String cadena;
cadena = 'Carlos';

Ejemplo de números.

// Números
  int amigos;
  double pi;
  amigos = 12;
  pi = 3.14;

Tipos de dato booleanos y condicionales ‘if-else’ en Dart

Los tipos de datos booleanos almacenan valores de verdadero o falso. Vemos cómo se dedfine un tipo de dato booleano.

void main() {
  bool dato;
  dato = true;
}

Y el condicional, para los que ya saben algo de programación, es muy simple. Se ejecuta el código que cumple la condición true, verdadero.

void main() {
  bool encendido;
  encendido = true;
  
  if (encendido = true) {
    print('Máquina encendida.');
  } else {
    print('Máquina apagada.');
  }
}

Las listas en Dart

Una lista es una colección de objetos. Veamos algunos ejemplos de listas en Dart.

void main() {
  
  // Lista de objetos de distinto tipo (dynamic)
  
  List lista = ['hola', 1];
  print(lista[0]);
  print(lista[1]);
  
  print('**************************');
  
  // Lista de números enteros
  
  List<int> listaN = [0, 23, 44];
  print(listaN[0]);
  print(listaN[1]);
  print(listaN[2]);
  
}

Para añadir un elemento usamos el método add.

// Añadimos el número 77 a nuestra lista de enteros
listaN.add(77);

Veamos la creación de una lista de tamaño fijo en Dart.

// Lista de tamaño fijo
List numeros = List(5);
print(numeros);
Lista vacía en Dart
Lista vacía en Dart

Veamos como establecer el valor de un elemento en una lista.

List numeros = List(5);
numeros[0] = 55;
print(numeros);
Lista de números y sus valores en Dart
Lista de números y sus valores

Tipo de dato Map en Dart

El objeto mapa es una pareja clave/valor. Ambos pueden ser de cualquier valor. Es muy fácil el acceso a cada valor del mapa.

void main() {
  
  Map<String, dynamic> coche = {
    'marca'    : 'Ford',
    'modelo'   : 'Focus',
    'potencia' : 125,
    'vendido'  : false
  };
  
  print(coche['marca'] + ' ' + coche['modelo']);
  print(coche['potencia']);
}
Resultado de imprimir los valores del Map seleccionados
Resultado de imprimir los valores del Map seleccionados

Veamos la creación de un mapa en Dart de enteros y cadenas al que añadiremos posteriormente un objeto.

  // Map int/String
  
  print('*********************************');
  
  Map<int, String> coches = {
    1: 'Alfa',
    2: 'Ford',
    10: 'Renault'
  };
  
  coches.addAll({3: 'Toyota'});

  print(coches);
  
  print(coches[1]);
  print(coches[2]);
  print(coches[10]);
  print(coches[3]);

El resultado sería el siguiente:

Veamos las Funciones en Dart

Veamos un sencillo repaso a las funciones.

void main() {

  decirHola();
}

void decirHola() {
  print('Hola');
}
Resultado por consola de la función decirHola
Resultado función decirHola

Veamos cómo pasamos parámetros a las funciones y cómo podemos nombrar a los parámetros en Dart.

void main() {

  decirHola();
  
  
  retornarCadena();
  
  print(retornarCadena());
  
  String resultado = retornarTexto(saludo: 'Hola,', nombre: 'Juan');
  
  print(resultado);
  
}

void decirHola() {
  print('Hola');
}

String retornarCadena() {
  return 'Hola desde la función';
}

// Función cuyos parámetros tienen nombre

retornarTexto({ String saludo, String nombre }) {
  return '$saludo $nombre';
}

Por último, quiero enseñaros cómo en este lenguaje también podemos usar las funciones de flecha.

void main() {
  
  String resultado = retornarTextoFlecha(saludo: 'Hola,', nombre: 'Juan');
  
  print(resultado);
}

// Función cuyos parámetros tienen nombre

retornarTexto({ String saludo, String nombre }) {
  return '$saludo $nombre';
}

// Función de flecha

retornarTextoFlecha({ String saludo, String nombre }) => '$saludo $nombre';
Resultado por consola
Resultado por consola

Clases en Dart

Para definir una nueva instancia de una clase en Dart, el new es opcional.

void main() {

  var miCoche = new Coche();
  var miCoche2 = Coche(); 
}

class Coche {
  String marca;
  String modelo;
}

Las clases en Dart tienen propiedades y métodos. Para distinguir entre métodos y funciones diremos que los métodos se encuentran dentro de una clase y las funciones fuera.

La clase Coche tiene como propiedades «marca» y «modelo». Si usamos final estamos indicando que ese objeto no va cambiar su valor nunca.

void main() {

  var miCoche = new Coche();
  var miCoche2 = Coche();
  
  final miCoche3 = Coche();
}

class Coche {
  
  String marca;
  String modelo;
}

Veamos el Constructor de una Clase con argumentos posicionales.

void main() {

  final miCoche3 = Coche('Renault', 'Clio');
  
  print(miCoche3.marca);
  print(miCoche3.modelo);
  print(miCoche3);
}

class Coche {
  
  String marca;
  String modelo;
  
  // Constructor con argumentos posicionales
  Coche(String marca, String modelo) {
    this.marca = marca;
    this.modelo = modelo;
  }
  
  // Sobreescribimos el método toString
  String toString() {
    return '${ this.marca } - ${ this.modelo }';
  }
}

Si queremos mantener el orden de los argumentos usamos el constructor con named arguments (argumentos con nombre). Veamos como quedaría el ejemplo anterior.

void main() {

  final miCoche3 = Coche(marca: 'Renault', modelo: 'Clio');
  
  print(miCoche3.marca);
  print(miCoche3.modelo);
  print(miCoche3);
}

class Coche {
  
  String marca;
  String modelo;
  
  // Constructor con argumentos posicionales
  Coche({ String marca, String modelo }) {
    this.marca = marca;
    this.modelo = modelo;
  }
  
  // Sobreescribimos el método toString
  String toString() {
    return '${ this.marca } - ${ this.modelo }';
  }
}
Resultado por consola del constructor con named arguments con Dart
Resultado por consola del constructor con named arguments con Dart

Veamos una forma más simple, más corta, que tenemos de escribir el constructor.

void main() {
  final miCoche3 = Coche(marca: 'Renault', modelo: 'Clio');

  print(miCoche3.marca);
  print(miCoche3.modelo);
  print(miCoche3);
}

class Coche {
  String marca;
  String modelo;

  // Constructor con argumentos posicionales
  /*Coche({String marca, String modelo}) {
    this.marca = marca;
    this.modelo = modelo;
  }*/
  
  // Constructor más simple (con argumentos posicionales en este caso)
  Coche({ this.marca, this.modelo });

  // Sobreescribimos el método toString
  String toString() {
    return '${this.marca} - ${this.modelo}';
  }
}

Constructores con nombre en Dart

Veamos un ejemplo de los constructores con nombre en Dart. Para esto, vamos a importar dart:convert.

import 'dart:convert';

void main() {
  // final miCoche = Coche('Renault', 'Clio');
  
  final rawJson = '{"marca": "Renault", "modelo": "Clio"}';
  Map parsedJson = json.decode(rawJson);
  
  print(parsedJson);
  
  // Uso del constructor con nombre creado abajo
  
  final coche2 = new Coche.fromJson( parsedJson );
  
  print(coche2.marca);
  print(coche2.modelo);

}

class Coche {
  String marca;
  String modelo;

  Coche( this.marca, this.modelo );
  
  Coche.fromJson( Map parsedJson ) {
    marca = parsedJson['marca'];
    modelo = parsedJson['modelo'];
  }
}

Los getters y setters en Dart

Vamos a ver los getters y setters en Dart y ya verás cómo no hay tanta complicación en la cosa. Veamos algún ejemplo. Debéis aprender que al ponerun «_» delante de cualquier propiedad, se hace privada. Sólo es visible dentro de esa clase.

void main() {
  final cuadrado = Cuadrado();
  cuadrado.lado = 2;
  
  print(cuadrado);
  print('Área: ${cuadrado.area}');
}

class Cuadrado {
  double _lado;
  // double _area;
  
  set lado( double valor ) {
    // Lanzamos un error si es menor o igual que 0
    if ( valor <= 0) {
      throw('El valor debe ser mayor que 0.');
    }
    
    // Si el valor es positivo se lo damos al lado.
    _lado = valor;
  }
  
  // Calculamos el área del cuadrado
  /*double get area {
    return _lado * _lado;
  }*/
  
  // Método simplificado
  double get area => _lado * _lado;
  
  toString () => 'Lado: $_lado';
}

Clases abstractas en Dart

En Dart, las clases abstractas se designan con la palabra reservada abstract class.

Para indicar que se implementa una clase, en Dart usamos la palabra reservada implements.

En Dart, las clases abstractas no pueden ser creadas con el constructor new. Una clase abstracta obliga a otras clases a que implementen sus propiedades y métodos. Veamos un ejemplo donde dos clases que son modelos de coche tienen que heredar obligatoriamente el atributo y el método que tiene la clase abstracta Coche.

void main() {
  final clio = new Clio();
  final focus = Focus();
  
  clio.pitar();
  focus.pitar();
}


// final clio = new Coche();

abstract class Coche {
  int ruedas;
  
  void pitar() {
    print('piiiiiiiiiiiii');
  }
}

// Clio implementa la clase abstracta Coche
class Clio implements Coche {
  int ruedas;
  int ventanillas;
  String matricula;
  
  void pitar() => print('piiii');
}

// Focus implementa la clase abstracta Coche
class Focus implements Coche {
  int ruedas;
  
  void pitar() => print('peee');
}

Si no se emplementan el atributo y el método, da error. El resultado sería el siguiente.

Resultado de ejecutar el método de la clase abstracta en Dart
Resultado de ejecutar el método de la clase abstracta en Dart

Extends en Dart

Cuando una clase extiende de otra, va a tener todas sus propiedades y métodos. Lo entenderéis claramente viendo el siguiente ejemplo de extends en Dart.

void main() {
  final coche = Coche();
  coche.marca = 'Renault';
  
  final camion = Camion();
  camion.marca = 'Volvo';
}

// Añadimos abstract para que no se puedan crear instancias de Vehiculo
abstract class Vehiculo {
  String marca;
  String modelo;
}

// La clase Coche extiende de Vahiculo
class Coche extends Vehiculo {
  
  int lMaletero;
}

// La clase Camion extiende de Vahiculo
class Camion extends Vehiculo {
  
  int lRemolque;
}

Mixins en Dart

En Dart, los Mixins es una forma de sólo asignar a las clases lo que necesitamos.

Usamos la palabra reservada with para hacer el mixin. Veamos un ejemplo muy demostrativo y claro con clases de animales, que vienen de hacer mixin de varias clases.

abstract class Animal {}


// Clases principales
abstract class Mamifero extends Animal {}

abstract class Ave extends Animal {}

abstract class Pez extends Animal {}

// Clases Mixins
abstract class Volador {
  void volar() => print('Estoy volando');
}

abstract class Caminante {
  void caminar() => print('Estoy caminando');
}

abstract class Nadador {
  void nadar() => print('Estoy nadando');
}

// Creamos los animales
class Delfin extends Mamifero with Nadador {}

class Murcielago extends Mamifero with Volador {}

class Gato extends Mamifero with Caminante {}

class Paloma extends Ave with Caminante, Volador {}

class Pato extends Ave with Caminante, Volador, Nadador {}

class Tiburon extends Pez with Nadador {}

class PezVolador extends Pez with Nadador, Volador {}

// Clase main
void main(){
  final pato = Pato();
  pato.volar();
  
  final pezVolador = PezVolador();
  pezVolador.nadar();
  pezVolador.volar();
}
Resultado por consola del mixin en Dart anterior
Resultado por consola del mixin en Dart anterior

Futures en Dart

Son muy importantes cuando estamos haciendo tareas asíncronas. Un Future es una tarea asíncrona que se hace en un hilo independiente del hilo principal que estamos ejecutando y cuando se resuelve nosotros podemos seguir ejecutando otras partes de nuestro programa.

Los Futures pueden dar errores. Usamos la palabra reservada Future. Veamos un ejemplo con código, donde nuestro Future va a tardar 4 segundos más que el hilo principal.

void main() {
  print('Vamos a pedir datos.');
  httpGet('http://api.dominio.com/ejemplo').then((data) {
    print( data );
  });
    
  print('Línea final');
}

Future<String> httpGet(String url) {
  return Future.delayed( new Duration(seconds: 4), () {
    return 'Hola, ¿qué tal?';
  } );
}

¿Qué es Async – Await? ¿Para que sirve?

El Async nos ayuda a transformar una función en una tarea asíncrona y Await nos permite esperar a que se resuelva dicha tarea, aunque nos de error.

Para poder usar el await, debemos estar a la fuerza dentro de una función async.

Los constructores en una clase no pueden ser asíncronos. No, no se pueden hacer constructores asíncronos.

Vamos a verlo transformando todo el ejemplo anterior, vamos a esperar a que la tarea se ejecute y luego pasaremos a la impresión de la última línea.

void main() async {
  print('Vamos a pedir datos.');
  String data = await httpGet('http://api.dominio.com/ejemplo');
  print( data );
    
  print('Línea final');
}

Future<String> httpGet(String url) {
  return Future.delayed( new Duration(seconds: 4), () {
    return 'Hola, ¿qué tal?';
  } );
}

Ahora puedes seguir este Curso de Flutter con la instalación de Flutter en Windows.

Publicado en: Curso de Flutter

Interacciones con los lectores

Comentarios

  1. Jessica Belen Arellano Saenz dice

    25/03/2021 a las 04:33

    Gracias por la información me sirvió de mucha ayuda para una investigación para mi tarea de programación sobre Dart.

    Responder
    • Carlos ZR dice

      12/04/2021 a las 17:30

      A ti Jessica Belen 🙂

      Responder

Deja una respuesta Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Carlos ZR

  • Sígueme en Twitter
  • Política de Cookies
  • Política de Privacidad
  • Aviso Legal

Utilizamos cookies para ofrecerte la mejor experiencia en nuestra web.

Puedes aprender más sobre qué cookies utilizamos o desactivarlas en los ajustes.

CARLOSZR.COM
Powered by  GDPR Cookie Compliance
Resumen de privacidad

Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.

Cookies estrictamente necesarias

Las cookies estrictamente necesarias tiene que activarse siempre para que podamos guardar tus preferencias de ajustes de cookies.

Si desactivas esta cookie no podremos guardar tus preferencias. Esto significa que cada vez que visites esta web tendrás que activar o desactivar las cookies de nuevo.