[英]flutter share received pusher data between screens using Riverpod
In our system we used Pusher
on both of our Admin Panel
and mobile
application, in flutter
i want to wrap whole application screens with Pusher
and Riverpod
and using providers with Hook
widget in screens, that means i want to implement Pusher
in main
or MyApp
and broadcast received data from Pusher
on all of screens which we have them, basically we had to use Pusher
in each screen which we need to receive data and its difficult to maintain application, for example:在我们的系统,我们使用Pusher
在我们两个的Admin Panel
和mobile
应用,在flutter
我想包装与整个应用程序的屏幕Pusher
和Riverpod
和使用供应商提供Hook
的屏幕小部件,这意味着我要实现Pusher
在main
或MyApp
和在我们拥有的所有屏幕上广播从Pusher
接收到的数据,基本上我们必须在每个需要接收数据的屏幕中使用Pusher
,并且应用程序难以维护,例如:
this sample code is not correct and i tried to implement that, but i can't此示例代码不正确,我试图实现它,但我不能
here as you can see Pusher
events and listeners work fine without any problem:在这里你可以看到Pusher
事件和监听器工作正常,没有任何问题:
D/PusherClientPlugin( 7447): Event stream cancelled.
D/PusherClientPlugin( 7447): Event stream listening...
D/PusherClientPlugin( 7447): Event stream cancelled.
D/PusherClientPlugin( 7447): Event stream listening...
D/PusherClientPlugin( 7447): [BIND] new-login
D/PusherClientPlugin( 7447): Event stream cancelled.
D/PusherClientPlugin( 7447): Event stream listening...
D/PusherClientPlugin( 7447): Event stream cancelled.
D/PusherClientPlugin( 7447): Event stream listening...
D/PusherClientPlugin( 7447): [BIND] new-login
D/PusherClientPlugin( 7447): [ON_EVENT] Channel: backers-list, EventName: new-login,
D/PusherClientPlugin( 7447): Data: Sending Test Data , User Id: null
I/flutter ( 7447): received
SpashScreen
class as initializing Pusher
SpashScreen
类作为初始化Pusher
class SplashScreen extends HookWidget{
@override
Widget build(BuildContext context) {
_routeNavigation();
final PusherClient pusher = PusherClient(
"xxxx",
PusherOptions(
cluster: 'us2',
));
final Channel channel;
pusher.connect();
channel = pusher.subscribe("backers-list");
channel.bind("new-login", (event) {
print('received');
context
.read(alarmNotificationStateProvider.notifier)
.increment('${event?.data.toString()}');
});
return Scaffold(
/* ... */
Profile
screen should be receive data from Pusher
which i implemented that into SplashScreen
Profile
屏幕应该从Pusher
接收数据,我将其实现到SplashScreen
class Profile extends HookWidget {
@override
Widget build(BuildContext context) {
final alarmNotification = useProvider(alarmNotificationStateProvider);
print('PUSH RECEIVED');
/* ... */
}
alarmNotificationStateProvider
: alarmNotificationStateProvider
:
final alarmNotificationStateProvider = StateNotifierProvider<AlarmNotification, AlarmNotificationData>(
(ref) => AlarmNotification(),
);
AlarmNotification
class: AlarmNotification
类:
class AlarmNotification extends StateNotifier<AlarmNotificationData> {
AlarmNotification() : super(_initialValue);
static const _initialValue = AlarmNotificationData('');
void increment(String data) {
state = AlarmNotificationData(data);
}
}
AlarmNotificationData
class: AlarmNotificationData
类:
class AlarmNotificationData {
final String data;
const AlarmNotificationData(this.data);
}
To listen changes in riverpod
you require useProvider(provider);
要收听riverpod
变化,您需要useProvider(provider);
The useProvider
method will listen for state changes in provider, which is the current instance of your model class useProvider
方法将监听 provider 中的状态变化,它是您模型类的当前实例
This also gives you a reference to the notifier state, which you're storing in model class这也为您提供了对存储在模型类中的通知程序状态的引用
use this:用这个:
final alarmNotificationNotifier = useProvider(alarmNotificationProvider);
instead of final alarmNotificationNotifier = context.read(alarmNotificationProvider);
而不是final alarmNotificationNotifier = context.read(alarmNotificationProvider);
the read
method gets you a reference to your state management class (CounterNotifier) without listening for changes in the state read
方法让你引用你的状态管理类(CounterNotifier),而不用监听状态的变化
I haven't seen your code of AlarmNotification
, so I use a simple version below.我没有看到你的AlarmNotification
代码,所以我在下面使用了一个简单的版本。
class AlarmNotification extends ChangeNotifier{
var _data;
String get data => _data;
void receivedData(String data){
_data = data;
notifyListeners();
}
}
I think you misunderstand a little about riverpod.我想你对riverpod有点误解。 The MyApp
seems only provide the event data but not consume it. MyApp
似乎只提供事件数据而不使用它。 So the part you can just use StatelessWidget.(It is also suggested to use "context.read(someProvider)" if you only read not watch)所以部分你可以只使用StatelessWidget。(如果你只看不看,也建议使用“context.read(someProvider)”)
final alarmNotificationProvider = ChangeNotifierProvider((ref)=>AlarmNotification());
class MyApp extends StatelessWidget{
const MyApp({Key? key}):super(key: key);
@override
Widget build(BuildContext context) {
...
channel.bind("new-login", (event) {
context
.read(alarmNotificationProvider)
.receivedData('${event?.data.toString()}');
});
...
}
}
And the other widgets that need the data just listen to the alarmNotificationProvider
(you may need to import the file to see it).而其他需要数据的小部件只听alarmNotificationProvider
(您可能需要导入文件才能看到它)。 It will rebuild the widget once it gets the notification.一旦收到通知,它将重建小部件。
class OtherWidget extends HookWidget {
const OtherWidget({Key? key}):super(key: key);
@override
Widget build(BuildContext context) {
final alarmNotification = useProvider(alarmNotificationProvider);
return Text(alarmNotification.data);
}
}
Try it this way,试试这个方法
/// Code /// 代码
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<SettingsProvider>(
create: (context) => SettingsProvider(),
),
],
child: MyApp(),
),
);
/// ///
class SettingsProvider extends ChangeNotifier {
Locale _currentLocale = Locale("en", "");
String _languageCode = "en";
Locale get getCurrentLocale => _currentLocale;
String get getLanguageCode => _languageCode;
void updateLocale(Locale locale) {
Log.loga(title, "updateLocale: >>>> $locale");
Log.loga(title, "updateLocale: toLanguageTag >>>> ${locale.toLanguageTag()}");
this._currentLocale = locale;
AppTranslations.load(locale);
this._languageCode = locale.toLanguageTag();
//notifyListeners();
Future.delayed(Duration(seconds: 0)).then((value) {
super.notifyListeners();
});
}
}
/// update data
Provider.of<SettingsProvider>(context, listen: false).updateLocale(locale);
/// get data
Provider.of<SettingsProvider>(context).getCurrentLocale
make sure both screeens are under the changenotifier in widget tree,确保两个屏幕都在小部件树中的 changenotifier 下,
other option is pass your provider to login screen as argument and use changenotifier.value() in login screen,另一个选项是将您的提供者作为参数传递给登录屏幕,并在登录屏幕中使用 changenotifier.value(),
We are also using pusher.我们也在使用推送器。 We are using flutter_pusher package and notifications work as expected.我们正在使用 flutter_pusher 包,通知按预期工作。 you can initialize it by eg你可以通过例如初始化它
Pusher.init('API_KEY', PusherOptions(encrypted:true));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.