Dans mon application Flutter, j'ai un widget ConnectivityStatus
qui affiche l'état actuel de la connexion de l'application à mon raspberry pi. Dans le initState
de mon widget, je m'abonne à une minuterie pour vérifier la connexion toutes les 5 secondes et mets à jour l'état en conséquence, puis me désabonne lors de la suppression.
Le problème est que lorsque plusieurs écrans utilisent le widget ConnectivityStatus
, comme dans une configuration de navigateur de pile, j'ai maintenant deux abonnements simultanés car aucune instance ne l'a supprimé. Cela provoque de nombreuses requêtes redondantes et inutiles.
Ce que je veux vraiment, c'est soit partager une seule instance du widget sur plusieurs écrans, soit avoir un état global auquel plusieurs instances peuvent accéder.
Comment puis-je y parvenir ou quelles sont les autres solutions recommandées à mon problème?
3 Réponses :
Le moyen le plus simple d'y parvenir serait d'utiliser InheritedWidget pour transmettre le ConnectivityStatus aux widgets descendants. https://api.flutter.dev/flutter/widgets/InheritedWidget-class. html
Vous pouvez également rechercher d'autres solutions de gestion d'état telles que Provider https://pub.dev/packages/provider ou Bloc https://pub.dev/packages/flutter_bloc
Je suggère d'utiliser Provider et de créer un RPIService
qui envoie un flux d'état de connectivité.
class YourHome extends StatelessWidget { @override Widget build(BuildContext context) { return Consumer<Status>(builder: (context, status, _) { return Scaffold( body: Text(status.status), ); }); } }
main.dart
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MultiProvider( providers: [ Provider<UserService>( create: (context) => UserService(), lazy: false, ), StreamProvider<Status>( create: (context) => Provider.of<RPIService>(context, listen: false).RPIstatus, ), ], child: MaterialApp( title: 'Your app', theme: ThemeData( primarySwatch: Colors.blue, ), home: YourHome(), ), ); } }
yourHome.dart
class RPIService { var RPIstatus = ValueNotifier<Status>(Status('offline')); RPIService(){ rpi...listen((cstatus){ RPIstatus.add(Status(cstatus)); }); }} class Status { final String statusMessage; Status(this.statusMessage); }
Une autre façon d'y parvenir consiste à utiliser GlobalKey
, car c'est le moyen officiel Flutter de partager un seul état de widget dans l'application.
Dans un key.dart code > fichier:
connectivityStatusKey.currentState.anythingPublicInThisState()
Lorsque vous créez votre widget ConnectivityStatus
:
ConnectivityStatus( key: connectivityStatusKey, ... )
Où vous voulez pour accéder à l'état ConnectivityStatus
:
final GlobalKey<ConnectivityStatusState> connectivityStatusKey = GlobalKey();
Pour l'utiliser, assurez-vous que votre classe d'état est publique (sans _
) et le widget ConnectivityStatus
est présent et unique dans l'arborescence des widgets.
J'espère que cela vous aidera!