Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Asiel Alonso
Asiel Alonso

Posted on • Edited on

     

Flutter y el patrón Provider

Hola mundo!!

Introducción

Tanto si desarrolla una aplicación nativa como una híbrida, el manejo del estado es un problema que debemos enfrentar y tener bajo control. Para administrar el estado global de una aplicación enFlutter existen varias maneras, en este post abordaremosProvider, una biblioteca bastante popular que nos ayudará con este trabajo.

Aplicación de ejemplo

Para ver el funcionamiento deProvider, vamos a realizar una sencilla aplicación que nos ejemplifique.
Esta app muestra una pantalla con unAppBar y su título, en el centro unText, y dos botones flotantes en la esquina inferior derecha, que tendrán como función cambiar el valor del texto que será mostrado tanto en el título delAppBar como en elText del body de la app.
Tenemos en cuenta que el valor del texto será administrado de manera global.

Dejo el link del ejercicio para quien desee descargarlo:
https://github.com/hextiandro/flutter_provider_pattern

Manos a la obra

Primeramente instalaremos la biblioteca:provider: ^5.0.0 (En el momento que escribí el post esta era la versión).
La podemos encontrar en:https://pub.dev/packages/provider

Dentro de lib creamos una carpeta llamada widgets y dentro un archivo llamado floating_actions.dart,lib/widgets/floating_actions.dart para crear el widget con los dos botones flotantes:

import'package:flutter/material.dart';classFloatingActionextendsStatelessWidget{@overrideWidgetbuild(BuildContextcontext){(context);returnColumn(mainAxisAlignment:MainAxisAlignment.end,children:<Widget>[FloatingActionButton(child:Icon(Icons.wifi),backgroundColor:Colors.orange,onPressed:(){}),SizedBox(height:10.0,),FloatingActionButton(child:Icon(Icons.bluetooth),backgroundColor:Colors.blue,onPressed:(){})],);}}
Enter fullscreen modeExit fullscreen mode

Notemos que elonPressed lo tenemos sin acción, más adelante agregaremos su funcionalidad.

Ahora dentro delib/widgets crearemos otro archivo llamado body,lib/widgets/body.dart para crear elwidget con el texto centralizado.

import'package:flutter/material.dart';classBodyextendsStatelessWidget{@overrideWidgetbuild(BuildContextcontext){(context);returnCenter(child:Text("",style:TextStyle(fontSize:20),),);}}
Enter fullscreen modeExit fullscreen mode

El texto mostrado por ahora es la cadena vacía.
Crearemos otrowidget dentro de lib, llamado homelib/Home.dart:

import'package:flutter/material.dart';classHomeextendsStatelessWidget{@overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:Center(child:Text("")),),body:Body(),floatingActionButton:FloatingAction(),);}}
Enter fullscreen modeExit fullscreen mode

Aquí estamos renderizando unScaffold, con unAppBar y su título vacío por el momento, además renderizamos loswidgetsBody yFloatingAction creados anteriormente.
Nada deProvider aún, solo vamos armando la interfaz gráfica de la app, pasemos a modificar elmain.dart.

Nuestro archivomain.dart debería lucir así por el momento:

import'package:flutter/material.dart';import'package:provider_pattern/home.dart';voidmain()=>runApp(MyApp());classMyAppextendsStatelessWidget{@overrideWidgetbuild(BuildContextcontext){returnMaterialApp(title:'Provider',home:Home());}}
Enter fullscreen modeExit fullscreen mode

Con esto tenemos todo listo para comenzar a construir nuestroProvider; hagamos lo siguiente:

Dentro de lib creamos otro directorio llamdo provider y dentro un archivo llamado signal_mode.dart,lib/provider/signal_mode.dart

import'package:flutter/material.dart';classSignalModeextendsChangeNotifier{String_signalMode='Wifi mode';StringgetsignalMode=>_signalMode;setsignalMode(Stringmode){this._signalMode=mode;notifyListeners();}}
Enter fullscreen modeExit fullscreen mode

Listo, este es nuestroProvider, es la clase que se ocupa de centralizar el valor de la variable privada_signalMode de tipoString que es el texto que se mostrará tanto en el título delAppBar como en el centro de la pantalla.

Notemos el primer detalle que extiende deChangeNotifier clase encargada de exponer los eventos de notificación,
veamos que tenemos un métodoget para obtener el valor de_signalMode, y un métodoset para modificarlo, dentro de este método vemos la llamada anotifyListeners() que es quien va a notificar a todos loswidgets que escuchen a este provider del cambio, para asi actualizar su estado.

Es momento de encapsular aquelloswidgets que van a escuhar los cambios.
Como queremos tener el control del estado en todos los niveles de la aplicación lo haremos en elmain.
Tenga en cuenta que no necesariamente se debe envolver en el nivel más alto de la aplicación en caso que desees compartir determinado estado para determinado nivel.
Si modificamos nuestromain quedaría de la siguiente forma:

import'package:flutter/material.dart';import'package:provider/provider.dart';import'package:provider_pattern/home.dart';import'package:provider_pattern/provider/signal_mode.dart';voidmain()=>runApp(MyApp());classMyAppextendsStatelessWidget{@overrideWidgetbuild(BuildContextcontext){returnChangeNotifierProvider(create:(_)=>SignalMode(),child:MaterialApp(title:'Provider',home:Home()),);}}
Enter fullscreen modeExit fullscreen mode

De esta manera toda la app está en condiciones de escuchar los cambios de la claseSignalMode

Desde ahora ya podemos integrar los distintoswidgets de nuestra app. Modifiquemos la claseFloatingAction para conectarla con nuestroProvider quedando de la siguiente forma:

import'package:flutter/material.dart';import'package:provider/provider.dart';import'package:provider_pattern/provider/signal_mode.dart';classFloatingActionextendsStatelessWidget{@overrideWidgetbuild(BuildContextcontext){finalsignal=Provider.of<SignalMode>(context);returnColumn(mainAxisAlignment:MainAxisAlignment.end,children:<Widget>[FloatingActionButton(child:Icon(Icons.wifi),backgroundColor:Colors.orange,onPressed:(){signal.signalMode="Wifi mode";}),SizedBox(height:10.0,),FloatingActionButton(child:Icon(Icons.bluetooth),backgroundColor:Colors.blue,onPressed:(){signal.signalMode="Bluetooth mode";})],);}}
Enter fullscreen modeExit fullscreen mode

Notemos aquí en la siguiente línea:

finalsignal=Provider.of<SignalMode>(context);
Enter fullscreen modeExit fullscreen mode

de esta manera obtenemos una instancia de nuestroProvider especificando que es de tipoSignalMode.

El otro punto a notar aquí es en elonPressed de los botones, cada uno hace una llamada modificando el valor designalMode

onPressed:(){signal.signalMode="Wifi mode";})
Enter fullscreen modeExit fullscreen mode
onPressed:(){signal.signalMode="Bluetooth mode";})
Enter fullscreen modeExit fullscreen mode

De esta manera podemos modifcar el estado global, ahora solamente debemos mostrar los valores, veamos como:

import'package:flutter/material.dart';import'package:provider_pattern/provider/signal_mode.dart';import'package:provider_pattern/widgets/body.dart';import'package:provider_pattern/widgets/floating_actions.dart';import'package:provider/provider.dart';classHomeextendsStatelessWidget{@overrideWidgetbuild(BuildContextcontext){finalsignal=Provider.of<SignalMode>(context);returnScaffold(appBar:AppBar(title:Center(child:Text(signal.signalMode)),),body:Body(),floatingActionButton:FloatingAction(),);}}
Enter fullscreen modeExit fullscreen mode

En la claseHome igualmente obtenemos la instancia delProvider y leemos la propiedadsignalHome.

De la misma forma lo hacemos en la claseBody:

import'package:flutter/material.dart';import'package:provider/provider.dart';import'package:provider_pattern/provider/signal_mode.dart';classBodyextendsStatelessWidget{@overrideWidgetbuild(BuildContextcontext){finalsignal=Provider.of<SignalMode>(context);returnCenter(child:Text(signal.signalMode,style:TextStyle(fontSize:20),),);}}
Enter fullscreen modeExit fullscreen mode

Ya, es todo!!

Hemos finalizado nuestro ejemplo, pero les dejaré una última consideración para la utilización de múltiples providers tendríamos que modificar nuevamente nuestromain de la siguiente forma:

voidmain()=>runApp(AppState());classAppStateextendsStatelessWidget{@overrideWidgetbuild(BuildContextcontext){returnMultiProvider(providers:[ChangeNotifierProvider(create:(_)=>SignalMode())],child:MyApp(),);}}classMyAppextendsStatelessWidget{@overrideWidgetbuild(BuildContextcontext){returnMaterialApp(title:'Provider',home:Home());}}
Enter fullscreen modeExit fullscreen mode

Percatarse aquí comoMultiPorvider admite un arreglo deProvider:

providers:[ChangeNotifierProvider(create:(_)=>SignalMode())],
Enter fullscreen modeExit fullscreen mode

Conclusiones

Hasta aquí este post, espero haberme explicado bien y de alguna manera haberle sido útil, nos vemos en la próxima!!

Chao Mundo!!

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Web and mobile devloper, Reactjs, React Native, learning Flutter. Life lover 🐕 🐈.
  • Location
    Cuba
  • Work
    Computer Science
  • Joined

Trending onDEV CommunityHot

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp