First POST build by Jekyll. github:https://github.com/nishibaiyang
Flutter快速开始
用处
- 快速开发
- 富有表现力和灵活的UI
- 原生性能
开始
Dart
- 在 Dart 2 里,创建对象时可以省略 new 关键字,也推荐省略 new。
- 基本类型
- 函数
- 类
基本类型
跟常用的其他语言不同,Dart 没有 byte、char 和 float,int、double 都是 64 位。final 跟 Java 里的 final 一样,表示一个运行时常量(在程序运行的时候赋值,赋值后值不再改变)。const 表示一个编译时常量,在程序编译的时候它的值就确定了。
类型推断
var isShow = true;
var num = 2;
var a = 3.14;
final isVisible = false;
final count = 1000;
const sum = 42;
Dart 里所有的东西都是对象,包括 int、函数。所有这些对象的父类就是 Object。
函数
int foo(int x){
return 0;
}
Dart 也支持可选参数和默认参数:
void main() {
print(foo(2));
print(foo(1, 2));
}
int foo(int x, [int y]) {
// 是的,int 也可以是 null
if (y != null) {
return x + y;
}
return x;
}
int foo2(int x, [int y = 0]) {
return x + y;
}
类
定义一个类
class Point2D {
static const someConst = 2;
int x;
// 成员变量也可以是 final 的
final int y;
Point2D(int x, int y) {
this.x = x;
this.y = y;
}
}
Dart 具有垃圾收集功能,对象的使用跟 Java 里几乎是一样的。Dart 使用 package 的概念来管理源码和可见性。它没有 public、private 之类的访问权限控制符,默认情况下,所有的符号都是公开的。如果我们不想某个变量对包的外部可见,可以使用下划线开头来给变量命名。
继承,dart是单继承,具有如下特点
- 先执行子类 initializer list,但只初始化自己的成员变量
- 初始化父类的成员变量
- 执行父类构造函数的函数体
- 执行子类构造函数的函数体 基于这个初始化顺序,推荐是把 super() 放在 initializer list 的最后。
Flutter
Everything is Widget,组合大于继承
栗子 hello world
import 'package:flutter/material.dart';
class MyAppBar extends StatelessWidget{
MyAppBar({this.title});//
final Widget title;
@override
Widget build(BuildContext context){
return new Container(
height: 56.0,
padding: const EdgeInsets.symmetric(horizontal:8.0),
decoration: new BoxDecoration(
color:Colors.blue[400]
),
child: Row(
children: <Widget>[
new IconButton(
icon:new Icon(Icons.menu),
tooltip:'Navigation menu',
onPressed: (){
print('点击Menu');
},
),
new Expanded(
child:new Center(
child:title
)
),
new IconButton(
icon:Icon(Icons.search),
tooltip:'Search',
onPressed: (){
print('点击搜索按钮');
},
)
],
),
);
}
}
class MyScaffold extends StatelessWidget{
@override
Widget build(BuildContext context){
return Material(
child: new Column(
children:<Widget>[
new MyAppBar(
title:new Text(
'Hello World',
style:Theme.of(context).primaryTextTheme.title
),
),
new Expanded(
child:new Center(
child:Text('Hello World!!!')
)
)
]
),
);
}
}
void main(){
runApp(
new MaterialApp(
title:'My app',
home:new MyScaffold()
)
);
}
- 一切都是Widget,且Widget前面的new可有可无。
- 类MyAppBar和MyScaffold中使用了Container、Row、Column、Text、IconButton、Icon、BoxDecoration、Center、Expanded等常用Widget
- Container一个拥有绘制、定位、调整大小的 widget。类似于div,我们可以用它来创建矩形视图,container 可以装饰为一个BoxDecoration, 如 background、一个边框、或者一个阴影。 Container 也可以具有边距(margins)、填充(padding)和应用于其大小的约束(constraints)。另外, Container可以使用矩阵在三维空间中对其进行变换。
- Row、Column其实就是flex布局中的flex-direction
- Expanded它会填充尚未被其他子项占用的的剩余可用空间。Expanded可以拥有多个children。然后使用flex参数来确定他们占用剩余空间的比例。更多细节可以参看:flutter控件Flexible和 Expanded的区别
- 先定义了一个MyAppBar的类,构造函数中接受一个Widget的title,其实我们也可以接受String title然后在类中自己去new Title(title)
- widget的主要工作是实现一个build函数,用以构建自身。一个widget通常由一些较低级别widget组成。Flutter框架将依次构建这些widget,直到构建到最底层的子widget时,这些最低层的widget通常为RenderObject,它会计算并描述widget的几何形状。
- Stateless widgets 是不可变的,这意味着它们的属性不能改变——所有的值都是 final
- Stateful widgets 持有的状态可能在 widget 生命周期中发生变化,实现一个 stateful widget 至少需要两个类:1)一个 StatefulWidget 类;2)一个 State 类,StatefulWidget 类本身是不变的,但是 State 类在 widget 生命周期中始终存在
- 如果需要变化需要重新创建。StatefulWidget可以保存自己的状态。那问题是既然widget都是immutable的,怎么保存状态?其实Flutter是通过引入了State来保存状态。当State的状态改变时,能重新构建本节点以及孩子的Widget树来进行UI变化。注意:如果需要主动改变State的状态,需要通过setState()方法进行触发,单纯改变数据是不会引发UI改变的。
蛋疼
- 代码结构
- 熟悉widget