问题
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