The Importance of Network Awareness
Mobile users are constantly on the move, switching between Wi-Fi and cellular data or entering dead zones. A well-built Flutter app should never leave a user staring at a broken 'Load Failed' screen without context. Instead, it should react dynamically to connection changes. Building a 'network-aware' UI ensures that users understand why data isn't loading and provides a seamless transition when the signal returns.
Setting Up Connectivity Monitoring
To monitor network status in Flutter, the community standard is the connectivity_plus package. This library allows you to check the current status and, more importantly, listen to a stream of updates. First, add the dependency to your pubspec.yaml file.
dependencies: connectivity_plus: ^6.0.0
Creating a Global Connectivity Wrapper
Rather than checking the network status on every single page, a more robust architectural pattern is to create a global wrapper. This widget wraps your MaterialApp or specific screens and reacts to the network stream using a StreamBuilder.
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
class ConnectivityWrapper extends StatelessWidget {
final Widget child;
const ConnectivityWrapper({required this.child, super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<List<ConnectivityResult>>(
stream: Connectivity().onConnectivityChanged,
builder: (context, snapshot) {
final connectivityResults = snapshot.data ?? [ConnectivityResult.none];
if (connectivityResults.contains(ConnectivityResult.none)) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.wifi_off, size: 64, color: Colors.grey),
const SizedBox(height: 16),
const Text(
'No Internet Connection',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const Text('Please check your settings.'),
],
),
),
);
}
return child;
},
);
}
}
Refining the User Experience
While a full-screen block is useful for apps that require a constant connection (like a real-time trading app), most apps benefit from a more subtle approach. You can use a Stack to overlay a small 'Offline' banner at the bottom of the screen. This allows the user to still browse cached content while being aware that new data cannot be fetched.
Widget build(BuildContext context) {
return Stack(
children: [
child,
if (isOffline)
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
color: Colors.red,
padding: const EdgeInsets.symmetric(vertical: 8),
child: const Text(
'You are currently offline',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
),
),
),
],
);
}
Best Practices for Offline Resilience
Monitoring the connection is only half the battle. To truly master the offline experience, consider the following strategies:
- Local Caching: Use
sqfliteorHiveto store data locally. When the network is unavailable, serve the cached version immediately. - Debouncing Status Changes: Network signals can flicker. Use a small delay before updating the UI to prevent the 'Offline' banner from flashing during rapid handoffs between Wi-Fi and 5G.
- Retry Logic: When the connection is restored, trigger a refresh of your data providers automatically to ensure the UI is up to date without requiring a manual swipe-to-refresh.


