Codificando una App Android Con Flutter y Dart
Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)



Si estás buscando aproximaciones alternativas para desarrollo de aplicación Android, deberías considerar darle a Flutter de Google, un framework basado en el lenguaje de programación Dart, una oportunidad.
Las apps construidas con Flutter son en gran parte indistinguibles de aquellas construidas usando el SDK de Android, ambos en términos de apariencia y desempeño. Lo que es más, con modificaciones menores, pueden ser ejecutadas en dispositivos iOS también.
En este tutorial, te presentaré las bases de Flutter mostrándote cómo construir una calculadora sencilla de propinas para Android.
Prerrequisitos
Para poder seguir este tutorial, necesitarás:
- la última versión de IntelliJ IDEA
- Android Studio 2.2 o superior
- un dispositivo o emulador ejecutando Android 4.4 o superior
- una computadora ejecutando Mac o Linux
1. ¿Por Qué Usar Flutter?
Corriendo a 60 fps, las interfaces de usuario creadas con Flutter se desempeñan mucho mejor que aquellas creadas con otros frameworks de desarrollo multi-plataforma tales como React Native y Ionic. Si eso no te emociona, aquí hay algunas razones por las que podrías querer usar Flutter:
- Flutter usa Dart, un rápido lenguaje orientado a objetos con varias características útiles mixins, generics, isolates y tipos opcionales estáticos.
- Flutter tiene sus propios componentes UI, junto con un motor para generarlos en plataformas Android y iOS. La mayoría de esos componentes UI, recién salidos de la caja, conforman los lineamientos de Material Design.
- Las apps Flutter pueden ser desarrolladas usando IntelliJ IDEA, un IDE que es muy similar a Android Studio.
2. Instalando Flutter
Puedes obtener la última versión de Flutter clonando tu repositorio GitHub.
1 |
git clone https://github.com/flutter/flutter.git |
Flutter tiene varias dependencias, tales como el SDK Dart y fuentes Material Design. Afortunadamente, la primera vez que ejecutes la herramienta diagnóstica de Flutter, todas estas son instaladas automáticamente.
1 |
cd flutter/bin
|
2 |
./flutter doctor |



Para poder construir aplicaciones Android, también debes apuntar a Flutter al directorio en donde instalaste Android Studio.
1 |
./flutter config --android-studio-dir ~/android-studio
|
3. Configurando IntelliJ IDEA
Aunque puedes usar el CLI de Flutter directamente para crear y ejecutar nuevas apps, probablemente tendrás una mucho mejor experiencia si usas un IDE. El IDE recomendado para Flutter es IntelliJ IDEA.
Antes de comenzar a desarrollar apps Flutter con este, sin embargo, debes instalar complementos para Dart y Flutter. Para hacerlo, comienza seleccionando Configurar > Complementos en la pantalla de bienvenida de IntelliJ.



En el diálogo que emerge, presiona el botón Explorar repositorios... y busca el complemento Dart. Una vez que lo encuentres, presiona el botón Instalar para instalarlo.



De manera similar, busca e instala el complemento Flutter.



Una vez que ambos complementos están instalados, reinicia IntelliJ IDEA.
Debes ahora apuntar al complemento Flutter al directorio en donde instalaste Flutter. Para hacerlo, selecciona Configurar > Ajustes en la pantalla de bienvenida y, en el diálogo que emerge, navega a Lenguajes y Frameworks > Flutter. En el campo de ruta Flutter SDK, teclea la ruta absoluta del directorio.



Presiona OK para completar la configuración.
4. Creando un Nuevo Proyecto
Para crear un nuevo proyecto Flutter, presiona el botón Crear Nuevo Proyecto en la pantalla de bienvenida. En el diálogo Nuevo Proyecto, elige Flutter y presiona Siguiente.
Ahora puedes darle un nombre significativo a tu proyecto y presionar Terminar.



Una vez que el proyecto ha sido generado, sugiero que presiones el botón Ejecutar para asegurar que el SDK Dart, los complementos y el framework Flutter están todos configurados correctamente. Si lo están, después de varios segundos, deberías ver la siguiente pantalla en tu dispositivo o emulador:



Nota qué, desde este punto, no necesitas presionar el botón Ejecutar de nuevo incluso después de hacer cambios de código. Flutter soporta recarga en vivo, una característica que te permite empujar inmediatamente actualizaciones a la app sin reiniciarla.



5. Creando Widgets
En este tutorial, estaremos creando una app calculadora de propinas con los siguientes widgets:
- un
TextFieldpara aceptar una cuenta
- un
TextFieldpara aceptar un porcentaje de propina
- un
RaisedButtonque el usuario puede presionar para calcular la propina
Cada widget de Flutter puede ser un StatelessWidget o un StatefulWidget. Como su nombre sugiere, un StatefulWidget tiene un objeto de State asociado con él, que le permite no solo almacenar datos, sino también reaccionar a cambios en los datos.
Un StatelessWidget, por otro lado, es un objeto más simple, no diseñado para almacenar persistentemente cualquier dato. Para mantener corto este tutorial, estaremos creando nuestra calculadora de propinas como un StatelessWidget. Así pues, abre main.dart, quita todos sus contenidos, y agrega el siguiente código a el:
1 |
import 'package:flutter/material.dart'; |
2 |
|
3 |
class TipCalculator extends StatelessWidget { |
4 |
|
5 |
}
|
En el código de arriba, la línea import es importante porque material.dart es la librería que contiene todos los widgets Material Design que estaremos usando en esta app.
Para almacenar la cantidad de la cuenta y el porcentaje de propina, agrega dos variables miembro a la clase.
1 |
double billAmount = 0.0; |
2 |
double tipPercentage = 0.0; |
Para comenzar a crear la interfaz de usuario de la app, anula el método build().
1 |
@override
|
2 |
Widget build(BuildContext context) { |
3 |
// More code goes here
|
4 |
}
|
Creemos ahora los dos widgets TextField. Mientras lo hacemos, podemos especificar detalles tales como las etiquetas que queremos asociar con los widgets y los tipos de teclados virtuales que deben ser mostrados cuando están enfocados.
Debido a que no podemos recolectar directamente los contenidos de un widget TextField, debemos también asociar un evento manejador onChanged con este. Dentro del manejador, que recibe un objeto InputValue, podemos actualizar los contenidos de nuestras variables de miembro de la clase.
En consecuencia, agrega el siguiente código dentro del método build():
1 |
// Create first input field
|
2 |
TextField billAmountField = new TextField( |
3 |
labelText: "Bill amount(\$)", |
4 |
keyboardType: TextInputType.number, |
5 |
onChanged: (InputValue value) { |
6 |
try { |
7 |
billAmount = double.parse(value.text); |
8 |
} catch (exception) { |
9 |
billAmount = 0.0; |
10 |
}
|
11 |
}
|
12 |
);
|
13 |
|
14 |
// Create another input field
|
15 |
TextField tipPercentageField = new TextField( |
16 |
labelText: "Tip %", |
17 |
keyboardType: TextInputType.number, |
18 |
hintText: "15", |
19 |
onChanged: (InputValue value) { |
20 |
try { |
21 |
tipPercentage = double.parse(value.text); |
22 |
} catch (exception) { |
23 |
tipPercentage = 0.0; |
24 |
}
|
25 |
}
|
26 |
);
|
Incluso si nunca has trabajado con Dart, el código de arriba debería ser bastante intuitivo, mientras estés familiarizado con Java. Por ejemplo, puedes ver que estamos usando el método parse() para convertir cada texto de contenido del widget TextField a un objeto double. Debido a que el método parse() puede arrojar un FormatException, también está rodeado por un bloque try...catch.
Crear un widget RaisedButton es mucho como crear un widget TextField. Sin embargo, para asignar una etiqueta a este, debes crear un nuevo widget Text y agregarlo como su child.
1 |
// Create button
|
2 |
RaisedButton calculateButton = new RaisedButton( |
3 |
child: new Text("Calculate"), |
4 |
onPressed: () { |
5 |
// More code goes here
|
6 |
}
|
7 |
);
|
Dentro del evento manejador onPressed del botón, calcularemos la propina y la cantidad total a ser pagada, y mostraremos ambos en un diálogo modal. Para crear el diálogo, podemos usar la clase AlertDialog. Una vez creada, el diálogo puede ser mostrado pasándolo como un argumento al método showDialog().
En consecuencia, agrega el siguiente código dentro del evento manejador onPressed:
1 |
// Calculate tip and total
|
2 |
double calculatedTip = billAmount * tipPercentage / 100.0; |
3 |
double total = billAmount + calculatedTip; |
4 |
|
5 |
// Generate dialog
|
6 |
AlertDialog dialog = new AlertDialog( |
7 |
content: new Text("Tip: \$$calculatedTip \n" |
8 |
"Total: \$$total") |
9 |
);
|
10 |
|
11 |
// Show dialog
|
12 |
showDialog(context: context, child: dialog); |
En el código de arriba, nota que he usado la característica de interpolación de cadena de Dart para embeber variables dentro de content del diálogo. También, puedes ver que las literales de cadena en Dart pueden ser concatenadas solo colocándolas a un lado de otra---aunque puedes usar también el operador +, si quieres.
6. Creando un Árbol de Widget
Una app Flutter usualmente no es nada más que un árbol de widgets. En otras palabras, tu creas una app Flutter simplemente creando múltiples widgets y estableciendo relaciones padre-hijo entre ellas.
Actualmente, no hay relaciones dentro de los widgets que creamos en el paso anterior. Como podrás haber adivinado, todos van a ser hijos, así que creemos ahora un widget padre para ellos.
Un widget que puede tener múltiples hijos es usualmente referido como widget de diseño. Flutter ofrece varios widgets de diseño de los cuales elegir. Para nuestra app, el widget Column es más apropiado porque posiciona a todos sus hijos uno debajo del otro.
De manera adicional, para conformar la especificación Material Design, debemos agregar un padding de 16 dp al widget Column. Podemos hacerlo haciéndolo un child de un widget Container.
1 |
Container container = new Container( |
2 |
padding: const EdgeInsets.all(16.0), |
3 |
child: new Column( |
4 |
children: [ billAmountField, |
5 |
tipPercentageField, |
6 |
calculateButton ] |
7 |
)
|
8 |
);
|
Una interfaz de usuario Material Design no está completa sin una barra de app. Así pues, crea una ahora usando el widget AppBar.
1 |
AppBar appBar = new AppBar(title: new Text("Tip Calculator")); |
Los diseños conteniendo barras de app y contenedores son tan comunes que Flutter ofrece un widget Scaffold para ayudarte a establecer rápidamente una relación entre estos.
1 |
Scaffold scaffold = new Scaffold(appBar: appBar, |
2 |
body: container); |
Con el widget Scaffold en su raíz, nuestro árbol de widgets está ahora listo. Puedes continuar y usar el widget Scaffold como el valor de regreso del método build().
1 |
return scaffold; |
Si te resulta difícil visualizar el árbol, el siguiente diagrama debería ayudar:



7. Creando un Punto de Entrada
Nuestro archivo Dart necesita una función main() como su punto de entrada. Dentro de este, debemos llamar la función runApp() para inflar realmente y generar el árbol de widgets que creamos en el paso anterior.
De manera adicional, nuestro widget TipCalculator debería ser colocado dentro de un widget MaterialApp para que un tema Material Design y esquema de color puedan ser aplicados a este. Así pues, agrega el siguiente código a main.dart:
1 |
void main() { |
2 |
runApp(new MaterialApp( |
3 |
title: 'Tip Calculator', |
4 |
home: new TipCalculator() |
5 |
));
|
6 |
}
|
Puedes ahora presionar el botón Hot Reload App para comenzar a usar la app en tu dispositivo.



Conclusión
En este tutorial, aprendiste como usar Flutter y Dart, junto con IntelliJ IDEA, para crear un a simple app para Android.
En mi opinión, Flutter tiene casi todo lo que un desarrollador podría buscar en un framework de desarrollo móvil multi-plataforma. Antes de que decidas comenzar a construir tu siguiente gran app con el, sin embargo, ten en cuenta que aún es un framework muy nuevo y en rápida evolución.
Para aprender más sobre Flutter, puedes referirte a su documentación oficial.



