还在写iOS?是时候学一下Flutter了

文章概述

本人之前主要从事iOS开发工作,刚好Flutter文档中有一篇Flutter for iOS developers的文档,之前两篇文章,我们大致上体验了Flutter,这篇文中我将从iOS开发者的角度来学习Flutter,与官方文档不同的是,这篇文章会更注重实践。由于文档很长,我将用两篇文章讲解。这是第一篇。通过阅读本篇文章,你讲学习到如下内容:

  • Widget与UIView的区别。
  • 导航,如何在页面间跳转

Widget与UIView

对于我们iOS开发者来讲,UIView再熟悉不过,它是我们构建界面的必备元素。而在Flutter中,我们可以将Widget看做是UIView,但它与UIView并不是完全等价的。

对于Widget而言,它是不可变的,当Widget所描述的界面需要改变的时候,Flutter是重新构建一个Widget实现的。对于UIView而言,界面改变的时候并不是去重新绘制(除非调用setNeedsDisplay()方法),而是属性的改变。

更确切的说,Widget更轻量级,因为它是不可变的。它只是UI的描述,是对下层真实视图对象的描述,而不是视图本身,也不会去绘制任何东西。

Flutter包含 Material Components组件库。这是一个遵循 Material Design guidelines 规范实现的控件,这是一个非常灵活的设计系统,并针对所有的系统进行了优化,包含iOS系统。

我们可以使用 Cupertino widgets 组件来实现遵循 Apple’s iOS design language 的界面。

如何更新Widgets

Flutter中更新widgets需要去操作它的state,不向UIView一样,直接修改对象的属性即可。Flutter中包含有状态Widgets和无状态Widgets,分别用StatefulWidgetStatelessWidget 表示。

举例来说:如果你只需要展示一个图标,并且它不会被改变,这时使用StatelessWidget 即可完成,但如果你需要根据网络请求返回的结果来动态的设置图片就需要使用StatefulWidget来完成了。

StatefulWidgetStatelessWidget的最大区别是,StatefulWidget拥有一个存储状态数据的State对象,并且在整个Widget Tree构建的过程中一直携带者它,永不丢失。

有一个简单的记法:如果一个Widget在它的build方法之外改变,它就是有状态的,如果在第一次构建之后永不改变,它就是无状态的。一个有状态的Widget的父控件可以是无状态的,只要父控件不受子控件状态的影响即可。如Text就是一个无状态的Widget组件。

// class Text extends StatelessWidget
Text(
  'I like Flutter!',
  style: TextStyle(fontWeight: FontWeight.bold),
);

不难发现Text没有携带任何状态信息,只有通过构造函数传递的信息。

如果要实现通过点击事件来改变Text的文本信息,需要通过将Text用StatefulWidget包裹一下来实现,

代码如下:

flutter布局.png

效果如下:

改变文本内容.gif

如何对Widget布局

In iOS, you might use a Storyboard file to organize your views and set constraints, or you might set your constraints programmatically in your view controllers. In Flutter, declare your layout in code by composing a widget tree.

The following example shows how to display a simple widget with padding:

在编写iOS代码的时候,你可以用Storyboard来构建视图和设置约束,或者在viewContoller中编写约束代码。在Flutter中,我们将布局代码写在Widget树种。

下面的例子展示了一个使用padding的Widget:

flutter布局.png

代码效果如下:

![布局效果图.jpg](https://upload-images.jianshu.io/upload_images/691666-99f93d3e3e89960e.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

你可以对任何一个Widget使用padding属性,它模拟了iOS中的约束功能。

widget layout这篇文章详细介绍了Flutter所提供的布局功能。

如何从布局中添加或者删除一个组件

在iOS中,我们可以调用父视图的addSubview() 方法为父视图添加可以子视图,或者调用子视图的removeFromSuperview()方法将自身从其父视图中移除,通过以上两个方法可以动态的添加或者移除子视图。在Flutter中,由于widget是不可变的,没有与addSubvie()等价的功能函数。在flutter中可以使用一个bool型变量来控制子视图是否需要创建。

来看下面的例子:通过一个toggle变量来控制子视图显示的内容:

更新子视图.png

效果如下:

变更子视图.gif

如何设置Widget 动画

在iOS中我们可以使用animate(withDuration:animations:)方法为一个view设置动画,在Flutter中需要使用第三方库来包装widget而不是使用具体动画属性的widge。

在Flutter中,使用AnimationController 它是Animation<double> 类型,可以控制一个动画的终止,执行,暂停和反转。它需要一个Ticker ,当垂直同步信号时产生在它执行的每一帧都产生一个0到1之间的线性插值。你可以创建一个或者多个动画绑定到这个controller上。

举个例子:

你可能使用CurvedAnimation依据插值曲线来完成一个动画,在这种场景下,controller是动画执行的"主人",CurvedAnimation计算用来计算的曲线会代替controller默认线性模式。

当构建widget树你将Animation赋值给一个widget的动画属性,比如,FadeTransition的不透明度,然后告诉controller开始执行动画。

下面的例子展示了如何写一个淡出动画,当点点击了按钮之后,logo会淡出显示。

动画.png

效果如下:

动画.gif

更多动画相关的资料可以参考 Animation & Motion widgets, 和 Animations tutorial, 还有 Animations overview

如何绘制到屏幕上

在iOS中,我们可以使用CoreGraphics可以将线条或者图形绘制到屏幕上。Flutter中拥有一套不同的Api,它基于Canvas这个类,并结合 CustomPaintCustomPainter 两个类可以帮你实现屏幕绘制需求,CustomPainter 实现了绘制画布的算法。

在Flutter中,实现画笔程序 可以参考Collin 在 StackOverflow 上的答案,源码在kitttn‘s github

Flutter画笔.png

\

效果如下:

画笔.gif

widget的透明度在哪

在iOS中每个组件都有.opacity 或者 .alpha 属性表示透明度。在Flutter中,要是先透明需要使用透明的widget包装一下widget才能实现。

如何实现自定义widget

在iOS中,我们可以继承UIView,或者使用已经存在的视图,通过重新和实现方法来实现期望的行为。在Flutter中,构造一个自定的widget需要将系统提供的widget组合在一起。

举个例子:如何自定义一个CustomButton, 它的构造方法中携带一个label?可以通过将RaisedButton和label结合在一起,如下代码:

自定义widget.png

导航

如何在多个页面之间跳转

在iOS中,多个viewController之间的转化可以通过UINavigationController来实现,它管理着一组viewController的显示。

Flutter中有类似的实现,使用NavigatorRouter来实现,一个Router是一个app中screen或者page的抽象,Navigator是一个widget,它管理着多个router。router近似于iOS中的UIViewController,navigator的工作机制和iOS中的UINavigationController一致。所以它可以使用push()pop()来将页面导航到某个视图或者返回到某个视图。

在页面之间跳转,你可以使用下面的几个方式:

  • 指定一个由router名称构成的map。
  • 直接跳转到一个路由
页面跳转.png

如何跳转到另一个app

在 iOS 中,要跳转到其他 App,你需要一个特定的 URL Scheme。对系统级别的 App 来说,这个 scheme 取决于 App。为了在 Flutter 中实现这个功能,你可以创建一个原生平台的整合层,或者使用现有的 plugin,例如 url_launcher

如何跳转到iOS原生的viewController

调用SystemNavigator.pop()方法相当于调用下面iOS代码:

UIViewController* viewController = [UIApplication sharedApplication].keyWindow.rootViewController;
  if ([viewController isKindOfClass:[UINavigationController class]]) {
    [((UINavigationController*)viewController) popViewControllerAnimated:NO];
  }

如果这样达不到你的期望,你可以写自己的跨平台方案来调用iOS代码。platform channel

小结

本文主要从iOS开发者的角度讲述了Flutter开发中的几个点,不知道你是否有所收获,本文还有第二篇文章,敬请期待。

本文主要参考Flutter官方文档Flutter中文网

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容