Home > Back-end >  How to overlay a popup on top of MaterialApp navigator in a flutter App?
How to overlay a popup on top of MaterialApp navigator in a flutter App?

Time:10-12

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

  • Related