Flutter 从发布之日起我就对其心心念念了很久。 奈何这段时间实在是太忙了,加之本身拖延症时不时发做下,一直都抽不出时间来学习这个跨平台框架。html
一转眼 Flutter 1.2 都已经发布了,这下实在是坐不住了。特意花了一周的时间来作了 一文 这个 APP 。以此来简单了解下这款全新跨平台框架的魅力。android
回到标题,既然是编写第二个 Flutter APP,那就要求各位观众老爷本身对照着官方的 First Flutter APP 撸一遍。(中文连接:flutterchina.club/get-started…)git
万事开头难,这部分包含了 dart 语言特性的学习,和 Flutter 框架一些特性的体验。github
若是你也是像我同样只是花两个小时简单看了下 dart 语言的新特性就直接来撸第一个 APP。写的时候可能会感受老是在云里雾里,不少地方都不明白。数据库
别担忧,这是正常现象,对咱们这种只想初步体验的用户来讲,没有系统的学习,这种状况才是正常现象。segmentfault
保持开放的心态,多学多看。碰到不懂的,多查,碰到不知道怎么写的,多看官方的源码实现,等代码量上去了,天然就熟练了。缓存
照着官方示例完成了本身了的第一个 APP 编写,是否是颇有成就感?激动之余,彷佛感受少了点什么。markdown
没错,毕竟只是照着官方的示例敲了一遍,说是 APP 也略简陋了。是否是火烧眉毛的想作点什么来巩固下本身的学习呢。框架
此次就跟着我一块儿从项目的立项开始你的第二个 APP 吧。async
因为项目一周的时间限制,本次就要求项目尽量的简单,页面尽量的少。且,要尽量的完成多的功能点,因而 一文 就诞生了。
一文 是基于每日一文 API 开发的一款全新的 Flutter APP。
注意:在源代码中,一个页面可能包含多个功能实现,在实际作的时候,请依据 APP 预览一项一项进行实现。
源代码并非标准答案,有问题欢迎提交 PR 进行贡献。
API 来源:github.com/jokermonn/-…
分析 API 进行联网实现,主要要求实现联网获取文章,获取后进行 Json 解析到 bean,而后进行简单的错误 handle。
参考文章:
按照原生 APP 开发的套路,用于初始化以及展现广告的 Splash 是必不可少的。
第一个页面,主要要求掌握页面编写的常规套路以及 StatefulWidget 的生命周期等。
好比 class SplashPage
的写法:
class SplashPage extends StatefulWidget { SplashPage({Key key, this.title}) : super(key: key); final String title; @override State<StatefulWidget> createState() { return _SplashPageState(); } } 复制代码
而后就是 class _SplashPageState
的编写。
布局就是一张图片:
import 'package:flutter/material.dart'; class SplashPage extends StatefulWidget { SplashPage({Key key, this.title}) : super(key: key); final String title; @override State<StatefulWidget> createState() { return _SplashPageState(); } } class _SplashPageState extends State<SplashPage> { @override void initState() { // TODO: do something to init super.initState(); } @override Widget build(BuildContext context) { return Builder(builder: (context) { return Container( child: Image(image: AssetImage('assets/images/splash.png'), fit: BoxFit.fill,), ); }); } } 复制代码
生命周期以下:
图片转载自segmentfault.com/a/119000001…
具体 Splash 页面讲解参考个人博客:Flutter 开发 Android & IOS 启动页 splash page
主页面主要是对文章进行展现以及相关设置项。
点击左上角能够弹出相关配置弹窗。
考虑到布局的复杂度,这里能够将底部弹窗抽离出单独写进一个 .dart
文件。
从这部分就涉及到各个控件的使用和状态设置,点击事件等内容。
这部分基本就是程序的核心内容了。
完成了该部分以后就是对程序进行优化,添加数据库来缓存数据,日期判断切换,文章收藏等。
这个部分是耗时最长的,也是从磕磕碰碰到逐渐熟练的过程。
最后就是国际化,添加资源和打包等一些杂项了,具体参见
从刚开始看 dart 语法,到这个项目开发完成。断断续续一共持续了三周的时间。天天抽出一到两个小时,合计一共是 56 小时左右。减去画 APP 图标,启动页面图片的两个小时,勉强算得上八小时工做制的一周。
这一周的使用过程当中,Flutter 有些特性让人感受相见恨晚:语法特性(类型动态检查,支持 .?
??
操做符)、简单方便完备的 UI 方案、Hot Reload等。可是诸如复杂冗长的 view tree、资源的硬编码、糟糕的 UI 控件 API 等又让人头痛不已。
在初步使用 Flutter 以后,我发觉彷佛 Flutter 短期内并不能让我不学习原生开发就直接使用 Flutter 解决移动客户端开发。
在不断的使(zhe)用(teng)过程当中,发现碰到好多问题仍是须要你必须用原生开发的知识去解决相应的问题。 好比项目里面获取已收藏文章,是这样从数据库里面获取文件的:
Future<List<ArticleBean>> getStarred() async { List<ArticleBean> articles = List(); Database db = await getDB(); List<Map<String, dynamic>> maps = await db.query(name, columns: [columnId, columnStarred, columnDate, columnData], where: "$columnStarred = ?", whereArgs: [true]); if (maps.length > 0) { for (Map<String, dynamic> map in maps) { ArticleBean article = ArticleBean.fromJson(map); articles.add(article); } } return articles; } 复制代码
请看核心查询代码
await db.query(name, columns: [columnId, columnStarred, columnDate, columnData], where: "$columnStarred = ?", whereArgs: [true]); 复制代码
这里就是获取全部 starred 为 true 的列。
可是实际运行的时候,发如今 Android 设备上面老是获取不到。
Android 数据库使用的是 Sqlite,不能存储 bool(boolean)。相反,布尔值被存储为整数 0(false)和 1(true)。
故上述代码要改为下面的代码才生效。
await db.query(name, columns: [columnId, columnStarred, columnDate, columnData], where: "$columnStarred > ?", whereArgs: [0]); 复制代码
这只是一个很小的简单例子,可是也说明了在 Flutter 上面并不能老是帮你解决原生的一些坑(这其实取决于各个框架的开发者为你作了多少兼容处理)。
本文到这里就要结束了,不怎么涉及具体代码,只是一周时间的 Flutter 简单上手。若是你们对项目有兴趣,欢迎你们 star、fork 以及提交 PR,谢谢你们。