What is flutter ?
- Flutter是Google开发的一套全新的 mobile app SDK
- 开源UI框架
- 一套代码同时运行在Android和iOS系统
- 媲美原生应用的性能
- 基于Dart编程语言
- 目前已经发布了120个版本,最新1.4.1(2019/3/27)
Why flutter ?
在Flutter之前,就已经有许多跨平台UI框架:
- 基于WebView的cordova、AppCan
- 将web渲染成原生控件的weex、ReactNative
基于WebView框架的优点很明显,几乎可以完全继承现代Web开发的所有成果,Web开发人员,不需要太多的学习和迁移成本就可以开发一个App
但也有很关键的缺点:WebView的渲染效率和JavaScript执行性能太差;Android各个系统版本和设备厂商的定制。
为了解决WebView性能差的问题,以React Native为代表的一类框架将最终渲染工作交还给了系统;但是随着系统版本变化和API的变化,这些框架本身需要处理大量平台相关的逻辑,开发者也需处理不同平台的差异;有些特性只能在部分平台。
为了解决这些问题,flutter从头到尾重写一套跨平台的UI框架,包括UI控件、渲染逻辑甚至开发语言,只调用原生的图形渲染接口。
How ?
我们试着写个简单的demo。
开发环境
安装Android Studio,flutter, VsCode插件,模拟器
在Android Studio里创建flutter app:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Welcome to Flutter',
home: new Scaffold(
appBar: new AppBar(
title: new Text('Welcome to Flutter'),
),
body: new Center(
child: new RandomWords()
),
),
);
}
}这里MyApp继承了
StatelessWidget
,这是一个无状态组件, 无状态组件是不可变的, 这意味着它们的属性不能改变 - 所有的值都是最终的。相对的,还有Stateful widgets(有状态组件)。在Flutter中,大多数东西都是widget,包括对齐(alignment)、填充(padding)和布局(layout),
Scaffold 是 Material library 中提供的一个widget, 它提供了默认的导航栏、标题和包含主屏幕widget树的body属性。widget树可以很复杂。
添加一个 Stateful 组件
实现一个 stateful widget 至少需要两个类:
- 一个 StatefulWidget类。
- 一个 State类。 StatefulWidget类本身是不变的,但是 State类在widget生命周期中始终存在.
1
2
3
4
5
6
7
8
9
10
11
12
13
14import 'package:english_words/english_words.dart';
class RandomWords extends StatefulWidget {
createState() => new RandomWordsState();
}
class RandomWordsState extends State<RandomWords> {
Widget build(BuildContext context) {
final wordPair = new WordPair.random();
return new Text(wordPair.asPascalCase);
}
}1
child: new Text('Hello World') => child: new RandomWords()
添加一个无限滚动的list
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
30
31
32
33
34
35
36class RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[]; // _下划线开头,强制私有化
Widget build(BuildContext context) {
return new Scaffold (
appBar: new AppBar(
title: new Text('Startup Name Generator'),
),
body: _buildSuggestions(),
);
}
Widget _buildSuggestions() {
return new ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (context, i) {
if(i.isOdd) return new Divider();
final index = i ~/ 2;
if(index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
}
);
}
Widget _buildRow(WordPair pair) {
return new ListTile(
title: new Text(
pair.asPascalCase,
style: const TextStyle(fontSize: 18.0),
)
);
}
}1
2
3
4
5
6
7
8
9class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Startup Name Generator',
home: new RandomWords(),
);
}
}
添加交互
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
28class RandomWordsState extends State<RandomWords> {
...
final _saved = new Set<WordPair>();
...
Widget _buildRow(WordPair pair, String index) {
final isSaved = _saved.contains(pair);
return new ListTile(
title: new Text(
pair.asPascalCase + ':兴爷第' + index + '个小弟',
style: _biggerFont,
),
trailing: new Icon(
isSaved ? Icons.favorite : Icons.favorite_border,
color: isSaved ? Colors.red : null,
),
onTap: () {
setState(() {
if (isSaved) {
_saved.remove(pair);
} else {
_saved.add(pair);
}
});
},
);
}
}