做者|严嘉俊
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 教程。