iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 23
1
Mobile Development

iOS Developer Learning Flutter系列 第 23

iOS Developer Learning Flutter. Lesson22 Notification

Notification
翻譯成通知,也有聽過有人叫他推播、或廣播
這個字會有很多的歧義
今天我們要談的
不是本地媽媽通知(Local Notification)
也不是遠端推播(Push Notifications)
而是寫code裡面,類似NotificationCenter的通知☘️☘️☘️
其實差不多的東西
前兩天InheritedWidget/Provider已經有提到過了
那麼最大的不同是什麼呢?
就是傳遞方向
InheritedWidget/Provider是由UI樹的上往下傳
Notification是由UI樹的下往上傳

Today Preview


其實畫這個金字塔比實作Notification麻煩XDD
(左圖才是最終效果 右圖只是圖層示意)

Notification在flutter裡面跟iOS一樣有分系統級跟自訂的兩種☘️☘️☘️
系統提供以下12種可監聽的通知

接著我們講講自訂的方式

  1. 建立通知類別
class PyramidNotification extends Notification {
  final bool ok;
  PyramidNotification(this.ok);
}
  1. 監聽通知
    在你想要取得通知的位置(注意要在觀察對象的UI樹上方)
    加入NotificationListener
    因為他本人也是StatelessWidget
    所以也可以放進UI樹
    child是你原本要呈現的UI Widget
    onNotification就是接收通知的callback
    注意裡面要return一個bool
    如果true, 就不會繼續往上傳遞
    要選false才會繼續往上傳遞
    (這語意是不是有點...)
return NotificationListener<PyramidNotification>(
    onNotification: (notifi){
      print("come");
      if (notifi.ok) {
        fireAfter(fireSecond);
        setState(() {
          showLevel = true;
        });
      }
      return true; //是否到此為止, true: Stop; false: Bubbling
    },
    child: stack
);
  1. 發送通知
    使用dispatch
PyramidNotification(true).dispatch(context);

full code

import 'package:flutter/material.dart';
import 'package:idlf/define.dart';

final maxLevel = 7;

class LessonPageNotification extends StatefulWidget {
  @override
  _LessonPageNotificationState createState() => _LessonPageNotificationState();
}

class _LessonPageNotificationState extends State<LessonPageNotification> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Notification"),
        ),
        body: PyramidWidget(1)
    );
  }
}

class PyramidWidget extends StatefulWidget {

  final int level;
  const PyramidWidget(this.level);

  @override
  _PyramidWidgetState createState() => _PyramidWidgetState();
}

class _PyramidWidgetState extends State<PyramidWidget> {

  final fireSecond = 1;
  final cubeLong = 25.0;
  bool showLevel = false;

  void fireAfter(int sec) {
    Future.delayed(Duration(seconds: sec)).then((value) {
      print("go");
      PyramidNotification(true).dispatch(context);
    });
  }

  @override
  void initState() {
    super.initState();
    print(widget.level);

    if (widget.level == maxLevel) {
      showLevel = true;
      print("me");

      fireAfter(fireSecond);
    }
  }

  @override
  Widget build(BuildContext context) {

    final levelText = Text(widget.level.toString(),
      style: TextStyle(
          fontSize: 20,
          fontWeight: FontWeight.bold
      ),
    );

    final pyramid = Container(
      width: cubeLong * (widget.level * 2 -1),
      height: cubeLong * (maxLevel + 1 - widget.level),
      color: rainbowColors[widget.level - 1],
      child: showLevel ? levelText : Container(),
    );

    final stack = Container(color: Color.fromRGBO(0, 0, 0, 0),
      child: Stack(alignment: Alignment.bottomCenter,
          children: [
            pyramid,
            widget.level == maxLevel ? Container() : PyramidWidget(widget.level + 1), //容器的部分
          ]
      ),
    );

    return NotificationListener<PyramidNotification>(
        onNotification: (notifi){
          print("come");
          if (notifi.ok) {
            fireAfter(fireSecond);
            setState(() {
              showLevel = true;
            });
          }
          return true; //是否到此為止, true: Stop; false: Bubbling
        },
        child: stack
    );
  }
}

class PyramidNotification extends Notification {
  final bool ok;
  PyramidNotification(this.ok);
}

到今天為止
狀態管理篇就告一段落了
其實狀態管理有超多可以講
三個三十天也講不完
除了Provider
還有個BLoC也是Flutter上的顯學
有興趣的朋友也可以參考一下Zonble大的文章

參考連結


下集預告:ImagePicker

最後提供一下github.com/mark33699/IDLF


上一篇
iOS Developer Learning Flutter. Lesson21 Provider
下一篇
iOS Developer Learning Flutter. Lesson23 ImagePicker
系列文
iOS Developer Learning Flutter30

尚未有邦友留言

立即登入留言