Flutter BLoC 教程:使用 BLoC 模式進(jìn)行狀態(tài)管理

言鼎科技 2023-05-08 690

什么是區(qū)塊鏈?

BLoC代表業(yè)務(wù)邏輯組件;它旨在將應(yīng)用程序的業(yè)務(wù)邏輯與用戶界面分開,使應(yīng)用程序代碼更加明確、可擴(kuò)展和可測試。

  • 開發(fā)者:費(fèi)利克斯·安格洛夫

  • 贊助商:Very Good Ventures、Stream、Miquido

  • 版本:flutter_bloc: ^8.0.1(寫文章時(shí))

Flutter BLoC 教程:使用 BLoC 模式進(jìn)行狀態(tài)管理

BLoC 設(shè)計(jì)模式的優(yōu)缺點(diǎn)

在繼續(xù)學(xué)習(xí)flutter bloc 教程之前,讓我們檢查一下 bloc 設(shè)計(jì)模式的一些優(yōu)缺點(diǎn)。

使用 BLoC 的優(yōu)點(diǎn)

  • 關(guān)于不同場景的優(yōu)秀文檔。

  • 將業(yè)務(wù)邏輯與 UI 分離,從而使代碼易于理解。

  • 使產(chǎn)品更具可測試性。

  • 易于跟蹤應(yīng)用程序經(jīng)歷的狀態(tài)。

使用 BLoC 的缺點(diǎn)

  • 學(xué)習(xí)曲線有點(diǎn)陡峭。

  • 不推薦用于簡單應(yīng)用

  • 更多樣板代碼,但可以通過擴(kuò)展來處理。

Flutter BLoC 教程目標(biāo)

我們將構(gòu)建一個(gè)相對簡單的應(yīng)用程序來演示 BLoC 如何使用流來管理狀態(tài)并為 bloc 編寫一些測試。

我們將構(gòu)建一個(gè)文本更改應(yīng)用程序;按文本將更改并顯示每個(gè)按鈕。您可以參考下面的 GIF。

Flutter BLoC 教程:使用 BLoC 模式進(jìn)行狀態(tài)管理

初始設(shè)置

1.確保安裝集團(tuán)在你的編輯器中擴(kuò)展;它將幫助創(chuàng)建項(xiàng)目所需的所有樣板代碼和文件(右鍵單擊 lib 文件夾,它將為您提供為項(xiàng)目生成 bloc 的選項(xiàng))。

2. 確保將你的 pubspec.yaml 文件與我的相匹配,以避免出現(xiàn)任何問題。

Flutter BLoC 教程:使用 BLoC 模式進(jìn)行狀態(tài)管理

想要輕松無憂地開發(fā) Flutter 應(yīng)用程序嗎?
Bacancy 在這里等你!聯(lián)系我們聘請 Flutter 開發(fā)人員,以出色的問題解決能力高效地滿足您的項(xiàng)目要求。

了解 BLoC 概念:事件和狀態(tài)

讓游戲開始吧。

要了解 bloc 的工作原理,我們需要知道什么是事件和狀態(tài)。

  • 事件:事件是應(yīng)用程序的輸入(例如 button_press 以加載圖像、文本輸入或我們的應(yīng)用程序可能希望接收的任何其他用戶輸入)。

  • 狀態(tài):狀態(tài)只是應(yīng)用程序的狀態(tài),可以根據(jù)接收到的事件進(jìn)行更改。

Bloc 管理這些事件和狀態(tài),即它接收事件流并將它們轉(zhuǎn)換為狀態(tài)流作為輸出。

Flutter BLoC 教程:使用 BLoC 模式進(jìn)行狀態(tài)管理

創(chuàng)建事件

Flutter BLoC 教程:使用 BLoC 模式進(jìn)行狀態(tài)管理
@immutable抽象類 AppBlocEvent {
常量 AppBlocEvent();}
@immutable類 ChangeTextEvent 擴(kuò)展 AppBlocEvent {
常量 ChangeTextEvent();}

在flutter bloc 教程中繼續(xù)前進(jìn)。在這里,我們創(chuàng)建了一個(gè)ChangeTextEvent,它會在單擊按鈕時(shí)觸發(fā)。

我們有一個(gè)抽象的AppBlocEvent類,因?yàn)?Bloc 期望將單個(gè)事件添加到流中。盡管如此,由于一個(gè)應(yīng)用程序中可以有多個(gè)事件,我們創(chuàng)建了一個(gè)抽象類并在我們想要?jiǎng)?chuàng)建任何新事件來處理多個(gè)事件并將其傳遞給 bloc 時(shí)擴(kuò)展它。

創(chuàng)建狀態(tài)

Flutter BLoC 教程:使用 BLoC 模式進(jìn)行狀態(tài)管理
@immutableAppState 類擴(kuò)展 Equatable {
最終整數(shù)索引;
最終字符串文本;

常量 AppState.empty()
    : 指數(shù) = 0,
      text = '初始文本';

常量 AppState({
  需要this.index,
  需要this.text,
});

@覆蓋
List<Object> get props => [index, text];}

同樣,我們可以在此應(yīng)用程序中創(chuàng)建不同的狀態(tài)。我們沒有很多州。因此,我們創(chuàng)建了一個(gè)單一的狀態(tài)來管理應(yīng)用程序;然而,我們可以通過創(chuàng)建一個(gè)抽象的 appstate 并將其擴(kuò)展到我們的自定義狀態(tài)來創(chuàng)建類似于事件的多個(gè)狀態(tài)。

  • AppState.empty只是應(yīng)用程序最初加載的初始狀態(tài)。

  • Equatable (get props)這里是用來和狀態(tài)進(jìn)行比較的。如果它們相等,它將用于測試區(qū)塊。

使用 BLoC 模式的事件和狀態(tài)管理

Flutter BLoC 教程:使用 BLoC 模式進(jìn)行狀態(tài)管理
AppBlocBloc 類擴(kuò)展了 Bloc{
最終名單文本列表 = [
  '初始文本',
  '更改文本',
  '再次改變',
];
AppBlocBloc() : super(const AppState.empty()) {
  在((事件,發(fā)出){
    嘗試 {
      int newIndex = state.index + 1;
      如果(新索引 >= textList.length){
        新指數(shù) = 0;
      }
      發(fā)射(
        應(yīng)用程序狀態(tài)(
          指數(shù):新指數(shù),
          文本:textList[newIndex],
        ),
      );
    } on Exception catch (e) {
      // 忽略:avoid_print
      打?。╡);
    }
  });
}}

說明
這是包含我們應(yīng)用程序業(yè)務(wù)邏輯的部分。

  • 當(dāng)通過單擊按鈕將 ChangeTextEvent 添加到流時(shí)執(zhí)行,它接收事件,即您想要與觸發(fā)事件一起傳遞的任何信息,您可以使用它訪問它(如 event.any_info - 你必須更改你的事件相應(yīng)地分類),emit 用于為該特定事件發(fā)出狀態(tài)。
  • state.index 允許您訪問應(yīng)用程序的當(dāng)前狀態(tài)。

  • emit(AppState(…)): emit(…) 用于輸出新狀態(tài)并導(dǎo)致 build() 函數(shù)的重建。

把碎片放在一起。
到目前為止,事件、狀態(tài)、集團(tuán)和我們的應(yīng)用程序的 UI 沒有以任何方式連接。讓我們開始將它們拼湊起來。

提供我們的 BLoC

Flutter BLoC 教程:使用 BLoC 模式進(jìn)行狀態(tài)管理
導(dǎo)入“包:flutter/material.dart”;導(dǎo)入“包:flutter_bloc/flutter_bloc.dart”;導(dǎo)入“包:text_change/text_controller.dart”;導(dǎo)入“bloc/app_bloc_bloc.dart”;導(dǎo)入“bloc/app_bloc_state.dart”;類 App 擴(kuò)展 StatelessWidget {
 const App({Key?key}) : super(key: key);
 @覆蓋
 小部件構(gòu)建(BuildContext 上下文){
   返回 MaterialApp(
     標(biāo)題:'顫振演示',
     主題:主題數(shù)據(jù)(
       primarySwatch: Colors.blue,
     ),
     家:BlocProvider(
       創(chuàng)建:(上下文)=> AppBlocBloc(),
       孩子:腳手架(
         應(yīng)用欄:應(yīng)用欄(
           title: const Text('文本變化'),
         ),
         正文:BlocConsumer(
           偵聽器:(上下文,狀態(tài)){},
           建設(shè)者:(上下文,狀態(tài)){
             返回文本控制器(
               文本:state.text,
             );
           },
         ),
       ),
     ),
   );
 }}

說明:App.dart
BlocProvider(...):我們使用它來提供我們的 bloc 實(shí)例,方法是將它放置在應(yīng)用程序的根目錄下方,以便在整個(gè)應(yīng)用程序中都可以訪問它。

  • 創(chuàng)建:它創(chuàng)建我們的 AppBloBloc 的實(shí)例。

BlocConsumer(...):這是一切發(fā)生的地方。

  • 它有一個(gè)名為 listener 的屬性,它監(jiān)聽狀態(tài)變化,并且可以隨著狀態(tài)變化以特定方式對特定狀態(tài)做出反應(yīng)。

  • builder:它負(fù)責(zé)構(gòu)建 UI 并在每次狀態(tài)更改時(shí)重新構(gòu)建。blocConsumer 還包含 listenWhen 和 buildWhen,正如名稱所述,可以對其進(jìn)行定制以對指定狀態(tài)做出反應(yīng)。

觸發(fā)事件和狀態(tài)

Flutter BLoC 教程:使用 BLoC 模式進(jìn)行狀態(tài)管理
類 TextChangeController 擴(kuò)展 StatelessWidget {最終字符串文本;const TextChangeController({Key? key, required this.text}) : super(key: key);@覆蓋小部件構(gòu)建(BuildContext 上下文){
     返回列
        孩子們:[
           文本變化(
              文字:文字,
           ), // 文本變化
          高架按鈕(
              onPressed: () =>
                   上下文.read().add(const ChangeTextEvent()),
             child: const Text('更改文本'),
        ), // 高架按鈕
     ), //[ ]
  ); // 柱子
 ))

在這里,我們將ChangetTextEvent添加到事件流中,從而觸發(fā)狀態(tài)更改,從而導(dǎo)致 BlocConsumer 中的 builder() 重建,并將更改的文本顯示在屏幕上。

你有它?。∈褂梅蛛x的 UI 和業(yè)務(wù)邏輯,您可以更改 UI 代碼,只需插入 Bloc。它的工作原理是一樣的。

您愿意構(gòu)建一個(gè)演示應(yīng)用程序并學(xué)習(xí)在您的 Flutter 應(yīng)用程序中使用 freezed 嗎?

Flutter 凍結(jié)示例

測試 BLoC 設(shè)計(jì)模式

為了測試 bloc,您需要兩個(gè)包:

  • bloc_test

  • 顫動測試

只需在測試文件夾中,創(chuàng)建 app_bloc_test.dart 文件并開始編寫測試。
在內(nèi)部我們將測試兩個(gè)條件:

  • 應(yīng)用程序的初始狀態(tài),即 AppState.empty()。

  • 按下按鈕時(shí)狀態(tài)會發(fā)生變化。

給你!????

Flutter BLoC 教程:使用 BLoC 模式進(jìn)行狀態(tài)管理
無效主要(){
塊測試(
  '初始狀態(tài)',
  構(gòu)建:()=> AppBlocBloc(),
  驗(yàn)證:(appState)=>
      expect(appState.state, const AppState.empty(), reason: 'Initial State'),
);
塊測試(
  '添加 MyEvent 時(shí)發(fā)出 [MyState]。',
  構(gòu)建:()=> AppBlocBloc(),
  行為:(bloc) => bloc.add(const ChangeTextEvent()),
  期望:()=>常量[
    應(yīng)用程序狀態(tài)(
      指數(shù):1,
      文本:'更改文本',
    ),
  ],
);}

解釋

  • blocTest 來自 bloc_test 包。

  • build():它返回 AppBlocBloc() 的一個(gè)實(shí)例。

  • verify 和 expect 顧名思義它們匹配狀態(tài) expect(actual, matcher, reason)。

  • act:將事件添加到事件流中。

Github 存儲庫:Flutter BLoC 簡單示例

隨意克隆存儲庫:flutter-bloc-demo并開始試驗(yàn)代碼。

結(jié)論

Flutter BLoC 教程有助于您開始使用 BLoC 模式進(jìn)行狀態(tài)管理。我們將帶著另一個(gè) Flutter 教程回來;到那時(shí),請?jiān)L問Flutter 教程頁面并了解有關(guān) Flutter 概念的更多信息。讓我們知道您是否希望涵蓋任何特定主題。給我們回信您的建議和反饋??鞓肪幋a!


The End