Primeros pasos con Flutter

Este es el primer tutorial de las serie Fundamentos de Flutter en el cual aprendemos sobre los conceptos básicos de Flutter desarrollando aplicaciones móviles simples. En este tutorial desarrollaremos un simple hola mundo pero explicaremos los conceptos más importantes detras de Flutter.

Índice

  1. Qué es Flutter
  2. Instalación de Flutter
  3. Nuestro primer archivo
  4. Separando la lógica en archivos distintos
  5. Creando la pantalla principal o Scaffold
  6. Eliminando el banner

1. Qué es Flutter

Flutter es un SDK (Software development kit) creado por Google para diseñar interfaces nativas para iOS y Android bajo un mismo código. Por este motivo Flutter pertenece al estilo de desarrollo Cross Platform.

Flutter utiliza el lenguaje de programación Dart también creado por Google. Con este lenguaje construimos el Widget Tree que es la forma en la que se estructura y crea la interface visual en Flutter. Esta es una de las principlales diferencias con el desarrollo nativo, mientras que en el desarrollo nativo todo lo tienes que crear desde cero, en Flutter tenemos componentes ya creados y listos para utilizarse llamamos widgets.

Qué es un widget

Los widgets son una especie de bloques de lego con los que se va construyendo la aplicación en Flutter. Pero, un widget es al fin y al cabo una clase que hereda caracteristicas de uno de los dos tipos de widget principales.

  • Stateless Widgets: Este es un widget que no almacenan estado.
  • Stateful Widget: Este widget si almacenan estado y además permiten redibujarse a sí mismos cuando su estado cambia.

En resumen una aplicación de Flutter es solo una gran cantidad de widgets estructurados uno dentro de otro formando un árbol de jerarquías donde existirá un widget principal o widget padre.

2. Instalación de Flutter

Para poder instalar Flutter primero debes tener instalado el SDK de Dart. Para saber como hacerlo puedes revisar el primer tutorial de la serie Fundamentos de Dart en este mismo blog.

Luego de instalar el SDK de Dart necesitamos intalar el SDK de Flutter para eso podemos visistar la documentación de instalación de Flutter donde encontraremos cómo instalar en los distintos sistemas operativos. No te olvides agregar las variables de entorno para poder utilizar la terminar con Flutter. En la documentación dice cómo hacerlo.

Una forma de saber si Flutter está funcionando correctamente es usar la herramienta Flutter Doctor usando el siguiente comando en la terminal.

flutter doctor

# Ver los demás comandos
flutter --help

Ahora si lo que queremos es abrir un proyecto de Flutter descargado de GitHub tenemos que descargar todas las dependencias que utiliza el proyecto usando flutter package get como se muestra en el siguiente ejemplo.

3. Nuestro primer proyecto

Para crear un proyecto en Flutter en VSCode ingresamos a la Paleta de Comandos usando F1 y en ahi seleccionamos Flutter: New Project. Ahora nos pedirá el nombre del proyecto el cual solo debe contener minusculas y guiones bajos. Luego de esto se generará un proyecto nuevo con un código base para una aplicación contadora de clicks.

Por ahora eliminaremos todo el código autogenerado en el archivo lib/main.dart ya que la idea es aprender y comenzar desde cero. También eliminaremos la carpeta test ya que en un principio no la utilizaremos. Por ahora nos centraremos en la carpeta lib ya que es ahí donde irá nuestro código. En futuros tutoriales iremos adentrándonos en las demás carpetas y archivos de Flutter de manera práctica.

Trabajaremos dentro de nuestro archivo main.dart. En ahi crearemos nuestro método que comenzará la ejecución de nuestra aplicación. A continuación, explicaremos cada una de las líneas de código necesarios para mostrar un hola mundo en Flutter.

// 3. Este es el import necesario para el runApp() y todos los widgets de flutter que usaremos.
import 'package:flutter/material.dart';

// 1. Este es el método principal
void main(){

// 2. Cuando la aplicación se ejecute buscará esta funcion para comenzar su ejecución.
// Esta funcion toma como parametro un widget, este será nuestro primer widget.
  runApp(new MyApp());
}


// 4. Crearemos un widget del tipo StatelessWidget.
// Los widgets son clases comunes y corrientes que extienden de determinada clase según el tipo de widget que deseamos crear.
// En este caso MyApp extiende de StatelessWidget
// StatelessWidget nos permite crear un widget que no almacena estado osea estático
class MyApp extends StatelessWidget{

// 5. Como es una clase abstracta tiene un método que necesariamente debe ser sobreescrito, este es el método 'build'.
// Este método recibe como parametro un contexto.
// Este contexto es dado por runApp para que el build haga uso de él al crear el widget.
// Dentro de build es donde diseñaremos nuestro widget y este lo retornaremos.
  
  Widget build(BuildContext context) {

    // 6. MaterialApp es el widget padre que proporciona el diseño de material dentro de la aplicación.
    return MaterialApp(

       // 7. Por ahora solo le daremos de parametro un Widget llamado home.
       // Dentro de este podemos colocar otros widget, pero por ahora solo irá un texto.
       // Los textos también son widgets
      home: Text('Hola mundo')

    );
  }
}

Ahora para correr nuestra aplicación tenemos que hacer uso del debug de VSCode. Para esto precionamos F5 y seleccionamos el dispositivo virtual donde queremos probar nuestra aplicación. Por ahora deberiamos obtener algo como esto.

Aqui es donde entra en acción otra de las grandes caracteristicas de Flutter. Flutter tiene lo que se conoce como Hot Reload que nos permite visualizar los cambios en el emulador solo con guardar dichos cambios en nuestro editor de código. Gracias a esto Flutter es ampliamente valorado.

Volviendo al proyecto, cómo ya dijimos podemos colocar un widget dentro de otro hasta obtener lo que queramos. Flutter tiene una serie de Widgets que nos ayudarán a dar diseño a nuestra aplicación. Uno de estos widget es Center. Este nos permitirá centrar el widget que lleve dentro. Para colocar algún widget dentro de otro generalmente usamos la propiedad child para asignar un Widget hijo.

home: Center(
    child: Text('Hola mundo'),
)

4. Separando la lógica en archivos distintos

Una de las buenas practicas de programación en el lenguaje orientado a objetos es separar nuestra lógica en distintas clases y métodos, pero también en distintos archivos. Todo esto con la finalidad de escribir un c;odigo ordenado y entendible.

Por ese motivo sacaremos la clase MyApp fuera de nuestro archivo main.dart. Para ello también es bueno separar la estructura de nuestro código en carpetas, generalmente se usa la carpeta lib/src de source para contener el código fuente de nuestra aplicación. El archivo main no lo movemos ya que al ser el método que ejecuta nuestra aplicación y es bueno tener un acceso más rápido y directo a él.

MyApp es nuestro widget principal o padre y es por eso que irá directamente dentro de la carpeta src. Asi que dentro de esta carpeta creamos un archivo llamado myapp.dart. Es una convención usar como nombre de archivo el nombre de la clase pero todo en minusculas.

import 'package:flutter/material.dart';

class MyApp extends StatelessWidget{

  
  Widget build(BuildContext context) {

    return MaterialApp(

      home: Center(
        child: Text('Hola mundo'),
      )

    );
  }
}

Dejando a lib/main.dart como sigue.

import 'package:flutter/material.dart';

import 'package:contador/src/app.dart';

// Es recomendable colocar las importaciones de librerias flutter antes que las importaciones de librerias propias del proyecto.

void main(){
  runApp(new MyApp());
}

5. Creando la pantalla principal o Scaffold

Para crear la página principal de nuestra aplicación crearemos la carpeta src/pages. Aquí crearemos el archivo dart llamado home_page.dart. Este archivo contendrá un widget llamado HomePage osea una clase llamada HomePage que extiende StatelessWidget. Usamos StatelessWidget por que nos creará un widget que no almacena estado, basicamente un widget estático. Ahora este widget retornará un Scaffold en el método build().

Un Scaffold es el widget que implementa el aspecto visual de material design además proporciona las propiedades necesarias para mostrar un appBar, snackBars, etc. Por este motivo es el widget que contendrá a nuestra aplicación.

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget{

  // 1. Dentro del build se diseña nuestra aplicación. En este caso solo creará un Scaffold
  
  Widget build(BuildContext context) {

    return Scaffold(

      // 2. El scaffold tiene propiedades que ayudan a diseñar nuestra aplicación
      // Sus parametros del scaffold son los que nos permiten diseñar nuestra aplicación.
      // Queremos que nuestra aplicación tenga AppBar y además Flutter ya nos brinda un widget AppBar
      appBar: AppBar(
        title: Text('Titulo'),
        centerTitle: true,
      ),

      // 3. La propiedad body es el cuerpo del Scaffold
      body: Center(
        child: Text('Hola mundo'),
      ),
    );
  }
}

De esta manera ya diseñamos la primera pantalla para nuestra aplicación, ahora la clase MyApp solo hará un llamado al widget HomePage.

import 'package:flutter/material.dart';

import 'package:contador/src/pages/home_page.dart';

class MyApp extends StatelessWidget{

  
  Widget build(BuildContext context) {

    return MaterialApp(
      home: HomePage()
    );
  }
}

6. Eliminando el banner

Por último vamos eliminar ese fastidioso banner que sale al ejecutar nuestra aplicación en el emulador. Para hacer esto nos dirigimos a la clase que retorna un MaterialApp y colocamos la propiedad debugShowCheckedModeBanner, la cual debemos colocar con el valor de false.

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
      debugShowCheckedModeBanner: false,
    );
  }

Terminamos

Mira que fácil es programar en Flutter, quiza el mismo tiempo pero si con muchos conocimientos de programación orientada a objetos nos hubiera costado hacer lo mismo en Android nativo, ya sea usando Kotlin o Java.