工程结构
打开Android studio 创建一个flutter 项目,会默认创建一个计数器项目。在右边project 下,可以看到:
分析一下几个重要的文件目录和文件:
android:包含Android的特定文件和Android子工程
build:Android 和iOS 的构建产物
ios:包含iOS 的特定文件和iOS 子工程
lib:放置flutter 代码
main.dart:程序的入口文件,类似Android 的application
test:测试文件
flutter_app.iml:工程配置文件
pubspec.lock:记录当前项目实际依赖信息的文件
pubspec.yaml:管理第三方库和资源文件
之所以有Android 和iOS 子项目,是因为flutter 最终会以原生的形式运行。
从简单的demo学习flutter项目的运行机制
在flutter 的世界中,一切都是widget,widget 是组件视觉效果的封装,是 UI 界面的载体,通过 build方法来构建UI页面。 看看main.dart 文件中的代码
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
- 从main函数开始,调用
runApp方法 传入MyApp(就是一个widget),APP就是我们看到的首页。 - 在 MyApp的build 方法中,返回了 MaterialApp(也是一个widget),里面还有很多可配置的属性,比如应用主题、应用名称、语言标识符、组件路由等。
- 在 MaterialApp,看到 MyHomePage(也是一个widget),但是这个 StatefulWidget 的子类,构建UI不是直接通过build 方法,而是交给 _MyHomePageState来完成。
到这来就可以看到,在flutter 中有两种 widget,StatelessWidget 和 StatefulWidget。
StatelessWidget:无状态的widget,UI构建的从一开始就是确定的,在 widget 的生命周期中不会发生变化。
StatefulWidget:有状态的widget,在widget 的生命周期中数据发生变化,在数据发生变化后,调用 setState方法来通知flutter 框架,重新创建widget。
随着数据的变化重新创建和销毁widget,会不会对性能有影响呢,flutter 如何优化的?
答案是:不会。因为框架内部会通过一个中间层去收敛上层 UI 配置对底层真实渲染的改动,从而最大程度降低对真实渲染视图的修改,提高渲染效率,而不是上层 UI 配置变了就需要销毁整个渲染视图树重建。
总结
从上面可以看出,在flutter 的世界里,widget 是无处不在,在页面上看到的一切的一切都是widget,如:AppBar、Center、Text、FloatingActionButton……都是widget,我们可以在widget构建的时候,做好配置,如,Text 文字大小、文字颜色、文字内容、点击事件等等,然后在数据发生变化后,通过调用 setState方法,就可以更新UI了。