flutter share state across multiple instances of a widget

南笙酒味 提交于 2021-01-28 09:33:26

问题


In my flutter app, I have a ConnectivityStatus widget which displays the current connection status of the app to my raspberry pi. In the initState of my widget, I subscribe to a timer to check the connection every 5 seconds and update the state accordingly, then unsubscribe upon disposal.

The issue is, when multiple screens use the ConnectivityStatus widget, such as in a stack navigator setup, I now have two concurrent subscriptions as neither instance has disposed. This causes many redundant, unneeded requests to occur.

What I really want is to either share a single instance of the widget across multiple screens, or have one global state multiple instances can access.

How can I achieve this or what are other recommended solutions to my problem?


回答1:


The most simple way of achieving this would be to use InheritedWidget to pass the ConnectivityStatus to the descending widgets. https://api.flutter.dev/flutter/widgets/InheritedWidget-class.html

You could also look into other state management solutions such as Provider https://pub.dev/packages/provider or Bloc https://pub.dev/packages/flutter_bloc




回答2:


I suggest using Provider and creating a RPIService that sends a stream of connectivity status.

class RPIService {
  var RPIstatus = ValueNotifier<Status>(Status('offline'));

RPIService(){

rpi...listen((cstatus){
RPIstatus.add(Status(cstatus));

});

}}

class Status {
final String statusMessage;
 Status(this.statusMessage);
} 

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 YourHome extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<Status>(builder: (context, status, _) {
      return Scaffold(
        body: Text(status.status),
      );
    });
  }
}



回答3:


Another way to achieve this is to use GlobalKey, since is the official Flutter way to share a single widget state across the app.

In a key.dart file:

final GlobalKey<ConnectivityStatusState> connectivityStatusKey = GlobalKey();

When you create your ConnectivityStatus widget:

ConnectivityStatus(
  key: connectivityStatusKey,
  ...
)

Where you want to access the ConnectivityStatus state:

connectivityStatusKey.currentState.anythingPublicInThisState()

To use this, make sure your state class is public (without a _) and the ConnectivityStatus widget is present and unique in the widget tree.

Hope this will help!



来源:https://stackoverflow.com/questions/61688479/flutter-share-state-across-multiple-instances-of-a-widget

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!