You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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状态管理,用这种方案更贴合现有架构:

  1. 创建网络状态的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();
      }
    });
  }
}
  1. 在main.dart全局提供这个Provider:
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(
    ChangeNotifierProvider(
      create: (context) => NetworkProvider(),
      child: const MyApp(),
    ),
  );
}
  1. 页面中直接获取状态:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 17:25:14