看看历史
你想想一套代码,移动端、web
端、pc
端都搞定!这生产力!非常值得学习了。
2015年5月 Dart
开发者峰会上,亮相了基于Dart
语言的移动应用程序开发框架Sky
,后更名为 Flutter
。Dart
语言2011年诞生,起初的竞对目标是Js
,2016年谷歌的AdWords
、AdSense
和Fiber
项目团队开始把Dart
融入他们的前端应用开发。一项当时的内部报告表明,Dart
可以帮助他们提升25%
到100%
的前端开发效率。谷歌内部的Dart
代码量比去年增长了3.5
倍。
5月7日 , Google i/O
大会 官方宣布,Flutter 1.5
预览版来了,已支持移动、Web
、桌面和嵌入式设备,也意味着它正式成为了支持多平台的轻量级 UI 框架,对于开发者而言越来越友好!
看看架构
Flutter for Mobile
Flutter for web
动手鼓捣
一个最简单的Flutter应用程序,只需一个widget即可!
import 'package:flutter/material.dart';
void main() {
runApp(
new Center(
child: new Text(
'Hello, world!',
textDirection: TextDirection.ltr,
),
),
);
}
UIView
相当于 Flutter
中的什么?
在 iOS
中,构建 UI
的过程中将大量使用 view
对象。这些对象都是 UIView
的实例。它们可以用作容器来承载其他的 UIView
,最终构成你的界面布局。
在 Flutter
中,你可以粗略地认为 Widget
相当于 UIView
。Widget
和 iOS
中的控件并不完全等价,但当你试图去理解 Flutter
是如何工作的时候,你可以认为它们是“声明和构建 UI
的方法”。
然而,Widget
和 UIView
还是有些区别的。首先,Widgets
拥有不同的生存时间:它们一直存在且保持不变,直到当它们需要被改变。当 Widgets
和它们的状态被改变时,Flutter
会构建一颗新的 Widgets
树。作为对比,iOS
中的 views
在改变时并不会被重新创建。但是与其说 views
是可变的实例,不如说它们被绘制了一次,并且直到使用 setNeedsDisplay()
之后才会被重新绘制。
此外,不像 UIView
,由于不可变性,Flutter
的 widgets
非常轻量。这是因为它们本身并不是什么控件,也不会被直接绘制出什么,而只是 UI
的描述。
Flutter
包含了 Material
组件库。这些 widgets
遵循了 Material
设计规范。MD
是一个灵活的设计系统,并且为包括 iOS
在内的所有系统进行了优化。
Flutter
有一套丰富、强大的基础widget
,其中以下是很常用的:
StatelessWidget
是无状态的Widget
,当我们要展示的Widget
不需要改变显示内容的时候,使用StatelessWidget
即可;
StatefulWidget
是有状态的Widget
,当我们要展示的Widget
需要改变显示内容的时候,需要使用StatefulWidget
;StatefulWidget
的子类相当于存放了State
的配置信息。StatefulWidget
的界面显示效果由State
来控制展示。 当StatefulWidget
对应的界面数据变化后,调用setState()
方法,然后系统会运行buildContext()
就可以做到更新界面的效果。
Row、 Column
: 这些具有弹性空间的布局类Widget
可让您在水平(Row)
和垂直(Column)
方向上创建灵活的布局。其设计是基于web
开发中的Flexbox
布局模型。
Container
是一个容器Widget
;
Text
用于展示文字,相当于iOS
中的UILabel
;
Image
用于展示图片;
FlatButton
相当于iOS
中的UIButton
,用于处理交互事件,同时,Flutter
中可以使用GestureDetector
对Widget
进行包裹,也可以达到具备交互的效果的目的;
ListView
相当于iOS
中的UITableView
,用于展示列表内容。
ListTile
相当于iOS
中的UITableViewCell
。
import 'package:flutter/material.dart';
class MyAppBar extends StatelessWidget {
MyAppBar({this.title});
// Widget子类中的字段往往都会定义为"final"
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[500]),
// Row 是水平方向的线性布局(linear layout)
child: new Row(
//列表项的类型是 <Widget>
children: <Widget>[
new IconButton(
icon: new Icon(Icons.menu),
tooltip: 'Navigation menu',
onPressed: null, // null 会禁用 button
),
// Expanded expands its child to fill the available space.
new Expanded(
child: title,
),
new IconButton(
icon: new Icon(Icons.search),
tooltip: 'Search',
onPressed: null,
),
],
),
);
}
}
class MyScaffold extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Material 是UI呈现的“一张纸”
return new Material(
// Column is 垂直方向的线性布局.
child: new Column(
children: <Widget>[
new MyAppBar(
title: new Text(
'Example title',
style: Theme.of(context).primaryTextTheme.title,
),
),
new Expanded(
child: new Center(
child: new Text('Hello, world!'),
),
),
],
),
);
}
}
void main() {
runApp(new MaterialApp(
title: 'My app', // used by the OS task switcher
home: new MyScaffold(),
));
}