flutter学习1

1.JIT以及AOT

JIT是just in time的缩写,表明即时编译,是指一边编译一边运行,Javascript和Python属于这一种类别;AOT则是需要经过提前编译,将其编译为机器码,典型代表是C/C++类语言。

2.开发环境安装

按照官网流程步骤进行安装,使用真机运行flutter的话如果想要体验热重载的话那么只需要在控制台下按下r键即可,终端下输入flutter run运行即可。

3.dart简介

1.dart是强类型语言,使用var关键字来定义变量,一旦变量被赋值,那么变量的类型就被确定了,后续不能进行修改。比如:

1
2
3
var str; // 说明没有什么默认赋值
str = 'hello world';
str = 1; // 报错

2.dynamic和Object:功能和var相似,都能够在赋值时进行类型推断,不同在于,赋值后可以改变其类型。而Object在dart里面是所有对象的基类,也就是说其它类型都是Object的子类,所以任何数据类型的数据都可以赋值给Object声明的对象,在表现上和dynamic类似。

1
2
3
dynamic t;
t = 'hello world';
t = 1000;

3.final和const

如果你不打算修改一个变量的话,那么使用final和const,final和const的区别在于,const变量是一个编译时常量,final变量则在使用的时候才被初始化。使用final和const修饰变量,变量类型可以省略。

4.函数

dart函数如果没有显示申明返回类型的话,那么返回类型将会是dynamic,函数返回值不具有类型推断功能。

1
2
3
4
5
6
7
8
9
10
typedef bool CALLBACK();

isNoble(int atom) {
return _noble[atom] != null;
}

void test(CALLBACK cb) {
print(cb());
}
test(isNoble);

箭头函数:单行函数

1
bool isNoble (int atomic) => _noble[atomic] != null;

函数作为参数传递:

1
2
3
4
5
// 注意这里的var cb
void exec(var cb) {
cb();
}
exec(() => print('xxx'));

可选参数,利用[]进行标记

1
2
3
4
5
6
7
8
9
String say(String from, String msg, [String device]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
return result;
}
say('i', 'am ok');
say('i', 'am ok', 'oneplus a5000');

flutter命名参数?

5.异步

典型的异步函数有返回Future和Stream这些东西的函数,Future和JavaScript中的Promise是非常相像的.

6.基本知识

  • 1.Flutter中main函数是整个应用程序的入口,main函数中会调用runApp方法,他的功能是启动Flutter应用,这个函数所接受的参数为一个Widget类型的参数,换言之,一个Flutter应用本身就是一个widget。一个widget的主要工作就是提供一个build方法来描述该怎么构建UI界面(一般就是通过组合方式)。home是Flutter应用的首页,同时也是一个widget。

  • 2.Stateful Widget和Stateless Widget的明显区别在于前者可以具有状态,而后者并不拥有。同时一个Stateful Widget至少由两个类组成:一个StatefulWidget类;一个State类。

7.路由

Route在Android里面对应一个Activity,在IOS中对应的是ViewController。当然,在Flutter中一个Route也是一个widget,只不过这个widget会通过路由操作呈现在UI上面,定义一个widget如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
class AboutMe extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scafford(
appBar: AppBar(
title: Text('我的'),
),
body: Center(
child: Text('这个人很懒,什么也没有留下')
)
);
}
}

定义好了一个Widget,那么怎么进行使用呢?答案就是利用Flutter提供的Navigator方法来实现路由操作,比如像下面这样的将路由push到路由栈的顶部:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Index extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scafford(
appBar: new AppBar(
title: new Text('首页')
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton(
child: Text('我的'),
textColor: Colors.blue,
onPressed: () {
Navigator.push(
context,
new MaterialPageRoute(builder: (context){
return new AboutMe();
})
);
}
)
]
)
)
);
}
}

关键点就是利用Navigator.push进行路由跳转,将一个widget路由页面通过MaterialPageRoute进行包装一下,MaterialPageRoute继承自PageRoute类,PageRoute类是一个抽象类,表示占有整个屏幕空间的一个模态路由页面,来自于Material组件库,实现与平台一致的动画效果;Navigator是Flutter提供的路由管理的widget,它通过一个栈来管理一个路由widget集合。下面是其暴露出了的两个常用的方法:

  • Future push(BuildContext context, Route route):将页面进行入栈
  • bool pop(BuildContext context):将页面出栈

8.命名路由

基本概念:给路由命名,之后便能直接通过路由名字打开一个新路由:

1.路由表表里面注册路由,到根widget里面进行注册routes,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'APP',
theme: new ThemeData(primarySwatch: Colors.blue),
home: new Index(),
routes: {
"About": (context) => AboutMe()
}
);
}
}

通过路由名字打开一个路由需要调用Navigator.pushNamed方法,如下所示:

1
2
3
4
5
6
7
8
Navigator.pushNamed(context, 'About');
/**
Navigator.push(context,
new MaterialPageRoute(builder: (context) {
return new AboutMe();
})
);
*/

9.在flutter中,最基础的组件类是Widget,其它所有组件都是继承自Widget的。组件又分为有状态组件和无状态组件。

10.main方法是dart语言的入口,runApp函数是flutter框架的入口。

11.实现一个有状态类至少需要两个类,分别是StatefulWidget类;一个State类,StatefulWidget类本身默认是不可变的,但是State类在Widget类中会始终存在。