Flutter应用全局网络状态监听实现,避免代码重复方案咨询
全局检测网络状态,避免重复代码的几种方案
方案1:单例+ValueNotifier(轻量方案)
把网络监听逻辑抽离成全局单例,所有页面直接监听单例的状态即可,不用每个页面重复写监听代码:
import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/foundation.dart'; class NetworkManager { // 单例实例,保证全局唯一 static final NetworkManager _instance = NetworkManager._internal(); factory NetworkManager() => _instance; NetworkManager._internal(); // 用ValueNotifier存储网络状态,方便页面监听更新 final ValueNotifier<bool> isConnected = ValueNotifier<bool>(true); // 初始化网络监听 void init() { Connectivity().onConnectivityChanged.listen((state) { final connected = state != ConnectivityResult.none; // 状态变化时才更新,避免不必要的UI重绘 if (isConnected.value != connected) { isConnected.value = connected; } }); } }
在main.dart里初始化全局监听:
void main() async { WidgetsFlutterBinding.ensureInitialized(); // 启动全局网络监听 NetworkManager().init(); runApp(const MyApp()); }
任意页面中使用,无需重复写监听:
class MyPage extends StatelessWidget { @override Widget build(BuildContext context) { return ValueListenableBuilder<bool>( valueListenable: NetworkManager().isConnected, builder: (context, isConnected, child) { return Scaffold( body: Center( child: Text(isConnected ? '已联网' : '无网络'), ), ); }, ); } }
方案2:ChangeNotifier+Provider(适配复杂状态管理场景)
如果项目已经在用Provider状态管理,用这种方案更贴合现有架构:
- 创建网络状态的ChangeNotifier类:
import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/foundation.dart'; class NetworkProvider extends ChangeNotifier { bool _isConnected = true; bool get isConnected => _isConnected; NetworkProvider() { _initNetworkListener(); } void _initNetworkListener() { Connectivity().onConnectivityChanged.listen((state) { final connected = state != ConnectivityResult.none; if (_isConnected != connected) { _isConnected = connected; // 通知所有监听页面更新UI notifyListeners(); } }); } }
- 在
main.dart全局提供这个Provider:
void main() async { WidgetsFlutterBinding.ensureInitialized(); runApp( ChangeNotifierProvider( create: (context) => NetworkProvider(), child: const MyApp(), ), ); }
- 页面中直接获取状态:
class MyPage extends StatelessWidget { @override Widget build(BuildContext context) { final networkState = Provider.of<NetworkProvider>(context); return Scaffold( body: Center( child: Text(networkState.isConnected ? '已联网' : '无网络'), ), ); } }
方案3:基类Widget(适合全页面都是StatefulWidget的场景)
如果你的项目页面都是StatefulWidget,可以写一个基类封装网络逻辑,页面直接继承即可:
import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/material.dart'; abstract class BaseState<T extends StatefulWidget> extends State<T> { bool isConnected = true; late StreamSubscription<ConnectivityResult> _networkSubscription; @override void initState() { super.initState(); _initNetworkListener(); } void _initNetworkListener() { _networkSubscription = Connectivity().onConnectivityChanged.listen((state) { setState(() { isConnected = state != ConnectivityResult.none; }); // 子类可重写此方法,自定义网络变化后的逻辑 onNetworkChanged(isConnected); }); } // 子类重写实现自定义逻辑 void onNetworkChanged(bool isConnected) {} @override void dispose() { // 销毁时取消订阅,避免内存泄漏 _networkSubscription.cancel(); super.dispose(); } }
页面继承基类,只需要写自己的业务逻辑:
class MyPage extends StatefulWidget { const MyPage({super.key}); @override State<MyPage> createState() => _MyPageState(); } class _MyPageState extends BaseState<MyPage> { final TextEditingController countryController = TextEditingController(); @override void initState() { // 自己页面的初始化逻辑 countryController.text = "+961"; super.initState(); } @override void onNetworkChanged(bool isConnected) { // 自定义网络变化提示,比如弹窗 if (!isConnected) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('网络连接已断开')), ); } } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Text(isConnected ? '已联网' : '无网络'), ), ); } }
内容的提问来源于stack exchange,提问作者Ibtissam
相关产品推荐
相关产品推荐

