自谷歌开发者大会之后, 一直手痒想体验一下 Flutter, 发现并非 JS 那种需要 bridge 的反复造轮子的框架, 在 2016 年尝试使用 React-Native 开发 App 发现真的是很难用, 莫名红屏报错填坑无数, 这两年也一直寻找能否跨越 Bridge 的混合框架, Flutter 出现了~
为什么是 IOT - 因为最近一直在做类似项目包括文章 Demo 部分
文章中心思想 - 表明填坑过程 & 怎样快速上手
目标
实现高产出
一套代码搭建高性能 iOS&Android 客户端
尽量减少对 native 的依赖
DEMO
入门
官网是一定要看的, 认真敲几个例子百十来行代码应该就会明白 Flutter 框架大概是怎么 run 起来的, 剩下的就一步一步填坑, 这框架有引力, 害得我上厕所都在想这个布局怎么实现...
写在前 - 不要在乎学习成本...
Dart 语言
如果熟悉 Java 或者 JS 的话, 会从 Dart 身上看到这些语言的影子, 在这之前我都不知道 Dart 是干什么的.
看文章不如直接上手, 创建变量? var 一下肯定没问题, 但先要知道对象叫什么, 我是基本上一路猜一路写...
Flutter
一切皆 Widget 可以理解成 UI 组件都是 Widget 对象, 整合 Material 和 Cupertion Design 设计风格的控件, 比如 Button, 我就觉得 RaisedButton 好看, iOS 无需封装直接拿来用, 两平台保持高度一致性, 类似的控件还有很多, Demo 中会列举出常用的
用 RN 也可以? 还记得 AlertIOS 和 xxxIOS 么还指定平台简直垃圾到爆炸, RN 粉丝别喷我...
SDK 看什么? 以下几点需要留意
- 控件叫什么名字?
- TableView -> ListView
- CollectionView ->GridView
- Label -> Text
- TextField -> TextField
Button -> RaisedButton|| MaterialButton||FlatButton||CupertinoButton 随你用
如果想用 iOS 控件比如 switch, 直接设计风格 + 控件名, 如: CupertinoSwitch
- 控件怎么创建?
只需要关注 Text 实现就好, 外部是布局
- Container(
- margin: EdgeInsets.only(top: 20),
- alignment: AlignmentDirectional.center,
- child: Text(
- 'Shanghai',
- style: TextStyle(
- fontSize: 20, color: Colors.white, fontWeight: FontWeight.bold),
- ),
),
- 我怎么摆放到屏幕指定位置上?
和 Android 或者 web 相似, 一句话切豆腐
这两个布局说明怎样循环生成子控件 + 布局解释, 基本上列表都沿用于此
看到 presenter? 没错是 MVP 设计模式
- Container topView() {
- return Container(
- height: screenHeight * 0.33,
- color: Colors.blue,
- child: ListView(
- physics: new NeverScrollableScrollPhysics(),//Ban Scroll Gesture
- controller: scrollController, //Listener
- scrollDirection: Axis.horizontal,
- children: devicesList(),
- ));
- }
- List<Widget> devicesList() {
- _presenter.getDeviceList();
- List<Widget> cell = new List();
- for (var i = 0; i <_presenter.deviceList.length; ++i) {
- DeviceData device = _presenter.deviceList[i];
- cell.add(deviceCell(i, device));
- }
- return cell;
}
- 我的 Controller/Activity 在哪
StatefulWidget 有状态 - 常用可以管理子控件刷新
StatelessWidget 无状态 - 不需要管理子控件状态刷新
直接上代码, AndroidStudio 有语法糖, 直接 stful 即可快速生成, 无状态 stless
- class MineController extends StatefulWidget {
- @override
- _MineControllerState createState() => _MineControllerState();
- }
- class _MineControllerState extends State<MineController> {
- @override
- Widget build(BuildContext context) {
- return Scaffold( // 整个页面承载对象
- appBar: AppBar( // 导航样式
- backgroundColor: Colors.white,
- elevation: 0.0,// 阴影
- title: Text('Mine'), // 标题
- ),
- body: ListView(children: cellView()), // 主视图
- );
}
既想要无状态又想要有状态怎么办?
home 指向有状态 Widget 即可, 下面是比较完整的页面代码
- class HomeController extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- return MaterialApp(
- theme: ThemeData(primaryColor: Colors.white), home: HomeCtrl());
- }
- }
- class HomeCtrl extends StatefulWidget {
- @override
- _HomeCtrlState createState() => _HomeCtrlState();
- }
- class _HomeCtrlState extends State<HomeCtrl> {
- HomePresenter presenter = new HomePresenter();
- @override
- Widget build(BuildContext context) {
- return new Scaffold(
- drawer: Drawer(), // 抽屉, 直接创建就有
- appBar: AppBar(
- title: Text('Home'),
- backgroundColor: Colors.white,
- elevation: 1.0,
- actions: <Widget>[IconButton(icon: Icon(Icons.add), onPressed: () {})],
- ),
- body: Stack( //Stack 布局主要是可以在图片上面承载子控件
- children: <Widget>[
- Image.asset(
- 'static/home.jpeg',
- fit: BoxFit.fill,
- ),
- ListView.builder(
- padding: EdgeInsets.only(left: 20, right: 20),
- itemCount: 10,
- itemBuilder: itemView,
- ),
- ],
- ),
- );
}
Layout
没有 xib,storyboard 或 xml, 对于我码代码的习惯来说, 并不喜欢拖拖拽拽, coding 能解决的问题干嘛搞这么复杂, 何况你拖完就结束了? 不会的...
常用布局
Container 只能放一个子控件 (放 row/column 没问题啊 毕竟是一个对象)
Row 行 可以放多个子控件
Column 列 可以放多个子控件
Stack 可重叠, 举例: 在背景图片上面放控件
很复杂的布局也离不开以上几个 Layout, 基本上贯穿了整个项目
需要注意的是, 认真研究这四个控件的属性, 基本上满足大部分应用场景
DEMO 架构
细节不上了, 整体就是这样, 有点偏向 iOS
Http 推荐使用 dio https://github.com/flutterchina/dio
Websocket: 参考官网
设计参考
IOT 终端设备不能只当做工具来使用, 更偏向一台互联网设备
推荐使用使用字体类图标, Flutter 整合两个平台的文字图标, 基本可以覆盖大部分开发需求
统一的 Widget 可极大减少 iOS&Android 平台差异性
FAQ
这里提供一些常用设计控件速查
- 左侧抽屉叫什么?
Scaffold 里的属性 Scaffold 理解一张页面包括了 appBar(导航) 和 body(主页面)
- return new Scaffold(
- drawer: Drawer(),
);
- 如何实现 ListView iOS 滑动删除子控件效果?(我帮你们谷歌完了)
在布局 cell 最外层添加, showSnackBar 自带的 toastView iOS 看着效果很不错, 关键 Android 还用得上~
- child: Dismissible(
- key: Key('1'),
- background: Container(
- color: Colors.red,
- ),
- onDismissed: (d) {
- Scaffold.of(context).showSnackBar(new SnackBar(
- content: new Text("Remove Success"),
- ));
},)
- 底部 tabbar
Scaffold 属性, 记得 body: 要实现 bar 里面所有 controller
bottomNavigationBar
- 修改返回按钮样式返回无效?
是的, 也要手动实现返回 Navigator.of(context).pop();
- 轮播图
自己可以实现, ListView 横向之后, 添加监听 scrollController, 不然你看不到 offset, 自己实现一个轮播图的封装单独不大, 日后写一个组件 share 一下
写在后:
快速学习和实现怎么具体操作
推荐按照官网 demo 敲一边, 能理解一下这东西怎么来的.
文中 Demo 未实现的部分还有很多, 主要是纠结细节部分怎么实现, 更多的页面也就是重复 Coding 的过程, 以后有时间争取补完.
来源: https://juejin.im/post/5bf40deaf265da611639680d