iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 12
2
Mobile Development

Flutter---Google推出的跨平台框架,Android、iOS一起搞定系列 第 12

【Flutter基礎概念與實作】 Day12–Flutter Bloc 套件介紹 (2) BlocBuilder、BlocProvider和BlocListener

又是新的一天,今天接著來看如何使用「flutter_bloc」內提供的widget吧。

BlocBuilder

BlocBuilder的用途非常好理解,就是當Bloc的State有變化,他會根據你的設計重建App的介面。使用BlocBuilder就不再需要使用setState()幫我們重繪介面了,一切交由BlocBuilder幫我們處理。

使用BlocBuilder需要給予兩個參數blocbuilder。同樣用LoginBloc作為範例。

BlocBuilder<LoginBloc, LoginState>(
    builder: (BuildContext context, LoginState state) {
    // 判斷目前的State是哪種,顯示對應的畫面給使用者
        if(state.isSuccess) {
            return Text('Login Successfully!');
        }
        else if (state.isFailure){
            return Text('Login failed ><');
        }
    }
)

另外還有condition參數能作使用,讓你能夠依照先前和當下的State決定是否要重新建構畫面。

BlocBuilder<LoginBloc, LoginState>(
    condition: (previousState, currentState){
        // 依照需求可以設定重建畫面的條件
        // 回傳true會呼叫builder重建畫面
        // 回傳false就會略過
    }
    builder: (BuildContext context, LoginState state) {
        if(state.isSuccess){
            return Text('Login Successfully!');
        }
        else if (state.isFailure){
            return Text('Login failed ><');
        }
    }
)

BlocProvider

BlocProvider顧名思義他的工作就是負責供應Bloc給其他人。它可以將Bloc給他widget tree下的children使用。這個widget非常方便,因為假如你不是使用它而是要自己實作bloc你會需要建立「inheritedwidget」才可以讓其他widget使用同個bloc。
如何實作inheritedwidget可以看這篇medium

另外使用BlocProvider的優點就是它會自動幫你將Bloc關閉(dispose),避免記憶體洩漏的問題,你會發覺有BlocProvider處理這些瑣事真好。

BlocProvider(
    builder: (BuildContext context) => LoginBloc(),
    child: // 下面的widget就可以使用loginbloc
)

// 需要使用到Loginbloc的widget就可以用下面這行來呼叫
_loginBloc = BlocProvider.of<LoginBloc>(context);

MultiBlocProvider

如果有多個Bloc就可以使用MultiBlocProvider。

MultiBlocProvider(
  providers: [
    BlocProvider<BlocA>(
      builder: (BuildContext context) => BlocA(),
    ),
    BlocProvider<BlocB>(
      builder: (BuildContext context) => BlocB(),
    ),
    BlocProvider<BlocC>(
      builder: (BuildContext context) => BlocC(),
    ),
  ],
  child: ChildA(),
)

BlocListener

BlocListener和BlocBuilder類似一樣會去監聽State的變化,兩者的差別在於Listener是用來顯示如SnackBar、Dialog的通知,而Builder是重建整個畫面。

BlocListener<LoginBloc, LoginState>(
      listener: (BuildContext context, LoginState state) {
      // 如果登入失敗就顯示失敗的通知
        if (state.isFailure) {
          Scaffold.of(context)
            ..hideCurrentSnackBar()
            ..showSnackBar(SnackBar(
              content: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Text('Login Failure'), Icon(Icons.error)
                ],)
              , backgroundColor: Colors.red,)
            );
        }
      child:
          // 可以接著使用BlocBuilder或其他widget

BlocListener一樣擁有condition參數可以依照前一個和現在的State決定是否要執行listener內的行為。

BlocListener<LoginBloc, LoginState>(
      condition: (previousState, currentState) {
          // 回傳true會執行listener
          // 回傳false不會執行listener
      }
      listener: (BuildContext context, LoginState state) {
        if (state.isFailure) {
          ......
        }
      child:
          // 可以接著使用BlocBuilder或其他widget

MultiBlocListener

若有多個Bloc要做監聽一樣有提供MultiBlocListener可以使用。

MultiBlocListener(
  listeners: [
    BlocListener<BlocA, BlocAState>(
      listener: (context, state) {},
    ),
    BlocListener<BlocB, BlocBState>(
      listener: (context, state) {},
    ),
    BlocListener<BlocC, BlocCState>(
      listener: (context, state) {},
    ),
  ],
  child: ChildA(),
)

今日總結

今天的內容比較少,不過介紹的widget都是非常實用的喔。這些widget讓我們不再需要使用setState()來通知介面需要重建。只要將bloc當作參數,UI不用知道背後的商業邏輯做了什麼事只要監聽到State有變動做出相對應的改變即可,漂亮地將Presentation layer和Business Logic分離。
呼~花了2天介紹Bloc這個套件大家可能有些厭煩了,別擔心明天就回到實作專案的部分,明天再見啦!


上一篇
【Flutter基礎概念與實作】 Day11–Flutter Bloc 套件介紹 (1) Events、States和Transitions
下一篇
【Flutter基礎概念與實作】 Day13–實作Authentication Bloc
系列文
Flutter---Google推出的跨平台框架,Android、iOS一起搞定30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言