跨小部件的多个实例颤动共享状态
flutter share state across multiple instances of a widget
在我的 flutter 应用程序中,我有一个 ConnectivityStatus
小部件,它显示应用程序与我的 raspberry pi 的当前连接状态。在我的小部件的 initState
中,我订阅了一个计时器以每 5 秒检查一次连接并相应地更新状态,然后在处理时取消订阅。
问题是,当多个屏幕使用 ConnectivityStatus
小部件时,例如在堆栈导航器设置中,我现在有两个并发订阅,因为两个实例都没有处理。这会导致出现许多多余的、不需要的请求。
我真正想要的是在多个屏幕上共享小部件的单个实例,或者让多个实例可以访问一个全局状态。
我怎样才能做到这一点或针对我的问题推荐的其他解决方案是什么?
实现此目的的最简单方法是使用 InheritedWidget 将 ConnectivityStatus 传递给降序小部件。
https://api.flutter.dev/flutter/widgets/InheritedWidget-class.html
您还可以查看其他状态管理解决方案,例如 Provider
https://pub.dev/packages/provider
或集团
https://pub.dev/packages/flutter_bloc
我建议使用 Provider 并创建一个 RPIService
来发送连接状态流。
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),
);
});
}
}
实现此目的的另一种方法是使用 GlobalKey
,因为这是在应用程序中共享单个小部件状态的官方 Flutter 方法。
在 key.dart
文件中:
final GlobalKey<ConnectivityStatusState> connectivityStatusKey = GlobalKey();
当您创建 ConnectivityStatus
小部件时:
ConnectivityStatus(
key: connectivityStatusKey,
...
)
您想访问ConnectivityStatus
状态的位置:
connectivityStatusKey.currentState.anythingPublicInThisState()
要使用它,请确保您的状态 class 是 public(没有 _
)并且 ConnectivityStatus
小部件存在 并且是唯一的 在小部件树中。
希望这会有所帮助!
在我的 flutter 应用程序中,我有一个 ConnectivityStatus
小部件,它显示应用程序与我的 raspberry pi 的当前连接状态。在我的小部件的 initState
中,我订阅了一个计时器以每 5 秒检查一次连接并相应地更新状态,然后在处理时取消订阅。
问题是,当多个屏幕使用 ConnectivityStatus
小部件时,例如在堆栈导航器设置中,我现在有两个并发订阅,因为两个实例都没有处理。这会导致出现许多多余的、不需要的请求。
我真正想要的是在多个屏幕上共享小部件的单个实例,或者让多个实例可以访问一个全局状态。
我怎样才能做到这一点或针对我的问题推荐的其他解决方案是什么?
实现此目的的最简单方法是使用 InheritedWidget 将 ConnectivityStatus 传递给降序小部件。 https://api.flutter.dev/flutter/widgets/InheritedWidget-class.html
您还可以查看其他状态管理解决方案,例如 Provider https://pub.dev/packages/provider 或集团 https://pub.dev/packages/flutter_bloc
我建议使用 Provider 并创建一个 RPIService
来发送连接状态流。
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),
);
});
}
}
实现此目的的另一种方法是使用 GlobalKey
,因为这是在应用程序中共享单个小部件状态的官方 Flutter 方法。
在 key.dart
文件中:
final GlobalKey<ConnectivityStatusState> connectivityStatusKey = GlobalKey();
当您创建 ConnectivityStatus
小部件时:
ConnectivityStatus(
key: connectivityStatusKey,
...
)
您想访问ConnectivityStatus
状态的位置:
connectivityStatusKey.currentState.anythingPublicInThisState()
要使用它,请确保您的状态 class 是 public(没有 _
)并且 ConnectivityStatus
小部件存在 并且是唯一的 在小部件树中。
希望这会有所帮助!