摘要:而在中,我们可以将看做是,但它与并不是完全等价的。中包含有状态和无状态,分别用和表示。在中,由于是不可变的,没有与等价的功能函数。在中,要是先透明需要使用透明的包装一下才能实现。近似于中的,的工作机制和中的一致。
文章概述
本人之前主要从事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 的界面。
Flutter中更新widgets需要去操作它的state,不向UIView一样,直接修改对象的属性即可。Flutter中包含有状态Widgets和无状态Widgets,分别用StatefulWidget和 StatelessWidget 表示。
举例来说:如果你只需要展示一个图标,并且它不会被改变,这时使用StatelessWidget 即可完成,但如果你需要根据网络请求返回的结果来动态的设置图片就需要使用StatefulWidget来完成了。
StatefulWidget和 StatelessWidget的最大区别是,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包裹一下来实现,
代码如下:
效果如下:
如何对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:
代码效果如下:
![布局效果图.jpg](https://test.demo-1s.com/images/2019/05/18/kqr78c99LPRXDpAz.jpg)
你可以对任何一个Widget使用padding属性,它模拟了iOS中的约束功能。
widget layout这篇文章详细介绍了Flutter所提供的布局功能。
如何从布局中添加或者删除一个组件
在iOS中,我们可以调用父视图的addSubview() 方法为父视图添加可以子视图,或者调用子视图的removeFromSuperview()方法将自身从其父视图中移除,通过以上两个方法可以动态的添加或者移除子视图。在Flutter中,由于widget是不可变的,没有与addSubvie()等价的功能函数。在flutter中可以使用一个bool型变量来控制子视图是否需要创建。
来看下面的例子:通过一个toggle变量来控制子视图显示的内容:
效果如下:
如何设置Widget 动画
在iOS中我们可以使用animate(withDuration:animations:)方法为一个view设置动画,在Flutter中需要使用第三方库来包装widget而不是使用具体动画属性的widge。
在Flutter中,使用AnimationController 它是Animation
举个例子:
你可能使用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
效果如下:
widget的透明度在哪
在iOS中每个组件都有.opacity 或者 .alpha 属性表示透明度。在Flutter中,要是先透明需要使用透明的widget包装一下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()来将页面导航到某个视图或者返回到某个视图。
在页面之间跳转,你可以使用下面的几个方式:
指定一个由router名称构成的map。
直接跳转到一个路由
在 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】,欢迎你的关注与投稿。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/7065.html
showImg(https://segmentfault.com/img/bVbw3tK?w=1240&h=827); 前端工程师这个岗位,真的是反人性的 我们来思考一个问题: 一个6年左右经验的前端工程师: 前面两年在用jQuery 期间一直在用React-native(一步一步踩坑过来的那种) 最近两年还在写微信小程序 下面一个2年经验的前端工程师: 并不会跨平台技术,他的两年工作都是Reac...
摘要:在舒伯的生涯阶段里有个确立阶段,岁岁。知识技术安卓程序员需要掌握编程语言应用框架开发工具等这些具体的知识和技术。技术能力与阅历对安卓程序员来讲,知识技术是一方面,是容易习得的,是较浅的层面。 大龄程序员的界定 老早网上有人说,安卓开发干不过30岁,后来又有人说干不过35岁,后来又有人说干不过...
阅读 682·2023-04-25 19:43
阅读 3855·2021-11-30 14:52
阅读 3729·2021-11-30 14:52
阅读 3795·2021-11-29 11:00
阅读 3745·2021-11-29 11:00
阅读 3812·2021-11-29 11:00
阅读 3528·2021-11-29 11:00
阅读 6009·2021-11-29 11:00