I am using Bloc
to check internet connection. If there is no connection, I show the SnackBar
. But I also need to be able to reuse the connection method to re-check the connection by clicking on the button, but I don’t understand how to call this method. Tell me how to call the connection method when the button is clicked?
bloc
class ConnectedBloc extends Bloc<ConnectedEvent, ConnectedState> {
StreamSubscription? subscription;
ConnectedBloc() : super(ConnectedInitial()) {
on<OnConnectedEvent>((event, emit) => emit(ConnectedSucess()));
on<OnNotConnectedEvent>((event, emit) => emit(ConnectedFailure()));
void connection() => Connectivity()
.onConnectivityChanged
.listen((ConnectivityResult result) {
if (result == ConnectivityResult.wifi ||
result == ConnectivityResult.mobile) {
add(OnConnectedEvent());
} else {
add(OnNotConnectedEvent());
}
});
home
home: BlocConsumer<ConnectedBloc, ConnectedState>(
listener: ((context, state) {
if (state is ConnectedSucess) {
const SizedBox();
} else if (state is ConnectedFailure) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
duration: const Duration(seconds: 3),
backgroundColor: Colors.transparent,
elevation: 0,
content: SystemMessagesSnackBar(
message: 'No internet access. Check your connection',
textButton: 'Refresh',
onPressed: () =>
ScaffoldMessenger.of(context).hideCurrentSnackBar(),
icon: SvgPicture.asset(constants.Assets.no_connection),
),
),
);
}
}),
CodePudding user response:
- wrap the code with a streambuilder and then associate the bloc streams with the streambuilder
- in your button click event interact with the bloc class
- check the streambuilder state and process the returning data.
yaml
dependencies:
flutter:
sdk: flutter
equatable: ^2.0.3
rxdart: ^0.27.4
import 'package:flutter/material.dart';
import 'package:equatable/equatable.dart';
import 'package:rxdart/rxdart.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Button Stream',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Test_StreambuilderButton(),
);
}
}
class Test_StreambuilderButton extends StatefulWidget {
Test_StreambuilderButton({Key? key}) : super(key: key);
BlocCode bloc= new BlocCode();
@override
State<Test_StreambuilderButton> createState() => _Test_StreambuilderButtonState();
}
class _Test_StreambuilderButtonState extends State<Test_StreambuilderButton> {
@override
Widget build(BuildContext context) {
return
Scaffold(appBar: AppBar(title:Text("Button Stream Event")),
body:
Column(children: [
StreamBuilder<BlocState>(
stream: widget.bloc.blocStream,
builder:(context,snapshot)
{
if (snapshot.hasData)
{
String data=snapshot.data!._message;
if (data == null)
{
return (Container(child:Text("No data")));
}
return (Container(child:Text(data)));
}
else
{
return (Container(child:Text("No activity")));
}
}
),
ElevatedButton(onPressed:(){
widget.bloc.setMessage(BlocState("Hello World"));
}, child: Text("Press Me"))
]));
}
}
class BlocState extends Equatable
{
BlocState(this._message);
final String _message;
@override
List<Object> get props=>[_message];
String get getMessage {return _message;}
}
class BlocCode
{
BlocCode();
Stream<BlocState> get blocStream => _loadController.stream;
final _loadController=BehaviorSubject<BlocState>();
void dispose()
{
_loadController.close();
}
setMessage(BlocState state)
{
_loadController.sink.add(state);
}
}
CodePudding user response:
To call a method inside your bloc, you need to get a reference to your bloc first by using context.read<T>()
. In your case:
context.read<ConnectedBloc>()
You can then call the method as follows:
onPressed:(){
ScaffoldMessenger.of(context).hideCurrentSnackBar();
context.read<ConnectedBloc>().connection();
}
But this will create an additional stream. Maybe you should use checkConnectivity if you click on the button.