Bienvenido, me llamo Miguel y aquí les traigo este nuevo artículo.
Índice
Cotizaciones de acciones multiplataforma
En la publicación más reciente sobre SwiftUI, aprendimos cómo crear la aplicación Apple Stocks en el marco SwiftUI.
Dado que Flutter y SwiftUI comparten muchas similitudes, pensamos que sería una buena idea implementar la misma aplicación usando el marco Flutter.
En esta publicación de varias partes, aprenderemos cómo crear la página de inicio que muestra acciones al usuario.
En una publicación futura, cubriremos cómo implementar la página de listado de noticias para la aplicación de acciones Flutter. Eche un vistazo a la captura de pantalla de la aplicación finalizada.
Tour del servidor
Nuestro servidor se implementa en Node utilizando el paquete Express.js y devuelve acciones codificadas como JSON. La implementación completa del servidor se muestra a continuación:
// init project const express = require("express"); const app = express(); app.get("/stocks", (req, res) => { let stocks = [ { symbol: "GOOG", description: "Google Innovation Media", price: 1080, change: "-0.24" }, { symbol: "MSFT", description: "Microsoft Cooporation", price: 60, change: "+3.45" }, { symbol: "FB", description: "Facebook Social Media", price: 220, change: "-1.56" }, { symbol: "AMAZON", description: "Amazon Everything Store ", price: 400, change: "+6.56" } ]; res.json(stocks); }); // listen for requests :) const listener = app.listen(process.env.PORT, function() { console.log("Your app is listening on port " + listener.address().port); });
¡Nada sofisticado!
Obtención de acciones de la API web JSON
Comencemos por implementar un cliente que obtendrá datos de la API JSON. El cliente dispondrá de un único método para hacerse con todas las existencias y devuelve la respuesta como futuro.
Estamos utilizando el paquete HTTP para realizar la solicitud de red, pero puede utilizar cualquier otra biblioteca HTTP. La implementación del servicio web se muestra a continuación:
import 'package:stocks_app_flutter/models/stock.dart'; import 'package:http/http.dart' as http; class Webservice { Future<List<Stock>> getStocks() async { final url = "https://silicon-rhinoceros.glitch.me/stocks"; final response = await http.get(url); if (response.statusCode == 200) { Iterable json = jsonDecode(response.body); return json.map((stock) => Stock.fromJson(stock)).toList(); } else { throw Exception("Error fetching stocks"); } } }
El servicio web obtiene las existencias de nuestro servidor personalizado y luego completa el modelo de existencias, que luego se devuelve a la persona que llama como un archivo Future<List<Stock>>
.
El modelo Stock se implementa a continuación:
class Stock { final String symbol; final String company; final double price; final String change; Stock({this.symbol, this.company, this.price, this.change}); factory Stock.fromJson(Map<String, dynamic> json) { return Stock( company: json["description"], change: json["change"], symbol: json["symbol"], price: json["price"].toDouble()); } }
El fromJson
método de fábrica toma un Map
objeto y luego devuelve una nueva instancia de Stock
basado en los datos JSON.
A continuación, necesitamos que los datos de las acciones se muestren en la página. Antes de pasar a la implementación de la interfaz de usuario, necesitamos implementar modelos de vista que puedan contener y suministrar los datos a la vista.
Implementar modelos de vista
Los modelos de vista son responsables de transportar los datos y luego vincularlos a la vista. Un modelo de vista puede representar una página completa, incluso con modelos de vista secundarios para orientar partes de la página.
La implementación de modelos de vista se muestra a continuación:
import 'package:flutter/material.dart'; import 'package:stocks_app_flutter/models/stock.dart'; import 'package:stocks_app_flutter/services/webservice.dart'; class StockListViewModel extends ChangeNotifier { List<StockViewModel> stocks = List<StockViewModel>(); List<StockViewModel> allStocks = List<StockViewModel>(); Future<void> fetchStocks() async { final result = await Webservice().getStocks(); stocks = result.map((stock) => StockViewModel(stock: stock)).toList(); allStocks = stocks; notifyListeners(); } void search(String searchTerm) { if(searchTerm.isEmpty) { stocks = allStocks; } else { stocks = allStocks.where((stock) => stock.symbol.startsWith(searchTerm)).toList(); } notifyListeners(); } } class StockViewModel { final Stock stock; StockViewModel({this.stock}); String get symbol { return stock.symbol.toUpperCase(); } String get company { return stock.company; } double get price { return stock.price; } String get change { return stock.change; } }
El StockListViewModel
representa la página completa y StockViewModel
representa las celdas de existencias individuales que se mostrarán en una lista.
El fetchStocks
método es responsable de usar la Webservice
instancia y recuperar todas las existencias.
Una vez que se obtienen las existencias, el resultado se transforma en una matriz de StockViewModel
objetos y se asigna a la stocks
propiedad de StockListViewModel
.
El StockListViewModel
también se extiende la ChangeNotifier
clase, lo que le permite notificar a los oyentes. Una vez notifyListeners
que se activa el método, se notifica a todos los oyentes y pueden tomar medidas.
Para nuestro caso, queremos actualizar la vista para que pueda mostrar las últimas existencias.
Para recibir una notificación de cambio del notificador de cambios, deberá usar ChangeNotifierProvider
. ChangeNotifierProvider
es parte del paquete del proveedor. Se pubspec.yaml
actualiza para agregar el paquete del proveedor.
dependencies: flutter:sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.2 http: ^0.12.0+4 provider: ^4.0.1
A continuación, veamos cómo podemos pasar la StockListViewModel
instancia a la vista.
Visualización de acciones en la vista
Para mostrar las existencias, tenemos que acceder al StockListViewModel
interior de nuestra vista. Podemos acceder al modelo de vista usando el ChangeNotifierProvider
.
Vamos a inyectar la instancia de StockListViewModel
en nuestro widget de página de inicio. Esto se implementa en el main.dart
archivo como se muestra a continuación:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:stocks_app_flutter/pages/home_page.dart'; import 'package:stocks_app_flutter/view_models/stock_list_view_model.dart'; void main() => runApp(App()); class App extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: "Stocks", home: ChangeNotifierProvider( create: (_) => StockListViewModel(), child: HomePage() ) ); } }
El código anterior asegura que la StockListViewModel
instancia esté disponible para HomePage
todos sus widgets secundarios.
Dentro del HomePage
widget, usamos Provider.of<StockListViewModel>
para obtener una instancia de StockListViewModel
y luego llamamos a la fetchStocks
función en el modelo de vista.
El fetchStocks
recuperará las existencias de la API web y completará la stocks
propiedad de StockListViewModel
.
Una vez que stocks
se establece la propiedad, llamamos al notifyListeners
método que actualiza la vista usando el Consumer
widget.
class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { StockListViewModel _vm; @override void initState() { super.initState(); _vm = Provider.of<StockListViewModel>(context, listen: false); _vm.fetchStocks(); }
El StockList
widget es responsable de mostrar una lista de acciones. El StockList
widget tiene un solo argumento, que es la lista de acciones.
La implementación del StockList
widget se muestra a continuación:
Si ejecuta la aplicación, podrá ver la aplicación Acciones en acción.
Buscando acciones
En la actualidad, escribir en el campo de texto no hace nada. Necesitamos filtrar las existencias en función de la entrada del usuario. La funcionalidad de búsqueda se implementa StockListViewModel
como se muestra a continuación:
class StockListViewModel extends ChangeNotifier { List<StockViewModel> stocks = List<StockViewModel>(); List<StockViewModel> allStocks = List<StockViewModel>(); Future<void> fetchStocks() async { ... } void search(String searchTerm) { if(searchTerm.isEmpty) { stocks = allStocks; } else { stocks = allStocks.where((stock) => stock.symbol.startsWith(searchTerm)).toList(); } notifyListeners(); } }
Dentro del método de búsqueda, usamos la función where para filtrar las acciones en función de la entrada del usuario.
¡Eso es!
Conclusión
Realmente espero que hayas disfrutado del artículo. En la segunda parte, cubriré cómo mostrar noticias desde una API web en vivo y agregar gestos de arrastre para deslizar / bajar la vista de noticias.
Recursos
- GitHub
- Construyendo acciones de Apple en videos de Flutter
- Cree la aplicación Apple Stocks usando Flutter Parte 2
[…] Cree la aplicación Apple Stocks usando Flutter Parte 1 […]