本人以前主要从事iOS开发工做,恰好Flutter文档中有一篇Flutter for iOS developers的文档,以前两篇文章,咱们大体上体验了Flutter,这篇文中我将从iOS开发者的角度来学习Flutter,与官方文档不一样的是,这篇文章会更注重实践。因为文档很长,我将用两篇文章讲解。这是第一篇。经过阅读本篇文章,你讲学习到以下内容:ios
对于咱们iOS开发者来说,UIView
再熟悉不过,它是咱们构建界面的必备元素。而在Flutter中,咱们能够将Widget
看作是UIView
,但它与UIView
并非彻底等价的。git
对于Widget而言,它是不可变的,当Widget所描述的界面须要改变的时候,Flutter是从新构建一个Widget实现的。对于UIView而言,界面改变的时候并非去从新绘制(除非调用setNeedsDisplay()方法),而是属性的改变。github
更确切的说,Widget更轻量级,由于它是不可变的。它只是UI的描述,是对下层真实视图对象的描述,而不是视图自己,也不会去绘制任何东西。objective-c
Flutter包含 Material Components组件库。这是一个遵循 Material Design guidelines 规范实现的控件,这是一个很是灵活的设计系统,并针对全部的系统进行了优化,包含iOS系统。算法
咱们可使用 Cupertino widgets 组件来实现遵循 Apple’s iOS design language 的界面。微信
Flutter中更新widgets须要去操做它的state,不向UIView同样,直接修改对象的属性便可。Flutter中包含有状态Widgets和无状态Widgets,分别用StatefulWidget
和 StatelessWidget
表示。网络
举例来讲:若是你只须要展现一个图标,而且它不会被改变,这时使用StatelessWidget
便可完成,但若是你须要根据网络请求返回的结果来动态的设置图片就须要使用StatefulWidget
来完成了。app
StatefulWidget
和 StatelessWidget
的最大区别是,StatefulWidget
拥有一个存储状态数据的State
对象,而且在整个Widget Tree构建的过程当中一直携带者它,永不丢失。less
有一个简单的记法:若是一个Widget在它的build
方法以外改变,它就是有状态的,若是在第一次构建以后永不改变,它就是无状态的。一个有状态的Widget的父控件能够是无状态的,只要父控件不受子控件状态的影响便可。如Text
就是一个无状态的Widget组件。ide
// class Text extends StatelessWidget
Text(
'I like Flutter!',
style: TextStyle(fontWeight: FontWeight.bold),
);
复制代码
不难发现Text没有携带任何状态信息,只有经过构造函数传递的信息。
若是要实现经过点击事件来改变Text的文本信息,须要经过将Text用StatefulWidget包裹一下来实现,
代码以下:
效果以下:
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:
代码效果以下:

你能够对任何一个Widget使用padding属性,它模拟了iOS中的约束功能。
widget layout这篇文章详细介绍了Flutter所提供的布局功能。
在iOS中,咱们能够调用父视图的addSubview()
方法为父视图添加能够子视图,或者调用子视图的removeFromSuperview()
方法将自身从其父视图中移除,经过以上两个方法能够动态的添加或者移除子视图。在Flutter中,因为widget是不可变的,没有与addSubvie()
等价的功能函数。在flutter中可使用一个bool型变量来控制子视图是否须要建立。
来看下面的例子:经过一个toggle变量来控制子视图显示的内容:
效果以下:
在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会淡出显示。
效果以下:
更多动画相关的资料能够参考 Animation & Motion widgets, 和 Animations tutorial, 还有 Animations overview。
在iOS中,咱们可使用CoreGraphics
能够将线条或者图形绘制到屏幕上。Flutter中拥有一套不一样的Api,它基于Canvas
这个类,并结合 CustomPaint
和 CustomPainter
两个类能够帮你实现屏幕绘制需求,CustomPainter
实现了绘制画布的算法。
在Flutter中,实现画笔程序 能够参考Collin 在 StackOverflow 上的答案,源码在kitttn‘s github
效果以下:
在iOS中每一个组件都有.opacity 或者 .alpha 属性表示透明度。在Flutter中,要是先透明须要使用透明的widget包装一下widget才能实现。
在iOS中,咱们能够继承UIView
,或者使用已经存在的视图,经过从新和实现方法来实现指望的行为。在Flutter中,构造一个自定的widget须要将系统提供的widget组合在一块儿。
举个例子:如何自定义一个CustomButton
, 它的构造方法中携带一个label?能够经过将RaisedButton
和label结合在一块儿,以下代码:
在iOS中,多个viewController之间的转化能够经过UINavigationController
来实现,它管理着一组viewController的显示。
Flutter中有相似的实现,使用Navigator
和Router
来实现,一个Router
是一个app中screen
或者page
的抽象,Navigator
是一个widget,它管理着多个router。router近似于iOS中的UIViewController,navigator的工做机制和iOS中的UINavigationController
一致。因此它可使用push()
和pop()
来将页面导航到某个视图或者返回到某个视图。
在页面之间跳转,你可使用下面的几个方式:
在 iOS 中,要跳转到其余 App,你须要一个特定的 URL Scheme。对系统级别的 App 来讲,这个 scheme 取决于 App。为了在 Flutter 中实现这个功能,你能够建立一个原平生台的整合层,或者使用现有的 plugin,例如 url_launcher。
调用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中文网。
因为排版缘由,文中我使用了图片的形式展现代码,若是你须要源码,能够关注个人公众号,回复关键字"flutter"获取相关代码。
本文首发自微信公众号【RiverLi】,欢迎你的关注与投稿。