iT邦幫忙

2021 iThome 鐵人賽

DAY 12
0
Mobile Development

Flutter - 複製貼上到開發套件之旅系列 第 12

【第十二天 - Flutter NetWork 網路判斷】

前言

今日的程式碼 => GIHUB

說明

這是一個網路判斷的一個範例,將會使用 data_connection_checker 套件,注意, GITHUB 裡面有一個檔案叫做 data_connection_checker,他就是現在 plugin 裡面的程式碼,因為現在這個套件還沒有支援Null-Safety,所以我是直接 clone 下來然後改程式碼。

網路判斷更多的人是使用
https://pub.dev/packages/connectivity
https://pub.dev/packages/connectivity_plus
這兩個的 Readme.md 都有非常完整的解說。
和現在的這個 [data_connection_checker 套件(https://pub.dev/packages/data_connection_checker) 一樣,都可以監聽即時的網路,如果想要修改的話,可以直接在底下 _subscription 修改程式碼。

註解:
這邊我不示範 connectivity 的原因是因為我使用他會有 bug。

  1. 我的 pub-cache 怪怪的。應該說,我沒有去更新 flutter 的版本,但我看 github,好像只有我會遇到這個 bug,應該是 flutter 沒更新,或者是 pub-cache 怪怪的。(但是因為這個對我影響不是很大,所以我不急著更新)。
  2. 這個 connectivity 套件需要初始化。而現在的 data_connection_checker 不需要初始化,只是這個 data_connection_checker 套件的作者好像比較不常更新,不過沒關係,我可以自己更新套件:)),反正很快 ? 。
  3. 不過使用 connectivity 可以增測到你連上的網路是 mobile 還是 wifi 的資訊,如果需要客製化,就必須使用這個套件。

設定 YAML 檔案

  flutter_bloc: ^7.2.0
  data_connection_checker: ^0.3.4
  cupertino_icons: ^1.0.3

Bloc

Event

abstract class NetworkEvent {}

class ListenConnection extends NetworkEvent {}

class ConnectionChanged extends NetworkEvent {
  NetworkState connection;
  ConnectionChanged(this.connection);
}

Bloc

裡面因為有用到 StreamSubscription,可以即時監聽資料。因此,要記得 close 掉 StreamSubscription
這個 StreamSubscription 可以等於 data_connection_checker 裡面提供的 DataConnectionChecker().onStatusChange 來監聽網路的 status(狀態) 是什麼。

class NetworkBloc extends Bloc<NetworkEvent, NetworkState> {
  NetworkBloc() : super(ConnectionInitial());

  late StreamSubscription _subscription;

  @override
  Stream<NetworkState> mapEventToState(NetworkEvent event) async* {
    if (event is ListenConnection) {
      _subscription = DataConnectionChecker().onStatusChange.listen((status) {
        add(ConnectionChanged(status == DataConnectionStatus.disconnected
            ? ConnectionFailure()
            : ConnectionSuccess()));
      });
    }
    if (event is ConnectionChanged) yield event.connection;
  }

  @override
  Future<void> close() {
    _subscription.cancel();
    return super.close();
  }
}

State

@immutable
abstract class NetworkState {}

class ConnectionInitial extends NetworkState {}

class ConnectionSuccess extends NetworkState {}

class ConnectionFailure extends NetworkState {}

View(畫面、UI)

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        backgroundColor: Colors.cyan[300],
        body: BlocProvider(
          create: (context) =>NetworkBloc()..add(ListenConnection()),
          child: HomeScreen(),
        ),
      ),
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: BlocBuilder<NetworkBloc, NetworkState>(
        builder: (context, state) {
          if (state is ConnectionFailure) return Text("Failed to connect to Internet",);
          if (state is ConnectionSuccess)
            return Text(" Connected to Internet Successfully");
          else
            return SizedBox();
        },
      ),
    );
  }
}

上一篇
【第十一天 - Flutter GetX 架構教學】
下一篇
【第十三天 - Flutter Sqflite+Provider】
系列文
Flutter - 複製貼上到開發套件之旅30

尚未有邦友留言

立即登入留言