Handling Internet Connectivity in Flutter with a Custom Provider and UI
TB
Teqani Blogs
Writer at Teqani
In modern mobile apps, monitoring internet connectivity is essential to ensure a smooth user experience. This article guides you through building an internet connectivity listener using Provider, Connectivity, and a custom UI for disconnected states.
🛠 Dependencies
To begin, you’ll need the following dependencies in your pubspec.yaml:
- connectivity: ^3.0.6
- provider: ^6.0.0
🔌 ConnectivityProvider: Monitor Connection Status
This class listens to real-time network changes and notifies widgets about the current connectivity state.
class ConnectivityProvider with ChangeNotifier {
Connectivity _connectivity = Connectivity();
late bool _isOnline = false;
bool get isOnline => _isOnline;
startMonitoring() async {
await initConnectivity();
_connectivity.onConnectivityChanged.listen((result) async {
if (result == ConnectivityResult.none) {
_isOnline = false;
} else {
_isOnline = await _updateConnectionStatus();
}
notifyListeners();
});
}
Future<void> initConnectivity() async {
try {
var status = await _connectivity.checkConnectivity();
_isOnline = status != ConnectivityResult.none;
notifyListeners();
} on PlatformException catch (e) {
print("PlatformException: $e");
}
}
Future<bool> _updateConnectionStatus() async {
try {
final result = await InternetAddress.lookup('google.com');
return result.isNotEmpty && result[0].rawAddress.isNotEmpty;
} on SocketException {
return false;
}
}
}
✅ This ensures actual internet access is verified, not just network presence (e.g., connected to a WiFi router without internet).
📵 NoInternet: A User-Friendly Offline Screen
This widget provides visual feedback when the app is offline.
class NoInternet extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white70,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset("assets/images/transport.png", height: 200, width: 200),
SizedBox(height: 25),
Text("No internet Connection", style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
Padding(
padding: EdgeInsets.all(15),
child: Text("You are not connected to the Internet. Make sure Wi-Fi is on", textAlign: TextAlign.center),
),
],
),
);
}
}
📶 InternetErrorScreen: Listener UI Layer
This StatefulWidget listens to ConnectivityProvider and invokes a callback when connectivity changes.
class InternetErrorScreen extends StatefulWidget {
final Function(bool) onInternetChanged;
const InternetErrorScreen({required this.onInternetChanged});
@override
_InternetErrorScreenState createState() => _InternetErrorScreenState();
}
class _InternetErrorScreenState extends State<InternetErrorScreen> {
@override
Widget build(BuildContext context) {
return Consumer<ConnectivityProvider>(
builder: (context, model, child) {
widget.onInternetChanged(model.isOnline);
return model.isOnline ? SizedBox.shrink() : NoInternet();
},
);
}
}
💡 How to Use
In your root or main screen:
InternetErrorScreen(
onInternetChanged: (isConnected) {
if (!isConnected) {
// Pause data fetches, show offline banner, etc.
}
},
),
Also, don’t forget to start monitoring when your app starts:
void main() {
runApp(
ChangeNotifierProvider(
create: (_) => ConnectivityProvider()..startMonitoring(),
child: MyApp(),
),
);
}
✅ Benefits of This Approach
- Real-time internet connection updates.
- Actual internet availability check (not just network presence).
- Seamless integration with Provider.
- Easy to customize the offline UI.
- Cleaner separation of business logic (provider) and UI.
Teqani Certified
All blogs are certified by our company and reviewed by our specialists
Issue Number: #a54e7953-8575-4c91-bf9f-e42ad8b86f69