This code does not work sending information between two different classes when using EventBus function.
import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import 'package:event_bus/event_bus.dart';
import 'dart:async';
//EventBus usage
final EventBus eventBus = EventBus();
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
static final GlobalKey<NavigatorState> navigatorKey =
GlobalKey<NavigatorState>();
static var isLoggedIn = false;
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: navigatorKey,
onGenerateRoute: _generateRoute,
home: const HomeScreen(),
);
}
Route<dynamic>? _generateRoute(RouteSettings settings) {
switch (settings.name) {
case '/':
return MaterialPageRoute( settings: settings, builder: (context) => const HomeScreen()); //settings的作用是debug, 追溯目前navigator stack中访问过的页面
case '/transactions':
return MaterialPageRoute(
settings: settings, builder: (context) => TransactionScreen());
case '/cart':
return MaterialPageRoute(
settings: settings, builder: (context) => CartScreen());
default:
return null;
}
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.of(context).pushNamed('/transactions');
},
child: const Text('View transactions'),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).pushNamed('/cart');
},
child: const Text('View Cart'),
),
],
),
),
);
}
}
class TransactionScreen extends StatelessWidget {
String message = 'Justin YC';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Transactions'),
),
body: Center(
child: Column(
children: [
ElevatedButton(
onPressed: () {
Navigator.of(context).pushNamed('/cart');
},
child: const Text('View Cart'),
),
ElevatedButton(
onPressed: () {
print("event has been sent: $message");
eventBus.fire(CustomEvent(message));
},
child: Text('Tap to send new Info: $message'),
),
],
),
),
);
}
}
class CustomEvent {
String msg;
CustomEvent(this.msg);
}
class CartScreen extends StatefulWidget {
const CartScreen({Key? key}) : super(key: key);
@override
State<CartScreen> createState() => _CartScreenState();
}
class _CartScreenState extends State<CartScreen> {
late StreamSubscription subscription;
String msg = " 通知:";
@override
void initState() {
subscription = eventBus.on<CustomEvent>().listen((event) {
print('received $event.msg');
setState(() {msg = event.msg;});
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Cart'),
),
body: Center(
child: Text(msg),
),
);
}
@override
void dispose() {
super.dispose();
}
}
I have tried several different ways, including keep both widgets alive when starting the app.
What I found is that if I keep both them alive, the listener can received the message from the sender. However, it will cause another issue, which is that the widget is no longer on the widget tree. So the receiver can not further process the data.