做者|嚴嘉俊
Flutter 是 Google 發佈的一個用於建立跨平臺、高性能移動應用的框架。隨着 Google 在 IO19 宣佈 Flutter 支持 Web 平臺,就標誌着 Flutter 已經全面持全部平臺。git
Flutter 提供了很是友好的文檔,開發過程當中遇到的問題均可以在 Stackoverflow 或其 github issue 中找到答案,幫助各端的同窗迅速地進入到 Flutter 中。同時它的徹底開源也讓其有了更快的迭代,更好的生態。github
根據谷歌官方 2020 年 4 月的統計數據,Flutter 自發布以來的 16 個月內,已有 200 萬開發者使用 Flutter,3 月份的時候也有 10% 的增加,Google Play Store 中發佈的 Flutter 應用約有 5 萬個,僅在 2020 年 4 月就有近 1 萬個應用上傳。開發者所在的團隊,初創公司最多,佔比 35%,其次是企業開發者,佔比 26% 。數據庫
🔺 來自谷歌開發者《Flutter 勢頭正盛 | 2020 春季速遞》小程序
知曉雲正式支持 Flutter,一樣也標誌着知曉雲已經全面支持全部平臺了。開發者經過使用知曉雲 Flutter SDK ,能夠在 Flutter 中操做存儲在知曉雲中的數據表、內容庫、媒體文件,以及調用雲函數進行後端邏輯的執行,節省了搭建服務器、數據庫,域名備案,數據接口實現等繁瑣流程,開發應用門檻更低、效率更高。後端
如今,咱們將結合知曉雲 Flutter SDK 來實戰作一個 Todo App,看看有多方便多快捷。服務器
🔺Todo App demo微信
構建一個 Todo App,咱們須要三步走:app
可下拉至文末,直接觀看教學視頻。框架
a. 使用 Flutter create 命令建立一個 project:less
$ flutter create todoApp $ cd todoApp
上述命令建立一個 Flutter 項目,項目名稱爲 todoApp,其中包含一個使用 Material 組件的簡單演示應用程序。
b. 將 lib/ 下的 main.dart 裏面的代碼所有刪除。
首先咱們先在 lib 文件夾新建一個 pages 文件夾並在該文件夾裏建立一個 home.dart 文件做爲咱們的首頁。
而後在 home.dart 這個文件裏,建立一個 stateful widget,添加引入 material 庫。
import 'package:flutter/material.dart'; class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { return Container( ); } }
最後在 main.dart 中引入該頁面便可。
import 'package:flutter/material.dart'; import './pages/home.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', home: HomePage(), ); } }
返回 home.dart 這個文件,在 build 的 return 處添加 Scaffold,並添加 AppBar 標題等信息。因爲咱們 Demo 的結構是縱向排列,所以咱們直接用 Column 便可。
爲了讓咱們的按鈕都可以撐開屏幕的寬度,能夠設置 CrossAxisAlignment.stretch。目前代碼:
class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('知曉雲 Flutter SDK Demo'), ), body: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ ], ), ); } }
接着咱們開始寫輸入框。咱們能夠用 Form 以及 TextFormField 來建立一個輸入框,而且經過構建一個 controller 來控制輸入框的行爲。最後,能夠定義 decoration 值來實現相似於佔位符的效果:
Form( child: TextFormField( controller: inputController, decoration: InputDecoration(labelText: '請輸入 Todo 內容'), ), )
下一步即是構建一個添加 Todo 的按鈕。咱們能夠經過建立一個 RaisedButton 並指定按鈕內容爲「添加 Todo」。因爲目前還沒到須要肯定點擊時間的時候,所以 onPressed 這個功能能夠暫時設置爲一個無動做的函數。以後爲了讓按鈕好看一點,咱們能夠把按鈕的背景設置爲藍色,文字設置爲白色,高度設置 50,並讓按鈕和輸入框稍微有一點間距:
SizedBox( height: 5.0, ), ButtonTheme( height: 50.0, child: RaisedButton( onPressed: () {}, child: Text( '添加 Todo', style: TextStyle(color: Colors.white), ), color: Colors.blue, ), ),
接下來咱們繼續構建咱們的 Todo 列表。
首先,咱們在寫結構以前先定義好一些將會用到的假數據,方便接下來的樣式調整。咱們能夠定義一個 todoList 列表,每一個子項都包含兩個字段,一個是「name」,表示 todo 的名字,另外一個是「isDone」,用於判斷這個 todo 是否已經完成。
List todoList = [ {"name": "學習 SDK", "isDone": false}, {"name": "開早會", "isDone": true}, ];
以後咱們繼續寫列表的結構。咱們能夠用 ListView 來建立一個列表項,其 children 屬性循遍歷 todoList 的內容。以後每一個 child 裏咱們都用一個 Row 來表示,其 children 屬性包含三樣東西,分別是 todo 的名稱,完成按鈕和刪除按鈕。爲了 todo 名稱能夠撐開剩餘寬度,咱們還可使用 Expanded 這個 widget 進行撐開:
ListView( shrinkWrap: true, children: todoList.map((todo) { return Row( children: [ Expanded(child: Text(todo['name'])), RaisedButton( onPressed: () {}, child: Text( '完成', style: TextStyle(color: Colors.white), ), color: Colors.green, ), SizedBox( width: 5, ), RaisedButton( onPressed: () {}, child: Text( '刪除', style: TextStyle(color: Colors.white), ), color: Colors.redAccent, ), ], ); }).toList(),
目前咱們的基本結構已經完成,但還須要判斷一下 todo 完成和未完成的狀態樣式。咱們能夠根據 isDone 來判斷完成狀態。若是已經完成,則將 todo 名稱的樣式置灰,而且加一條橫線表示已完成。因爲已經完成,完成按鈕也無須顯示:
Expanded( child: Text( todo['name'], style: TextStyle( color: todo['isDone'] == true ? Colors.black26 : Colors.black, decoration: todo['isDone'] == true ? TextDecoration.lineThrough : TextDecoration.none, ), ), ), if (todo['isDone'] == false) RaisedButton( onPressed: () {}, child: Text( '完成', style: TextStyle(color: ), color: Colors.redAccent, ),
至此,咱們基本完成了本次 Demo 的樣式結構。
引入 SDK 的部分相對比較簡單,咱們先去 https://pub.dev/ 搜索 minapp,找到咱們官方知曉雲 SDK 的包。在 Installing 標籤頁,將 dependencies 中的 minapp 部分引入到咱們項目根目錄中的 pubspec.yaml 文件對應的部分:
dependencies: flutter: sdk: flutter minapp: ^0.0.1-dev.1
上面代碼塊的版本號爲 0.0.1-dev.1,該版本仍是一個預覽版本。相信您在看到這篇文章時已是正式版本了。
項目目錄下跑 flutter pub get 安裝依賴。
安裝依賴後,咱們回到 main.dart,引入 SDK。並在 main 這個函數中,用咱們的 ClientID 初始化咱們的 SDK。該 SDK 能夠在知曉雲控制檯的設置中找到。最後,也須要在 home.dart 中引入 SDK。
import 'package:flutter/material.dart'; import 'package:minapp/minapp.dart' as BaaS; import './pages/home.dart'; void main() { BaaS.init('dce25a0b4fe0a5558b5'); runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', home: HomePage(), ); } }
至此,咱們已完成對 SDK 的引入。
在寫 Todo 的增刪查改功能前,咱們先在知曉雲控制檯建立一個名爲 todo_demo 的表,爲了接下來更方便地展現,這個表暫時設置爲全部人均可以讀寫。而後新建兩個字段,第一個爲類型爲 string 的「name」字段,另外一個爲類型爲 boolean 的 「isDone」字段,默認爲 false。
🔺知曉雲控制檯
以後返回到 home.dart,添加一個 TableObject 變量,並指定表名爲 todo_demo:
TableObject tableObject = new TableObject('todo_demo');
接下來咱們正式開始對數據的新增查改。
首先先建立一個添加 Todo 的函數。這個函數須要獲取用戶輸入的值,而後經過調用 tableObject 中的 create 方法,建立一條記錄。以後經過記錄中的 set 方法設定 「name」」字段中的值,也就是輸入值。最後調用 save 方法發出請求保存數據。
// 添加 todo void addTodo() async { TableRecord record = tableObject.create(); record.set('name', inputController.text); try { await record.save(); } catch (e) { print(e.toString()); } }
知曉雲對於數據庫的新增和刪改都須要用戶登陸才能正常使用,但因爲以前咱們在建立表的時候已經對錶的權限放開,容許全部人均可以增刪查改,所以咱們只須要構建一個匿名登陸的方法便可。最後還須要將這個匿名登陸方法放到 initState 中執行一下:
void anonymousLogin() async { try { await Auth.anonymousLogin(); print('登陸成功'); } catch (e) { print(e.toString()); } } @override void initState() { super.initState(); anonymousLogin(); }
接下來咱們開始添加獲取 Todo 列表的方法。咱們建立一個 getTodoList 函數,經過 tableObject 中的 find 方法,獲取表內全部的數據。而後對 todoList 進行賦值爲 recordList.records。其中這個 records 是 SDK 封裝好的數據類型,具體內容可參考官方文檔。
// 獲取 todo 列表 void getTodoList() async { try { TableRecordList recordList = await tableObject.find(); setState(() { todoList = recordList.records; }); } catch (e) { print(e.toString()); } }
因爲以前的 todoList 是假數據,如今須要移除一下。在第一步構建的結構也要對應修改,在 todo 後面添加 recordInfo:
Expanded( child: Text( todo.recordInfo['name'], style: TextStyle( color: todo.recordInfo['isDone'] == true ? Colors.black26 : Colors.black, decoration: todo.recordInfo['isDone'] == true ? TextDecoration.lineThrough : TextDecoration.none, ), ), ), if (todo.recordInfo['isDone'] == false) RaisedButton( onPressed: () {}, child: Text( '完成', style: TextStyle(color: Colors.white), ), color: Colors.green, ),
最後爲了更好的用戶體驗,咱們也要把 getTodoList 這個方法放到 initState 中,且也要相應地,在 addTodo 這個方法中放入。這樣每當咱們添加 todo 時,就刷新一次 todo 列表。
@override void initState() { super.initState(); anonymousLogin(); getTodoList(); }
await record.save(); getTodoList();
以後,咱們刷新一個頁面便可看到真實數據。
接下來咱們繼續寫完成按鈕的操做。咱們能夠經過調用 tableObject.getWithoutData 來獲取某條數據項,而後將這條數據的 isDone 設置爲 true,表示已經完成,而後經過 update 方法發出請求更新數據。
// 完成 todo void completeTodo(String id) async { TableRecord record =tableObject.getWithoutData(recordId: id); record.set('isDone', true); try { await record.update(); getTodoList(); } catch (e) { print(e.toString()); } }
最後咱們來完成一下刪除功能。經過調用 tableObject 的 delete 方法,並傳入 id,進行刪除:
// 刪除 todo void deleteTodo(String id) async { try { await tableObject.delete(recordId: id); getTodoList(); } catch (e) { print(e.toString()); } }
咱們也不要忘記每次構建一個函數,也要相應地將其綁定到咱們的按鈕時間當中:
RaisedButton( onPressed: () => deleteTodo(todo.id), child: Text( '刪除', style: TextStyle(color: Colors.white), ), color: Colors.redAccent, ),
至此,咱們的 todo app 已經順利地完成。
本章節主要以 Todo App 爲例,向你們展現了數據的增刪查改等基礎功能,若有不明白的地方,可經過掃描下方小程序碼,觀看教學視頻,結合開發實戰教學視頻一塊兒學習。
👉 掃描下方小程序碼,觀看教學視頻
👉 PC 端可點這裏觀看教學視頻
另外,提到 Flutter,你們可能會聯想起 SwiftUI。關於 SwiftUI 開發實戰,咱們也以新聞資訊 App 爲例,提供了開發實戰教程。有興趣的小夥伴可點擊下方標題連接進行學習。
若是有其它學習需求,可經過文末評論或小曉雲微信留言(微信號:minsupport4),咱們將根據實際反饋狀況安排下期實戰教學,敬請期待。
💡教程預告:App Clips 蘋果牌小程序完整版 demo 教程。