In case of internet connectivity loss I want to show a widget which informs the user on connectivity issues. I want this widget to show when connectivity status changes, no matter which route is present right now.
The issue is that I can't find a way to overlay this "connectivity loss" widget on top of the main navigator (Used Modular for Navigation).
What's the best way to implement it?
CodePudding user response:
create one provider for connectivity and listen it on all the screens
import 'dart:async';
import 'package:connectivity/connectivity.dart';
enum NetworkStatus { Online, Offline }
class NetworkStatusService {
StreamController<NetworkStatus> networkStatusController =
StreamController<NetworkStatus>();
NetworkStatusService() {
Connectivity().onConnectivityChanged.listen((status){
networkStatusController.add(_getNetworkStatus(status));
});
}
NetworkStatus _getNetworkStatus(ConnectivityResult status) {
return status == ConnectivityResult.mobile || status == ConnectivityResult.wifi ? NetworkStatus.Online : NetworkStatus.Offline;
}
}
in the build method of all the screens.
NetworkStatus networkStatus = Provider.of<NetworkStatus>(context);
if (networkStatus == NetworkStatus.Online) {
return realscreen();
} else {
_showToastMessage("Offline");
return offlineimagewidget();
}
}
CodePudding user response:
I used a method like the one below in my own application. You can adapt it to your own project
void goToPage() async {
var prefs = await SharedPreferences.getInstance();
if (request) {
request = !request;
try {
HttpClient httpClient = HttpClient();
httpClient.connectionTimeout = const Duration(seconds: 5);
HttpClientRequest req =
await httpClient.getUrl(Uri.parse(url "/get-counts"));
HttpClientResponse resp =
await req.close().timeout(const Duration(seconds: 5));
String jsonStr = await utf8.decodeStream(resp);
dynamic jsonDyn = json.decode(jsonStr);
await prefs.setString(
"text", jsonDyn["data"]["text"]);
await prefs.setString("text",
jsonDyn["data"]["text"]);
await prefs.setString("text", jsonDyn["data"]["text"]);
await prefs.setString(
"text", jsonDyn["data"]["text"]);
if (prefs.getString("hash") != null) {
Navigator.of(context).pushReplacement(FadePageRoute(
builder: (context) => DashboardScreen(
analytics: widget.analytics, observer: widget.observer),
));
} else {
Navigator.of(context).pushReplacement(FadePageRoute(
builder: (context) => LoginScreen(
analytics: widget.analytics, observer: widget.observer)));
}
} catch (e) {
showDialog(
context: context,
builder: (BuildContext builderContext) {
return SizedBox(
width: MediaQuery.of(context).size.width * 0.8,
child: AlertDialog(
elevation: 0.0,
actions: [
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: const Color(0xFFFCCBD8),
),
onPressed: () {
request = !request;
goToPage();
Navigator.pop(context);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text("Try Again",
style: TextStyle(
color: Color(0xFF6953A0),
fontWeight: FontWeight.bold)),
],
))
],
backgroundColor: const Color(0xFF6953A0),
title: Icon(
Icons.signal_wifi_connected_no_internet_4_outlined,
size: MediaQuery.of(context).size.width * 0.3,
color: const Color(0xFFFCCBD8),
),
content: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Flexible(
child: Text("Check Your Internet Connection.",
style: TextStyle(color: Color(0xFFFCCBD8))),
)
]),
),
);
});
}
}
}
CodePudding user response:
You can use overlayment to do this.
This will show an overlay without carrying on which route you are.
You can show this as notification, or you can use Overlayment.showMessage(connectionMessage)
.
See the online demo