Creando nuestra primera app multiplataforma, un verificador de palíndromos
Introducción En los capítulos anteriores de nuestra serie sobre Flutter, hemos establecido una …
leer másYa hemos hablado de Flutter y como ha ganado popularidad como uno de los frameworks más potentes para crear aplicaciones móviles con un solo código base. Sin embargo, sus capacidades van más allá del desarrollo de aplicaciones móviles y web, permitiendo la creación de aplicaciones de escritorio multiplataforma. Con Flutter, podemos desarrollar para Linux, Mac y Windows, utilizando las mismas herramientas y paradigmas que ya conocemos, sin necesidad de aprender tecnologías adicionales específicas para cada plataforma.
El desarrollo de aplicaciones de escritorio a menudo ha sido un desafío para los desarrolladores que quieren ofrecer una experiencia uniforme en múltiples sistemas operativos. Tradicionalmente, esto requería aprender varias herramientas y lenguajes de programación según la plataforma: C# para Windows, Objective-C o Swift para macOS, y lenguajes basados en Linux para otros entornos. Flutter elimina esta complejidad ofreciendo una única solución para todas estas plataformas, utilizando Dart como lenguaje central y brindando un rico ecosistema de widgets y herramientas.
El motor gráfico de Flutter, Skia, permite crear interfaces de usuario altamente personalizables y fluidas, sin importar la plataforma en la que se ejecute la aplicación. Esto asegura que nuestras aplicaciones mantengan la misma calidad visual y rendimiento en cualquier sistema operativo, ya sea en un dispositivo móvil o en un escritorio.
Otro aspecto fundamental es la capacidad de prototipado rápido. Al igual que en sus versiones móviles y web, Flutter en escritorio permite a los desarrolladores ver los cambios en tiempo real, gracias a la función Hot Reload. Esto facilita iteraciones rápidas y mejora la experiencia de desarrollo, sobre todo en las fases tempranas del ciclo de vida de la aplicación.
En este artículo, no sólo veremos cómo Flutter nos permite desarrollar aplicaciones de escritorio, sino que también exploraremos cómo elegir las bibliotecas adecuadas y qué consideraciones tomar al integrar funcionalidades específicas a través de paquetes externos. Después, pondremos todo esto en práctica con un ejemplo real con una aplicación para visualizar la evolución de los valores de algunas criptomonedas.
Al desarrollar aplicaciones con Flutter, una de las fuentes más importantes de recursos es Pub Dev, el repositorio oficial de paquetes para el ecosistema de Dart y Flutter. Aquí es donde encontraremos bibliotecas y herramientas adicionales que nos ayudarán a implementar funcionalidades en nuestras aplicaciones, desde gestión de estado hasta gráficos, bases de datos locales, y mucho más. Sin embargo, al trabajar con múltiples plataformas como móvil, web y escritorio, es crucial saber distinguir los detalles clave de cada biblioteca antes de integrarla en nuestro proyecto.
Cuando navegamos por Pub Dev, hay varios factores a tener en cuenta para asegurarnos de que el paquete seleccionado es adecuado para nuestra aplicación y compatible con las plataformas objetivo.
Uno de los detalles más importantes al seleccionar un paquete es asegurarnos de que es compatible con las plataformas en las que queremos que se ejecute nuestra aplicación. Pub Dev ofrece un apartado específico en cada paquete, debajo del nombre del mismo, que indica claramente para qué entornos el paquete ha sido diseñado. Debemos prestar atención a que el paquete soporte:
Esta información nos ahorra tiempo y nos evita errores al seleccionar una biblioteca que no funcione en todas las plataformas en las que planeamos desplegar nuestra aplicación.
Otro aspecto fundamental es la versión del paquete que estamos integrando. En Pub Dev, las versiones están
claramente marcadas y debemos asegurarnos de que estamos utilizando la última versión estable. Las versiones suelen
seguir el estándar de versionado semántico (x.y.z
), donde:
Debemos tener cuidado con las versiones mayores, ya que pueden implicar cambios importantes en la API del paquete y pueden requerir modificaciones en nuestro código.
La versión 3 de Flutter introduce mejoras significativas en el rendimiento y la estabilidad de las aplicaciones, así como nuevas características y optimizaciones. Al elegir un paquete, es importante asegurarnos de que sea compatible con la versión 3 de Dart, ya que esto garantiza que podremos aprovechar al máximo las ventajas de la última versión de Flutter. En Pub Dev, podemos ver si un paquete es compatible con la versión 3 de Dart justo al lado de su nombre.
Pub Dev también asigna puntuaciones a los paquetes basándose en varios factores, como la popularidad, la salud y el mantenimiento. Estas puntuaciones nos ayudan a identificar paquetes confiables y bien mantenidos por la comunidad. Un paquete con una alta puntuación de popularidad probablemente sea utilizado por muchos desarrolladores y cuente con una comunidad activa que reporta y soluciona problemas rápidamente.
Elegir paquetes con buenas puntuaciones y mantenimiento activo puede ahorrarnos muchos problemas en el futuro, ya que es más probable que sean actualizados regularmente y compatibles con futuras versiones de Flutter.
Finalmente, antes de elegir un paquete, es recomendable revisar la documentación y los ejemplos que proporciona. Una buena documentación es crucial para integrar un paquete de manera eficiente, y los ejemplos nos permiten ver rápidamente cómo implementar las funcionalidades que ofrece el paquete. Además, es útil verificar si el paquete tiene un repositorio en GitHub donde se pueden reportar errores o sugerir mejoras.
Para nuestro ejemplo vamos a utilizar los siguientes paquetes de Pub Dev:
Todos ellos compatibles con Flutter Desktop nos proporcionan las herramientas necesarias para crear una aplicación con los requisitos establecidos. En este ejemplo práctico crearemos un visualizador de la evolución del precio de algunas criptomonedas.
Ahora que ya hemos explorado cómo identificar las bibliotecas más adecuadas para nuestro proyecto en Pub Dev, vamos a sumergirnos en nuestro ejemplo práctico, construiremos un visualizador de la evolución de valores de criptomonedas con una interfaz sencilla y clara. La aplicación permitirá al usuario seleccionar las criptomonedas que desea visualizar y mostrará un gráfico interactivo con los precios de las monedas digitales en un período de tiempo seleccionado, también modificable.
Antes de pasar al código fuente, veamos brevemente la interfaz del proyecto. Nuestra aplicación consistirá en:
A continuación, repasamos algunas de las partes más importantes del código fuente que hemos utilizado para crear esta aplicación. Tienes todo el código disponible en nuestro repositorio de Github.
Una de las partes fundamentales de esta aplicación es la visualización de los datos obtenidos de la API. Para mostrar de manera gráfica los valores de las criptomonedas seleccionadas, utilizamos el paquete fl_chart. Éste nos permite crear gráficos interactivos y altamente personalizables.
Widget _buildLineChart() {
DateTime today = DateTime.now();
int daysInPeriod = int.parse(_selectedPeriod);
DateTime startDate = today.subtract(Duration(days: daysInPeriod));
return LineChart(
LineChartData(
maxX: daysInPeriod.toDouble() - 1,
borderData: FlBorderData(
show: true,
border: Border(
left: BorderSide(color: Colors.black),
bottom: BorderSide(color: Colors.black),
top: BorderSide.none,
right: BorderSide.none,
),
),
titlesData: FlTitlesData(
show: true,
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 22,
interval: 1,
getTitlesWidget: (value, meta) {
DateTime date = startDate.add(Duration(days: value.toInt()));
return SideTitleWidget(
axisSide: meta.axisSide,
child: Text(
DateFormat('dd/MM').format(date),
style: TextStyle(fontSize: 10),
),
);
},
),
),
leftTitles: AxisTitles(
sideTitles: SideTitles(
reservedSize: 40,
showTitles: true,
getTitlesWidget: (value, meta) {
return Text('\$${value.toInt()}',
style: TextStyle(fontSize: 10));
},
),
),
),
lineBarsData: _cryptoPrices.entries.map((entry) {
return LineChartBarData(
spots: entry.value.asMap().entries.map((e) {
return FlSpot(e.key.toDouble(), e.value);
}).toList(),
isCurved: true,
color: _cryptoList[entry.key],
barWidth: 2,
dotData: FlDotData(show: false),
);
}).toList(),
),
);
}
Aquí hemos creado un gráfico de líneas que muestra los valores de las criptomonedas en un período de
tiempo seleccionado por el usuario. Utilizamos la clase LineChart
de fl_chart para configurar los datos y la
apariencia del gráfico, incluyendo los ejes, títulos y colores de las líneas.
Para permitir al usuario elegir las criptomonedas que desea visualizar, utilizamos un diálogo emergente que muestra una
lista de opciones. Para implementar esta funcionalidad, creamos un diálogo personalizado con un Widget sin estado que utiliza
un AlertDialog
en el que se muestra una lista de opciones de criptomonedas predeterminadas. Si necesitas recordar cómo
era exactamente el tema de los estados en Flutter, puedes echar un vistazo a nuestro artículo hablando sobre los Widgets,
la piedra angular de Flutter.
class SelectCryptoDialog extends StatelessWidget {
final Map<String, Color> cryptoList;
final Map<String, bool> selectedCryptos;
final Function(String, bool) onSelected;
const SelectCryptoDialog({
required this.cryptoList,
required this.selectedCryptos,
required this.onSelected,
});
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Select Cryptocurrencies'),
content: SingleChildScrollView(
child: StatefulBuilder( // Asegura que el estado se actualice correctamente dentro del diálogo
builder: (BuildContext context, StateSetter setState) {
return Column(
mainAxisSize: MainAxisSize.min,
children: cryptoList.keys.map((crypto) {
return CheckboxListTile(
title: Text(crypto),
value: selectedCryptos[crypto],
activeColor: cryptoList[crypto],
onChanged: (bool? selected) {
setState(() {
onSelected(crypto, selected!); // Actualizar selección
});
},
);
}).toList(),
);
},
),
),
actions: [
TextButton(
child: Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
}
}
En este fragmento de código, creamos un diálogo emergente que muestra una lista de opciones de criptomonedas. Utilizamos
un AlertDialog
para mostrar las opciones y permitir al usuario seleccionar o deseleccionar las criptomonedas deseadas.
Estas criptomonedas son las que se mostrarán en el gráfico de evolución de precios y podrán ser mostrarse u ocultarse utilizando
los controles de visibilidad.
Para obtener los datos de las criptomonedas, utilizamos una API externa que proporciona información actualizada sobre los valores de las monedas digitales. En este caso, utilizamos la API de CoinGecko para obtener los precios de las criptomonedas seleccionadas.
Future<List<double>> getCryptoPrices(String coinId, String days) async {
try {
final url = Uri.parse('$baseUrl/coins/$coinId/market_chart?vs_currency=usd&days=$days');
final response = await http.get(url);
if (response.statusCode == 200) {
final data = json.decode(response.body);
List<double> prices = List<double>.from(data['prices'].map((priceData) => priceData[1]));
return prices;
} else {
throw Exception('Failed to load data: ${response.statusCode}');
}
} catch (e) {
throw Exception('Error fetching data: $e');
}
}
En este fragmento de código, realizamos una solicitud HTTP a la API de CoinGecko para obtener los precios de la
criptomoneda indicada. Con la biblioteca http realizamos la solicitud y jsonDecode se encarga de gestionar
la respuesta JSON. Una vez que obtenemos los datos, actualizamos el estado de la aplicación con los precios de las
criptomonedas.
Compilar el código es tan sencillo como ejecutar flutter run -d windows
para Windows, flutter run -d macos
para Mac
o flutter run -d linux
para Linux. Flutter Desktop se encargará de compilar la aplicación para la plataforma indicada y
generará el ejecutable para distribuir la aplicación.
Te invito a probarlo y a jugar con la aplicación, puedes encontrar el código fuente completo en nuestro repositorio de Github y seguir explorando las posibilidades de Flutter Desktop. Podrías añadir más funcionalidades como mostrar el precio actual de las criptomonedas, una gráfica que muestre los cambios por horas o periodos más cortos, o incluso implementar un sistema de notificaciones para cambios significativos en los precios. También podrías mejorar el diseño de la aplicación para hacerla más atractiva visualmente, ahora mismo utiliza la configuración por defecto de Flutter. Hay un montón de funcionalidades y mejoras para añadir a este proyecto.
En este artículo, hemos explorado cómo Flutter puede ser utilizado para crear aplicaciones de escritorio multiplataforma, junto con una guía sobre cómo elegir paquetes compatibles para tu proyecto. Hemos visto cómo identificar las bibliotecas más adecuadas en Pub Dev y hemos aplicado estos conocimientos en un ejemplo práctico de un visualizador de la evolución de criptomonedas.
Flutter Desktop ofrece una solución poderosa y unificada para el desarrollo de aplicaciones de escritorio, permitiéndonos crear experiencias de usuario consistentes en múltiples sistemas operativos. Con la creciente popularidad de Flutter y su rico ecosistema de paquetes, es el momento perfecto para explorar las posibilidades que ofrece esta tecnología para el desarrollo de aplicaciones multiplataforma modernas. ¡Happy Coding!
Quizá te puedan interesar
Introducción En los capítulos anteriores de nuestra serie sobre Flutter, hemos establecido una …
leer másEn el capítulo anterior hemos visto los orígenes del framework Flutter, quién lo creó, un poco sobre …
leer másFlutter es un framework de desarrollo de aplicaciones móviles creado por Google, utiliza el motor de …
leer másDe concepto a realidad