Flutter 空安全的糖果罐


theme: cyanosis

前言

Fluter 2.0 已經(jīng)發(fā)布了一段時間了皆怕,其中一項就是包含 Dart 2.12 的穩(wěn)定版,完全支持空安全聲明四啰。作為一個進步的 Flutter 組織
, 組織的小伙伴也在第一時間支持了空安全吆鹤。

組織發(fā)布的組件: https://pub.flutter-io.cn/publishers/fluttercandies.com/packages

組織支持空安全的進度: https://github.com/fluttercandies/flutter_candies/issues/5

介紹

以下的組件均已支持空安全丛肮,這里只會做簡單的介紹,具體使用方法涡驮,請到各組件下地址查看暗甥。

屏幕適配

Adaptation,用于屏幕適配的組件遮怜,你只需要設(shè)置設(shè)計稿的寬度淋袖,其他的尺寸直接按照設(shè)計稿填寫即可。當然這種適配方式其實是不推薦的锯梁,正如作者所言即碗。

用戶使用更大的屏幕是為了接收更多的信息, 而不是看到更大的字

基于這個觀點, 我個人建議使用文字流式, 圖片寬高比, 控件彈性的方案來做

但是很多初學(xué)者對于這個原則很難把握, 而等比例放大比較容易理解, 所以我寫了這個庫

import 'package:adaptation/adaptation.dart';
 MaterialApp(
  title: 'Flutter Demo',
  theme: ThemeData(
    primarySwatch: Colors.blue,
    visualDensity: VisualDensity.adaptivePlatformDensity,
  ),
  home: MyHomePage(title: 'Flutter Demo Home Page'),
  builder: (context, widget) {
    return Adaptation(
      child: widget,
      designWidth: 375, // 你的設(shè)計稿寬度
    );
  },
);

資源文件生成

assets_generator焰情,用于自動生成 assets 配置 (yaml) 以及 consts 的工具,支持單項目和多模塊剥懒。

-h, --[no-]help     顯示幫助信息
-p, --path          Flutter 項目的根路徑
                    (默認 ".")
-f, --folder        assets 文件夾的名字
                    (默認 "assets")
-w, --[no-]watch    是否繼續(xù)監(jiān)聽 assets 的變化
                    (默認 開啟)
-t, --type          pubsepec.yaml 生成配置的類型
                    "d" 代表以文件夾方式生成 "- assets/images/"
                    "f" 代表以文件方式生成   "- assets/images/xxx.jpg"
                    (默認 "d")
-s, --[no-]save     是否保存命令到本地
                    如果執(zhí)行 "agen" 不帶任何命令内舟,將優(yōu)先使用本地的命令進行執(zhí)行
-o, --out           const 類放置的位置
                    (默認放置在 "lib" 下面)
-r, --rule          consts 的名字的命名規(guī)范
                    "lwu"(小寫帶下劃線) : "assets_images_xxx_jpg"
                    "uwu"(大寫帶下劃線) : "ASSETS_IMAGES_XXX_JPG"
                    "lcc"(小駝峰)      : "assetsImagesXxxJpg"
                    (默認 "lwu")
-c, --class         const 類的名字
                    (默認 "Assets")
    --const-ignore  使用正則表達式忽略一些const(不是全部const都希望生成)
assets_generator.gif

圖片

ExtendedImage,集眾多功能為一體的圖片組件初橘,包括以下主要功能:

  • 緩存網(wǎng)絡(luò)圖片
  • 加載狀態(tài)(正在加載,完成保檐,失敗)
  • 拖拽縮放圖片
  • 圖片編輯(裁剪耕蝉,旋轉(zhuǎn),翻轉(zhuǎn))
  • 圖片預(yù)覽(跟微信掘金一樣)
  • 滑動退出效果(跟微信掘金一樣)
  • 設(shè)置圓角夜只,邊框
  • 支持進度顯示
  • 圖片預(yù)覽上滑顯示詳情(跟圖蟲一樣)
  • 減少內(nèi)存占用
zoom.gif
slide.gif
photo_view.gif
editor.gif
9e93eba3cc614ddbb818a3a445a41a99_tplv-k3u1fbpfcp-zoom-1 (1).gif
2097626b7d0a406ab769cb528a31388e_tplv-k3u1fbpfcp-zoom-1.gif

列表擴展

9e93eba3cc614ddbb818a3a445a41a99_tplv-k3u1fbpfcp-zoom-1 (1).gif

ExtendedList垒在,針對官方 ListviewGirdView 做的擴展組件,包括以下主要功能:

  • 監(jiān)聽元素回收
  • 監(jiān)聽 Viewport 中元素變化
  • 為最后一個元素設(shè)置特殊布局
  • 列表倒序特殊布局扔亥,類聊天列表
gridview.gif
chat_list.gif

嵌套滾動視圖擴展

ExtendedNestedScrollView场躯,主要解決官方 NestedScrollView 存在的2個問題。

Sliver 擴展

ExtendedSliver,對 Sliver 組件的擴展粘茄,主要包括以下功能:

  • SliverPinnedPersistentHeader签舞,跟官方的SliverPersistentHeader(pinned: true) 一樣的效果, 不同的是你不需要去設(shè)置 minExtentmaxExtent。因為大部分場景下面驹闰,我們是無法提前知道 minExtentmaxExtent瘪菌。
  • SliverPinnedToBoxAdapter,可以通過它輕松創(chuàng)建一個置頂?shù)脑剜诶剩?child 沒有 layout 之前师妙,你沒法知道 child 的實際大小,這將是非常有用的組件屹培。
  • ExtendedSliverAppbar默穴,你可以創(chuàng)建一個跟 SliverAppbar 一樣效果的組件,而不用去關(guān)心 expandedHeight 褪秀。
extended_sliver.gif

TabBarView 擴展

ExtendedTabs蓄诽,對 TabBarView 組件的擴展,主要包括以下功能:

  • 解決多級 TabBarView 嵌套的時候媒吗,無法連貫切換的問題
  • 垂直方向滾動
  • 設(shè)置緩存頁面數(shù)量
  • 提供 CarouselIndicatorColorTabIndicator
link.gif
scrollDirection.gif

文本

ExtendedText仑氛,針對 Text 組件的擴展,主要包括以下功能:

special_text.jpg
overflow.jpg
background.png
selection.gif

輸入框

ExtendedTextField,針對 TextField 組件的擴展捶牢,主要包括以下功能:

  • 方便快速生成特殊文本鸠珠,原理很簡單,就是把字符串轉(zhuǎn)換成特定的 InlineSpan秋麸。
  • ExtendedWidgetSpan 支持輸入框中插入任何 Widget渐排,比如表情圖片。
  • ExtendedWidgetSpan 支持選擇和復(fù)制灸蟆, https://github.com/flutter/flutter/issues/30688 飞盆。
extended_text_field.gif
extended_text_field_image.gif
custom_toolbar.gif
widget_span.gif

路由注解

ff_annotation_route,通過注解生成路由映射次乓,統(tǒng)一處理路由,支持 Navigator 1.0Navigator 2.0孽水。

  1. 激活工具 pub global activate ff_annotation_route
  2. 增加引用
dependencies:
  # 在子模塊中引入
  ff_annotation_route_core: any
  # 在根項目引入票腰,包括一些幫助類以及 ff_annotation_route_core
  ff_annotation_route_library: any
  1. 添加注釋

工具會自動處理帶參數(shù)的構(gòu)造,不需要做特殊處理女气。唯一需要注意的是杏慰,你需要設(shè)置 argumentImports 來為 class/enum 的參數(shù)提供 import 地址。現(xiàn)在你也可以使用 @FFArgumentImport() 注釋來替代.

@FFArgumentImport('hide TestMode2')
import 'package:example1/src/model/test_model.dart';
@FFArgumentImport()
import 'package:example1/src/model/test_model1.dart' hide TestMode3;
import 'package:ff_annotation_route_library/ff_annotation_route_library.dart';

@FFRoute(
  name: 'flutterCandies://testPageE',
  routeName: 'testPageE',
  description: 'Show how to push new page with arguments(class)',
  // argumentImports are still work for some cases which you can't use @FFArgumentImport()
  // argumentImports: <String>[
  //   'import \'package:example1/src/model/test_model.dart\';',
  //   'import \'package:example1/src/model/test_model1.dart\';',
  // ],
  exts: <String, dynamic>{
    'group': 'Complex',
    'order': 1,
  },
)
class TestPageE extends StatelessWidget {
  const TestPageE({
    this.testMode = const TestMode(
      id: 2,
      isTest: false,
    ),
    this.testMode1,
  });
  factory TestPageE.deafult() => TestPageE(
        testMode: TestMode.deafult(),
      );

  factory TestPageE.required({@required TestMode testMode}) => TestPageE(
        testMode: testMode,
      );

  final TestMode testMode;
  final TestMode1 testMode1;
}
  1. 執(zhí)行命令生成路由炼鞠,ff_route <command> [arguments]缘滥,全部命令如下:
-h, --[no-]help                   幫助信息。

-p, --path                        執(zhí)行命令的目錄谒主,默認當前目錄朝扼。

-o, --output                      route 和 helper 文件的輸出目錄路徑,路徑相對于主項目的 lib 文件夾霎肯。

-n, --name                        路由常量類的名稱擎颖,默認為 `Routes`。

-g, --git                         掃描 git 引用的 package观游,你需要指定 package 的名字搂捧,多個用 `,` 分開
    --routes-file-output          routes 文件的輸出目錄路徑,路徑相對于主項目的lib文件夾
    --const-ignore                使用正則表達式忽略一些const(不是全部const都希望生成)
    --[no-]route-constants        是否在根項目中的 `xxx_route.dart` 生成全部路由的靜態(tài)常量
    --[no-]package                這個是否是一個 package
    --[no-]supper-arguments       是否生成路由參數(shù)幫助類

-s, --[no-]save                   是否保存命令到本地懂缕。如果保存了允跑,下一次就只需要執(zhí)行 `ff_route` 就可以了。
    --[no-]null-safety            是否支持空安全,默認 `true`
  1. 設(shè)置 MaterialApponGenerateRoute 回調(diào)
import 'package:ff_annotation_route_library/ff_annotation_route_library.dart';
import 'package:flutter/material.dart';
import 'example_route.dart';
import 'example_routes.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ff_annotation_route demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      initialRoute: Routes.fluttercandiesMainpage,
      onGenerateRoute: (RouteSettings settings) {
        return onGenerateRoute(
          settings: settings,
          getRouteSettings: getRouteSettings,
          routeSettingsWrapper: (FFRouteSettings ffRouteSettings) {
            if (ffRouteSettings.name == Routes.fluttercandiesMainpage ||
                ffRouteSettings.name ==
                    Routes.fluttercandiesDemogrouppage.name) {
              return ffRouteSettings;
            }
            return ffRouteSettings.copyWith(
                widget: CommonWidget(
              child: ffRouteSettings.widget,
              title: ffRouteSettings.routeName,
            ));
          },
        );
      },
    );
  }
}
  1. 打開一個頁面
  Navigator.pushNamed(
    context,
    Routes.flutterCandiesTestPageE.name,
    arguments: Routes.flutterCandiesTestPageE.requiredC(
      testMode: const TestMode(
        id: 100,
        isTest: true,
      ),
    ),
  );

可拖拽容器

DraggableContainer聋丝,可拖拽容器索烹,支持元素移動動畫效果,主要包括以下功能:

  • 可拖動子元素
  • 可刪除子元素
  • 可固定子元素
  • 元素移動動畫效果
image

圖片編輯

ImageEditor潮针,強大的原生圖片處理庫术荤,主要包括以下功能:

  • 裁剪
  • 翻轉(zhuǎn)
  • 旋轉(zhuǎn)
  • 縮放
  • 色彩矩陣變化
  • 添加文字
  • 混合圖片
  • 添加任意圖形
editor.gif

Dialog

SmartDialog,一種更優(yōu)雅的Dialog 解決方案每篷,主要解決了系統(tǒng)自帶的Dialog的一些問題:

  • 必須傳 BuildContext瓣戚。
  • 無法穿透暗色背景,點擊 Dialog 后面的頁面焦读。
  • 解決系統(tǒng)自帶 Dialog 寫成的 Loading 彈窗子库,在網(wǎng)絡(luò)請求和跳轉(zhuǎn)頁面的情況,會存在路由混亂的情況矗晃。
smartDialog

資源選擇器

AssetPicker仑嗅,對標微信的多選資源選擇器,99%接近于原生微信的操作张症,主要包括以下功能:

  • ?? 支持基于代理重載的全量自定義
  • ?? 99% 的微信風(fēng)格
  • ?? 圖片資源支持
    • ??HEIC 格式圖片支持
  • ?? 視頻資源支持
  • ?? 音頻資源支持
  • 1?? 單資源模式
  • ?? 國際化支持
  • ? 特殊 widget 構(gòu)建支持(前置/后置)
  • ?? 自定義路徑排序支持
  • ?? 自定義文本構(gòu)建支持
  • ? 自定義篩選規(guī)則支持( photo_manager
  • ?? 完整的自定義主題
  • ?? 支持 MacOS
1
2
3
4
5
6
7
8
9

相機資源選擇器

CameraPicker仓技,對標微信的視頻資源選擇器,99%接近于原生微信的操作俗他,主要包括以下功能:

  • ?? 支持健全的空安全
  • ?? 99% 的微信風(fēng)格
  • ?? 支持拍照
    • ?? 支持設(shè)置曝光參數(shù)
    • ??? 支持捏合縮放
  • ?? 支持錄像
    • ? 支持限制錄像時間
    • ?? 支持錄像時縮放
  • ?? 支持自定義前景 widget 構(gòu)建
image
image
image
image

JsonToDart

JsonToDart脖捻,強大的 JsonToDart 工具,主要包括以下功能:

  • 空安全
  • 編輯類名兆衅,屬性名
  • 去重復(fù)類
  • Merge 類屬性
  • 數(shù)據(jù)數(shù)組保護
  • 屬性命名規(guī)范化地沮,只讀,排序
  • 國際化
  • 全平臺
  • 智能可空
平臺 描述 地址
Windows Flutter for Windows https://gitee.com/zmtzawqlp/JsonToDart/releases/
Macos Flutter for Macos https://gitee.com/zmtzawqlp/JsonToDart/releases/
Web Flutter for Web https://zmtzawqlp.gitee.io/jsontodart/
微軟商店 功能未同步羡亩,以后會替換成 Flutter for UWP https://www.microsoft.com/store/apps/9NBRW9451QSR
JsonToDart.gif

點贊按鈕

LikeButton摩疑,仿推特點贊效果,支持數(shù)字動畫效果畏铆。

image

增量加載列表

LoadingMoreList雷袋,支持各種布局的增量加載列表,主要包括以下功能:

  • ListView
  • GridView
  • 瀑布流
  • 多個 Sliver 布局
  • 自定義加載狀態(tài) UI
  • 監(jiān)控進入 Viewport 元素
  • 類聊天列表布局
  • 監(jiān)控元素回收
listview.gif
multiple_sliver.gif
error.gif
custom_indicator.gif
nested_scrollView.gif
known_sized.gif

下拉刷新

PullToRefreshNotification及志,靈活的自定義下拉刷新組件片排,可以創(chuàng)造出任意的下拉刷新樣式。

appbar.gif
header.gif
image.gif
candies.gif

底部擴散模糊動畫

RippleBackdropAnimatePage,騷氣十足的模糊動畫,只需要幾行代碼就能幫你實現(xiàn)序调。

image

彈出菜單

WPopupMenu财边,目前最好用的仿微信聊天長按彈出框。

image

瀑布流

WaterfallFlow,高性能的瀑布流布局蝗敢,https://github.com/flutter/flutter/issues/40856 日缨。

  • 高性能
  • 易上手捅僵,跟 GridView 一樣的 api
  • 可監(jiān)控進入 Viewport 元素
  • 可監(jiān)控元素回收
random_sized.gif
custom_scrollView.gif
known_sized.gif
variable_sized.gif

遷移

指南

感謝 Flutter & Dart 文檔中國本地化 全球遮天團 為我們提供了完整準確的文檔家卖,https://dart.cn/null-safety/migration-guide空安全 遷移大概有下面幾個步驟:

  1. 執(zhí)行flutter pub outdated --mode=null-safety 庙楚,檢查自己項目依賴的庫是否都支持空安全上荡。

  2. 如果都支持了,執(zhí)行 dart migrate --apply-changes馒闷。不加 --apply-changes 的話酪捡,會有一個瀏覽器地址,你打開之后纳账,可以在瀏覽器中進行修改逛薇。我一般還是習(xí)慣在直接 --apply-changes 之后直接在 vscode 中進行修改。執(zhí)行完畢之后疏虫,你的 Dart SDK 版本會自動改為大于2.12.0永罚。(注意,執(zhí)行 dart migrate 命令必須確保 SDK 是小于 2.12.0 的)

environment:
  sdk: '>=2.12.0 <3.0.0'
  1. 工具不是萬能的卧秘,會有一些 錯誤呢袱,請先查看完 https://dart.cn/null-safety 之后,根據(jù)自己的業(yè)務(wù)場景對代碼進行更正翅敌。

問題

空安全對非空 List<T> 的影響是非常大的产捞。

不能對非空的列表設(shè)置更大的長度

List 的 length getter 也有一個對應(yīng)的 setter,這一點鮮為人知哼御。您可以對列表設(shè)置一個較短的長度,從而截斷它焊唬。您也可以對列表設(shè)置一個更長的長度恋昼,從而使用未初始化的元素填充它。

如果您對一個非空的列表做了這樣的操作赶促,在訪問未初始化的元素時液肌,就與空安全的健全性發(fā)生了沖突。為了防止意外發(fā)生鸥滨,現(xiàn)在對一個非空類型的數(shù)組調(diào)用調(diào)用 length setter嗦哆, 并且 準備設(shè)置一個更長的長度時,會在運行時拋出一個異常婿滓。您仍然可以對任何類型的列表進行截斷老速,也可以對一個可空類型的列表進行填充。

如果您自定義了列表的類型凸主,例如繼承了 ListBase 或者混入了 ListMixin橘券,那么這項改動可能會造成較大的影響。以上的兩種類型都提供了 insert() 的實現(xiàn),通過設(shè)置長度旁舰,為插入的元素提供空間锋华。在空安全中這樣做可能會出現(xiàn)錯誤,所以我們將它們的 insert() 實現(xiàn)改為了 add()〖埽現(xiàn)在您自定義的列表應(yīng)該繼承 add() 方法 方法毯焕。

下面我們來跟一波可空列表在做 add 操作時候的流程,來理解下文檔所說的意思磺樱。

位置
list.dart bin/cache/dart-sdk/lib/collection/list.dart
growable_array.dart bin/cache/dart-sdk/lib/_internal/vm/lib/growable_array.dart
array.dart bin/cache/dart-sdk/lib/_internal/vm/lib/array.dart
  1. ListMixin.add (dart:collection/list.dart:278)
  // List interface.
  void add(E element) {
    // This implementation only works for lists which allow `null` 
    // as element.
    this[this.length++] = element;
  }
  1. List.length= (dart:core-patch/growable_array.dart:227)
  void set length(int new_length) {
    if (new_length > length) {
      // Verify that element type is nullable.
      // 官方在這里做了判斷 
      null as T;
      if (new_length > _capacity) {
        _grow(new_length);
      }
      _setLength(new_length);
      return;
    }
    final int new_capacity = new_length;
  1. List._grow (dart:core-patch/growable_array.dart:362)
  void _grow(int new_capacity) {
    // 創(chuàng)建了一個長度為 new_capacity 的數(shù)組纳猫,并且用 null 填充
    var newData = _allocateData(new_capacity);
    // This is a work-around for dartbug.com/30090: array-bound-check
    // generalization causes excessive deoptimizations because it
    // hoists CheckArrayBound(i, ...) out of the loop below and turns it
    // into CheckArrayBound(length - 1, ...). Which deoptimizes
    // if length == 0. However the loop itself does not execute
    // if length == 0.
    // 從舊列表中復(fù)制數(shù)據(jù)
    if (length > 0) {
      for (int i = 0; i < length; i++) {
        newData[i] = this[i];
      }
    }
    // 通知引擎替換新數(shù)據(jù)
    _setData(newData);
  }
  1. List._allocateData (dart:core-patch/growable_array.dart:349) 以及
    _List (dart:core-patch/array.dart.dart:13)
  static _List _allocateData(int capacity) {
    if (capacity == 0) {
      // Use shared empty list as backing.
      return _emptyList;
    }
    // Round up size to the next odd number, since this is free
    // because of alignment requirements of the GC.
    // (dart:core-patch/array.dart.dart:13)
    return new _List(capacity | 1);
  }
  1. 通知引擎更新新數(shù)據(jù)
 @pragma("vm:recognized", "graph-intrinsic")
  void _setData(_List array) native "GrowableList_setData";
  1. 通知引擎更新新長度
  @pragma("vm:recognized", "graph-intrinsic")
  void _setLength(int new_length) native "GrowableList_setLength";
image.png

第三步中,會返回元素為 null 的列表坊罢,所以在空安全的情況下续担,列表操作中需要做以下改動。

  • List<int> list = List<int>(); 改為 List<int> list = <int>[];

  • List<int> list = List<int>(1); 改為 List<int> list = List<int>.filled(1, 0);

  • 如果你繼承了 ListBase 或者混入了 ListMixin活孩,你需要重寫 add() 方法物遇,否則在第二步中就會報錯。完整代碼

  @override
  void add(T element) {
    _array.add(element);
  }

建議

坐和放寬

對于每次的大版本更新憾儒,不要著急升級询兴,特別是你的項目引用了三方組件。三方開源作者是不大可能有時間立刻就更新起趾,訂閱一下作者的更新計劃诗舰,靜靜等待。一般 stable 版本發(fā)布之后都會有熱修復(fù)版本训裆。如果你是新手眶根,請坐和放寬,靜待大佬們發(fā)現(xiàn)和解決點一些重大問題之后再更新边琉。

image.png

學(xué)會使用 pub.dev

空安全的組件有很明顯的標志 Null safety属百。打開 Versions 一簽,通過 Min Dart SDK很容易就看出組件是從哪個版本開始支持空安全的变姨,比如 extended_image3.0.0 版本支持空安全族扰。

image.png

另外,有些組件還提供了 Prerelease versions定欧。比如 extended_image 還提供了非空安全版本. 當然 Prerelease versions 也可能是預(yù)覽版渔呵,修復(fù)緊急問題(一些用戶使用 Flutter master/dev/beta 分支,該分支可能會有一些 apibreaking change)砍鸠,作者會發(fā)布預(yù)覽版來滿足這部分人群扩氢。

image.png

每個人都從萌新而來,愛護萌新爷辱,但也不應(yīng)該縱容巨嬰类茂。

  1. https://flutter.cn/https://dart.cn/ 耍属,從入門到深入,各種資源應(yīng)有盡有巩检。如果你準備入手 Flutter厚骗,這應(yīng)該是你必看的網(wǎng)站。
截屏2021-04-10 下午2.57.54.png
  1. https://github.com/flutter/flutter/issues 兢哭,當遇到一些奇怪問題的時候领舰,可以嘗試搜索官方, 也許地球上某個地方的我也遇到了相同的問題。如果沒搜到迟螺,并且確定是官方的問題冲秽,請不要吝嗇你的時間,提交一個 issue 矩父,讓官方知曉锉桑,為其他人節(jié)約時間,提供思路窍株。不要擔心你的英文水平民轴,只有多寫,多練習(xí)球订,才能更好后裸。

  2. https://www.google.comhttps://stackoverflow.com 程序猿都應(yīng)該知道和會使用。

  3. https://juejin.cn 應(yīng)該算是國內(nèi) Flutter 文章最多的一個網(wǎng)站了冒滩,對于英文不好的小伙伴微驶,有中文的各種各樣的 Flutter 相關(guān)文章也是極好的。

  4. qq群:181398081开睡,如果通過上面的方式因苹,你還是沒法解決問題,你可以在 qq群 里面提問篇恒,很榮幸群里有一群熱心的群友容燕,互相幫助,互相學(xué)習(xí)婚度。

  5. 最后,不管在哪里提問官卡,盡量上代碼蝗茁,或者闡明清楚意圖,因為也許想法或者解決方向從開始就是不正確的寻咒。


    image

結(jié)語

2歲的糖果

不知不覺哮翘,糖果 已經(jīng) 2歲 了,Flutter2.0 了毛秘。感謝 糖果 的小伙伴饭寺,對開源組件的持續(xù)支持阻课。從 Flutter Candies 一桶天下 到現(xiàn)在又一年了,組織也在不斷地壯大艰匙。歡迎更多的小伙伴都加入進來限煞,一起為 Flutter 社區(qū)添磚加瓦。

截屏.png

致糖果們

2019年2月14日 孤單一個人员凝,到現(xiàn)在的 2000 人署驻,感謝每個糖果的支持,感謝積極回復(fù)問題的糖果們健霹,感謝智能憨憨的群機器人旺上。如果你喜歡分享,請加入我們糖埋;如果你需要別人的分享宣吱,也請加入我們。

image.png

愛Flutter 瞳别,愛糖果

很開心你能閱讀到這里征候,愛Flutter愛糖果 洒试,歡迎加入 Flutter Candies 倍奢,一起生產(chǎn)可愛的 Flutter小糖果

QQ群:181398081。最后放上 Flutter Candies 全家桶垒棋,真香卒煞。

flutter_candies_logo.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市叼架,隨后出現(xiàn)的幾起案子畔裕,更是在濱河造成了極大的恐慌,老刑警劉巖乖订,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扮饶,死亡現(xiàn)場離奇詭異,居然都是意外死亡乍构,警方通過查閱死者的電腦和手機甜无,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哥遮,“玉大人岂丘,你說我怎么就攤上這事∶咭” “怎么了奥帘?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長仪召。 經(jīng)常有香客問我寨蹋,道長松蒜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任已旧,我火速辦了婚禮秸苗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘评姨。我一直安慰自己难述,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布吐句。 她就那樣靜靜地躺著胁后,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嗦枢。 梳的紋絲不亂的頭發(fā)上攀芯,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音文虏,去河邊找鬼侣诺。 笑死,一個胖子當著我的面吹牛氧秘,可吹牛的內(nèi)容都是我干的年鸳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼丸相,長吁一口氣:“原來是場噩夢啊……” “哼搔确!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起灭忠,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤膳算,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后弛作,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涕蜂,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年映琳,在試婚紗的時候發(fā)現(xiàn)自己被綠了机隙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡萨西,死狀恐怖有鹿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情原杂,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布您机,位于F島的核電站穿肄,受9級特大地震影響年局,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜咸产,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一矢否、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧脑溢,春花似錦僵朗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至社牲,卻和暖如春粪薛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背搏恤。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工违寿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人熟空。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓藤巢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親息罗。 傳聞我的和親對象是個殘疾皇子掂咒,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容