八天让iOS开发者上手Flutter!
Posted iOS大鑫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了八天让iOS开发者上手Flutter!相关的知识,希望对你有一定的参考价值。
flutter现在是越来越火了,现在作为一个ios开发,如果你不会flutter都好像不算个正常人似的?而且现在的flutter情况,有点像2012年那会儿刚刚兴起的iOS,android开发一样,会点皮毛UI就可以提升不少身价…这些年过来,有无数的前端跨平台框架兴起。却只有flutter一家独秀,说明它还是有两把刷子的。今天这篇文章内容是基于Mac和Android Studio基础来开发flutter的,如果你还没有配置好开发环境,可以在网上搜索,或者直接到官网安装。这篇文章主要用来记录我学习flutter的过程,如果你也对flutter感兴趣可以跟着一起练习。
配置好Flutter环境之后,开始创建我们的第一个Flutter工程
创建第一个Flutter工程
打开iTerm2,cd到~/AndroidStudioProjects目录,输入以下命令,没有iTerms的使用Mac系统自带的Terminal也行。
flutter create flutter_demo
这里需要注意,AndroidStudio项目名称不能使用大写字母,这里推荐使用小写字母加下划线给工程命名。
打开对应的目录,可以看到新建了一个flutter_demo
目录
接下来,cd到flutter_demo
目录,在终端输入flutter run
命令,它就会运行项目,如果你电脑连接了真机,就会自动运行到真机上,没有真机会去寻找模拟器并运行,模拟器也没有,就会打开一个Chrome网页运行项目(flutter项目目前可以运行在iOS,Android,web上)。我这里连上了iPhone真机,运行项目会报一个BUILD FAILED的错误:
原因是flutter_demo项目生成的iOS项目默认的bundle identifier咱们用不了,去iOS项目里面修改一下就好了
这里注意我们免费的开发者证书,在iPhone上最多安装3个开发中的APP,多了就安装不了,删掉之前的APP就好了,再次运行flutter run
可以看到这里给出了flutter运行的一些关键命令,Hot reload热重载,这个特性对我们开发UI时还是比原生的体验好不少的,它不用我们重新运行项目就能看到UI的一些改变。Hot restart热重启,意思不用退出APP,就直接重新运行了。此时真机上就打开了我们的第一个flutter工程的APP
HelloFlutter
上面是通过命令创建一个flutter项目,当然在实际开发过程我,我们一般不会这么操作。使用Android Studio来创建flutter项目。没有这个选项的同学,在Android Studio的插件里面选择flutter并安装就有了,如果提示还需要安装Dart就一块安装了,flutter使用的是Dart语言。iOS开发者没必要被这个新语言给吓到了,现代的语言基本都差不了太多,敲着敲着就熟悉了
点击后会出现以下界面,目前我们选择Flutter App就好了
下一个界面会让我们设置工程名称,工程位置,工程描述,工程组织,Android语言,iOS语言等等…我这里设置工程名称为hello_flutter,其他的默认选择就好了…也可以根据你自己的需要选择
点击Finish之后就可以看到完整的工程目录了,flutter工程的主入口,跟我们iOS项目一样有一个main.m文件,flutter的是main.dart文件,可以看到这个文件里面已经有不少初始的代码了,今天是我们第一次接触flutter项目,就不要这里的代码,全部删掉,我们从第一行代码开始自己敲出来
- 导入material.dart头文件(相当于iOS中UIKit)
- 写一个main()函数作为主入口
- 调用runAPP()函数
- Center类是用来布局的类,表示一个位置,child属性表示他有的子控件的意思。Text类就是我们文本类,有点儿我们iOS的UILabel的意思,Text类的第一个参数就是具体的文本,省略了参数名,第二个参数
textDirection
表示文本显示方向,我们习惯的从左至右就是TextDirection.ltr
,left to right。像一些阿拉伯语言,希伯来语的文字就是从右到左显示的,我这里试了一下hello world的方向并没有变化,可能还需要其他设置吧…
首先作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS开发公众号:编程大鑫,不管你是小白还是大牛都欢迎入驻 ,让我们一起进步,共同发展!(群内会免费提供一些群主收藏的免费学习书籍资料以及整理好的几百道面试题和答案文档!)
运行之后iPhone显示如下:
自定义Widget
flutter里面的Widget类叫作小部件,是flutter里面经常用到的,它分为有状态的Stateful和Stateless无状态的。其中无状态的比较简单,我们先自定义一个类CustomWidget继承自StatelessWidget。我们自定义的Widget想要显示到屏幕上需要实现一个build的函数,系统会调用这个函数来渲染我们想要显示到屏幕上的内容
这个时候,如何将我们的hello flutter显示到屏幕呢,可以看到runApp函数里面有一个Center类,我们CustomWidget类的build方法也是返回的一个Center类,所以可以直接将我们CustomWidget初始化给runApp作参数
有些时候,我们发现hot reload无法更新界面,可以使用hot restart,如果hot restart还是无法更新界面,那就需要重新运行一下就可以了。此时我们发现main()函数里面就只有一句调用runApp()代码,在Dart语言中,函数定义如果只有一句代码,那么可以省略成如下箭头形式
设置文字样式style
按住command再用鼠标左键点击Text类,就会跳到一个text.dart文件,会看到一个this.style属性,再次按住command点击,会来到style的声明部分:
这里的final表示不可变,常量的意思,类似于Swift里面的let。可以看到style是一个TextStyle类型,查看TextStyle类,会发现里面很多的属性,比如color,backgroundColor,fontSize,fontWeight…这些都是很熟悉的属性,接下来我们设置一下hello flutter的一些文字样式
使用Android Studio快捷键command + \\查看界面
Material App
在flutter提供的头文件material.dart中,提供了一个快速构建APP的类型MaterialApp,我们可以使用它来快速构建一个APP的基础框架。
我们先新建一个App类来写我们的代码
然后我们在App的build方法中,返回一个MaterialApp类,如果MaterialApp不传入任何参数的话,运行后会发现APP整个屏幕变成红色,并且显示了一行文字,意思是出错了之类的,说明我们的MaterialApp应该是需要传入一个必要的参数的。
没错就像我们iOS的APP同样需要一个rootViewController一样,MaterialApp函数需要一个home参数,home参数可以传一个Widget类,如果传入我们刚刚写的CustomWidget类,运行后发现有了一点不一样的地方
右上角有一个debug的图标,hello flutter下面也出现了两条横线。
flutter还提供了一个Scaffold的类,这个类翻译过来叫作脚手架,有点像是我们iOS中的一些基础控制器(比如UITabBarController,UINavigationController)的封装。我们来使用一下这个类,这个Scaffold类有一个appBar的属性,这个属性就跟我们的UINavigationController的UINavigationBar一样,appBar是一个AppBar类型,它的title属性可以传入一个Widget,我们传入一个Text类试试看。Scaffold类除了appBar属性,还有一个body属性表示的内容,把这个body设置为我们刚刚的CustomWidget,看看是什么效果,代码如下:
APP上显示效果:
这个时候,是不是发现像那么回事了
MaterialApp还有一个theme的属性,这个属性用了配置app的主题,设置一下主题颜色代码如下:
APP上显示效果:
初探ListView
在探索ListView之前,我们先把模型实现一下,我们这里展示的一组关于汽车的图片和名字,就定义一个Car类,我们新建一个car文件用来存放我们的模型代码,代码如下:
再定义一个数组,用来存放一组汽车模型,我这里放了一组网络图片,你可以直接使用,也可以自己在网上找几张图片,填入模型数组中
final List<Car> cars = [
Car(
name: '保时捷918 Spyder',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-7d8be6ebc4c7c95b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '兰博基尼Aventador',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-e3bfd824f30afaac?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '法拉利Enzo',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-a1d64cf5da2d9d99?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: 'Zenvo ST1',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-bf883b46690f93ce?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '迈凯伦F1',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-5a7b5550a19b8342?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '萨林S7',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-2e128d18144ad5b8?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '科尼赛克CCR',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-01ced8f6f95219ec?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '布加迪Chiron',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-7fc8359eb61adac0?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '轩尼诗Venom GT',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-d332bf510d61bbc2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '西贝尔Tuatara',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-3dd9a70b25ae6bc9?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
)
];
然后回到main.dart文件新建一个Home类,用来存放我们ListView相关代码,和Xcode一样Android Studio同样有代码块功能,直接输入stl就会出现提示,回车就会生成StatelessWidget类相关代码。我们将Scaffold相关的代码挪到Home中来。
接下来就是正式开始使用ListView了,ListView跟其他一般的类不太一样,它的初始化需要调用build方法,并且传入两个参数,一个是itemCount,一个是itemBuilder,有点类似我们UITableView的cellForRow方法,只不过我们UITableView使用的是代理的设计,而这里的ListView使用的代码块回调的设计。
这里说一个Android Studio的比Xcode好用的地方,如图的itemCount使用了cars.length但是提示cars报错,是因为没有导入car.dart文件,给了个小红灯泡。这个时候,我们光标移动到Car类上,然后使用option + 回车会弹出一个菜单,再按一次回车就可以导入我们的car.dart文件了
itemBuilder属性就是一个代码块,用来配置每个item的样式,我们可以先统一返回一个Text文本看看效果。
显示效果就是类似于tableView一样的一行行的文本
接下来介绍一个类似于UIView的容器类Container,它跟UIView类似,可以设置一些颜色,间距,子控件之类的,我们来试一下,将Text改为Container,child属性就是子控件的意思,再给child设置为Text,文本就是cars里面的name,代码如下:
再看一下显示效果
那么如果我们现在想要显示图片加文字的话应该怎么做呢?这里再介绍一个Column类,和前面介绍Center类类似,同样是属于布局的类,Column表示上下的布局,因为我们想把图片和文字上下摆放,所以需要用到Column这个类。然后关于图片的显示,这里我们先不讲怎么去网络请求,而是直接使用Image类提供的一个方法去加载网络图片,代码如图:
显示效果如图:
这个时候,你应该也猜到了,如果挪动children里面Text和Image和顺序,会发现图片和文字的顺序就交换了,是不是很容易理解。如果想要调整图片和文字之间的间距怎么调呢,使用SizedBox类,传一个height就可以调整间距了,也可以继续使用Container,代码如下:
如果觉得itemBuilder的代码太长,也可以将它的代码封装到一个方法里面,例如我这里使用iOS中的_cellForRow来命名这个方法。使用下划线的意义的是表示这是一个私有方法。
APP右上角会发现有一个debug图标,这个图标的显示在MaterialApp类里面有一个属性可以控制显示隐藏。 debugShowCheckedModeBanner: false
常用Widget介绍
在介绍常用Widget之前,我们想把刚刚写的ListView相关代码,封装到一个文件内,这样方便以后我们回头学习。listView_demo代码如下:
这个时候,main.dart文件内的Home类的build方法里,返回我们的ListViewDemo初始化方法就行了。
然后再新建一个新的base_widget文件,用来存放我们将要介绍的基础Widget代码。
可以在main.dart文件中直接使用我的BaseWidgetDemo初始化方法,这样我们就不需要再去main.dart文件修改代码了。每介绍一个新Widget直接修改BaseWidgetDemo的build方法返回值为我们的自定义类xxxDemo()就好了
第一个介绍是Text
Text
Text我们一开始讲过了,这里就再讲一点关于字符串相关的,如果需要拼接字符串可以使用 符 号 , 如 果 字 符 串 中 有 特 殊 符 号 , 那 就 使 用 符号,如果字符串中有特殊符号,那就使用 符号,如果字符串中有特殊符号,那就使用。其他Text常用的属性,跟我们iOS中都差不太多,需要注意的是Text的样式,是在style里面设置的。下面看一下APP显示的效果
RichText
RichText就是富文本,它的text属性可以传一个TextSpan的类,这个TextSpan类可以设置text文本,设置style样式,还可以设置children子控件,这样就可以无限加花样拼接各种字符串在一起,代码如下
APP上显示的效果:
Container,Row
Container是个容器,Row是个用于布局的类,跟Column,Center类似,根据代码查看一下APP的显示,就能大概明白意思了,代码如下:
APP显示如下:
总结
今天介绍了Flutter里面的许多的基础Widget,有用于布局的Center,Row,Column…有用于显示文本的Text,RichText,TextSpan…有列表展示ListView,有基础架构Scaffold,MaterialApp类,虽然东西有点多,但基本还没有什么难以理解的内容。
以上是关于八天让iOS开发者上手Flutter!的主要内容,如果未能解决你的问题,请参考以下文章