8天让iOS开发者上手Flutter之一:快速入门Flutter

flutter如今是愈来愈火了,如今做为一个iOS开发,若是你不会flutter都好像不算个正常人似的?并且如今的flutter状况,有点像2012年那会儿刚刚兴起的iOS,Android开发同样,会点皮毛UI就能够提高很多身价...这些年过来,有无数的前端跨平台框架兴起。却只有flutter一家独秀,说明它仍是有两把刷子的。今天这篇文章内容是基于Mac和Android Studio基础来开发flutter的,若是你尚未配置好开发环境,能够在网上搜索,或者直接到官网安装。这篇文章主要用来记录我学习flutter的过程,若是你也对flutter感兴趣能够跟着一块儿练习。前端

配置好Flutter环境以后,开始建立咱们的第一个Flutter工程web

建立第一个Flutter工程

打开iTerm2,cd到~/AndroidStudioProjects目录,输入如下命令,没有iTerms的使用Mac系统自带的Terminal也行。
flutter create flutter_demo
这里须要注意,AndroidStudio项目名称不能使用大写字母,这里推荐使用小写字母加下划线给工程命名。 image.png 打开对应的目录,能够看到新建了一个flutter_demo目录 image.png
接下来,cd到flutter_demo目录,在终端输入flutter run命令,它就会运行项目,若是你电脑链接了真机,就会自动运行到真机上,没有真机会去寻找模拟器并运行,模拟器也没有,就会打开一个Chrome网页运行项目(flutter项目目前能够运行在iOS,Android,web上)。我这里连上了iPhone真机,运行项目会报一个BUILD FAILED的错误: image.png 缘由是flutter_demo项目生成的iOS项目默认的bundle identifier我们用不了,去iOS项目里面修改一下就行了 image.png 这里注意咱们免费的开发者证书,在iPhone上最多安装3个开发中的APP,多了就安装不了,删掉以前的APP就行了,再次运行flutter run image.png 能够看到这里给出了flutter运行的一些关键命令,Hot reload热重载,这个特性对咱们开发UI时仍是比原生的体验好很多的,它不用咱们从新运行项目就能看到UI的一些改变。Hot restart热重启,意思不用退出APP,就直接从新运行了。此时真机上就打开了咱们的第一个flutter工程的APP数组

HelloFlutter

上面是经过命令建立一个flutter项目,固然在实际开发过程我,咱们通常不会这么操做。使用Android Studio来建立flutter项目。没有这个选项的同窗,在Android Studio的插件里面选择flutter并安装就有了,若是提示还须要安装Dart就一块安装了,flutter使用的是Dart语言。iOS开发者不必被这个新语言给吓到了,现代的语言基本都差不了太多,敲着敲着就熟悉了 image.png 点击后会出现如下界面,目前咱们选择Flutter App就行了 image.png 下一个界面会让咱们设置工程名称,工程位置,工程描述,工程组织,Android语言,iOS语言等等...我这里设置工程名称为hello_flutter,其余的默认选择就行了...也能够根据你本身的须要选择 image.png 点击Finish以后就能够看到完整的工程目录了,flutter工程的主入口,跟咱们iOS项目同样有一个main.m文件,flutter的是main.dart文件,能够看到这个文件里面已经有很多初始的代码了,今天是咱们第一次接触flutter项目,就不要这里的代码,所有删掉,咱们从第一行代码开始本身敲出来 image.pngmarkdown

image.png

  • 导入material.dart头文件(至关于iOS中UIKit)
  • 写一个main()函数做为主入口
  • 调用runAPP()函数
  • Center类是用来布局的类,表示一个位置,child属性表示他有的子控件的意思。Text类就是咱们文本类,有点儿咱们iOS的UILabel的意思,Text类的第一个参数就是具体的文本,省略了参数名,第二个参数textDirection表示文本显示方向,咱们习惯的从左至右就是TextDirection.ltr,left to right。像一些阿拉伯语言,希伯来语的文字就是从右到左显示的,我这里试了一下hello world的方向并无变化,可能还须要其余设置吧...

运行以后iPhone显示以下:网络

自定义Widget

flutter里面的Widget类叫做小部件,是flutter里面常常用到的,它分为有状态的Stateful和Stateless无状态的。其中无状态的比较简单,咱们先自定义一个类CustomWidget继承自StatelessWidget。咱们自定义的Widget想要显示到屏幕上须要实现一个build的函数,系统会调用这个函数来渲染咱们想要显示到屏幕上的内容 image.png 这个时候,如何将咱们的hello flutter显示到屏幕呢,能够看到runApp函数里面有一个Center类,咱们CustomWidget类的build方法也是返回的一个Center类,因此能够直接将咱们CustomWidget初始化给runApp做参数 image.png 有些时候,咱们发现hot reload没法更新界面,可使用hot restart,若是hot restart仍是没法更新界面,那就须要从新运行一下就能够了。此时咱们发现main()函数里面就只有一句调用runApp()代码,在Dart语言中,函数定义若是只有一句代码,那么能够省略成以下箭头形式 image.png架构

设置文字样式style

按住command再用鼠标左键点击Text类,就会跳到一个text.dart文件,会看到一个this.style属性,再次按住command点击,会来到style的声明部分: image.png 这里的final表示不可变,常量的意思,相似于Swift里面的let。能够看到style是一个TextStyle类型,查看TextStyle类,会发现里面不少的属性,好比color,backgroundColor,fontSize,fontWeight...这些都是很熟悉的属性,接下来咱们设置一下hello flutter的一些文字样式 image.png 使用Android Studio快捷键command + \查看界面app

Material App

在flutter提供的头文件material.dart中,提供了一个快速构建APP的类型MaterialApp,咱们可使用它来快速构建一个APP的基础框架。
咱们先新建一个App类来写咱们的代码 image.png
而后咱们在App的build方法中,返回一个MaterialApp类,若是MaterialApp不传入任何参数的话,运行后会发现APP整个屏幕变成红色,而且显示了一行文字,意思是出错了之类的,说明咱们的MaterialApp应该是须要传入一个必要的参数的。 image.png 没错就像咱们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,看看是什么效果,代码以下: image.png APP上显示效果:less

这个时候,是否是发现像那么回事了

MaterialApp还有一个theme的属性,这个属性用了配置app的主题,设置一下主题颜色代码以下: image.png APP上显示效果:ide

初探ListView

在探索ListView以前,咱们先把模型实现一下,咱们这里展现的一组关于汽车的图片和名字,就定义一个Car类,咱们新建一个car文件用来存放咱们的模型代码,代码以下: image.png

再定义一个数组,用来存放一组汽车模型,我这里放了一组网络图片,你能够直接使用,也能够本身在网上找几张图片,填入模型数组中

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中来。 image.png

接下来就是正式开始使用ListView了,ListView跟其余通常的类不太同样,它的初始化须要调用build方法,而且传入两个参数,一个是itemCount,一个是itemBuilder,有点相似咱们UITableView的cellForRow方法,只不过咱们UITableView使用的是代理的设计,而这里的ListView使用的代码块回调的设计。

这里说一个Android Studio的比Xcode好用的地方,如图的itemCount使用了cars.length可是提示cars报错,是由于没有导入car.dart文件,给了个小红灯泡。这个时候,咱们光标移动到Car类上,而后使用option + 回车会弹出一个菜单,再按一次回车就能够导入咱们的car.dart文件了 image.png

itemBuilder属性就是一个代码块,用来配置每一个item的样式,咱们能够先统一返回一个Text文本看看效果。 image.png 显示效果就是相似于tableView同样的一行行的文本

接下来介绍一个相似于UIView的容器类Container,它跟UIView相似,能够设置一些颜色,间距,子控件之类的,咱们来试一下,将Text改成Container,child属性就是子控件的意思,再给child设置为Text,文本就是cars里面的name,代码以下: image.png 再看一下显示效果

那么若是咱们如今想要显示图片加文字的话应该怎么作呢?这里再介绍一个Column类,和前面介绍Center类相似,一样是属于布局的类,Column表示上下的布局,由于咱们想把图片和文字上下摆放,因此须要用到Column这个类。而后关于图片的显示,这里咱们先不讲怎么去网络请求,而是直接使用Image类提供的一个方法去加载网络图片,代码如图: image.png 显示效果如图:

这个时候,你应该也猜到了,若是挪动children里面Text和Image和顺序,会发现图片和文字的顺序就交换了,是否是很容易理解。若是想要调整图片和文字之间的间距怎么调呢,使用SizedBox类,传一个height就能够调整间距了,也能够继续使用Container,代码以下: image.png

若是以为itemBuilder的代码太长,也能够将它的代码封装到一个方法里面,例如我这里使用iOS中的_cellForRow来命名这个方法。使用下划线的意义的是表示这是一个私有方法。 image.png

APP右上角会发现有一个debug图标,这个图标的显示在MaterialApp类里面有一个属性能够控制显示隐藏。 debugShowCheckedModeBanner: false

经常使用Widget介绍

在介绍经常使用Widget以前,咱们想把刚刚写的ListView相关代码,封装到一个文件内,这样方便之后咱们回头学习。listView_demo代码以下: image.png 这个时候,main.dart文件内的Home类的build方法里,返回咱们的ListViewDemo初始化方法就好了。

而后再新建一个新的base_widget文件,用来存放咱们将要介绍的基础Widget代码。 image.png 能够在main.dart文件中直接使用个人BaseWidgetDemo初始化方法,这样咱们就不须要再去main.dart文件修改代码了。每介绍一个新Widget直接修改BaseWidgetDemo的build方法返回值为咱们的自定义类xxxDemo()就行了 image.png

第一个介绍是Text

Text

image.png Text咱们一开始讲过了,这里就再讲一点关于字符串相关的,若是须要拼接字符串可使用$符号,若是字符串中有特殊符号,那就使用${}。其余Text经常使用的属性,跟咱们iOS中都差不太多,须要注意的是Text的样式,是在style里面设置的。下面看一下APP显示的效果

RichText

RichText就是富文本,它的text属性能够传一个TextSpan的类,这个TextSpan类能够设置text文本,设置style样式,还能够设置children子控件,这样就能够无限加花样拼接各类字符串在一块儿,代码以下 image.png APP上显示的效果:

Container,Row

Container是个容器,Row是个用于布局的类,跟Column,Center相似,根据代码查看一下APP的显示,就能大概明白意思了,代码以下: image.png APP显示以下:

总结

今天介绍了Flutter里面的许多的基础Widget,有用于布局的Center,Row,Column...有用于显示文本的Text,RichText,TextSpan...有列表展现ListView,有基础架构Scaffold,MaterialApp类,虽然东西有点多,但基本尚未什么难以理解的内容