Window搭建环境
下载并且安装Git
git clone https://github.com/flutter/flutter.git
环境变量path添加Flutter的路径,比如:
C:\[你的Flutter路径]\flutter\bin
然后在当前目录执行:
flutter doctor
Android Studio 下载
[https://www.androiddevtools.cn/](https://www.androiddevtools.cn/)
Android SDK
https://www.androiddevtools.cn
然后 Android Studio 里面下载和安装 Flutter 插件和 Dart 插件。插件安装完后,Android Studio 重启就可以创建 Flutter 项目了。
File -> New -> new Flutter Project -> Flutter Application...
也可以用命令形式创建
flutter create xxx
然后导入即可。
项目创建完后,如执行成功就代表搭建环境没问题。
接下来,就可以学习下 main.dart 。
从后缀名也可以发现,Flutter 使用的是 Dart 语言开发的。Dart 语言和 Kotlin 类似,不过 Dart 即支持 JIT(动态编译)和 AOT(静态编译)。
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
new Text(
'You have pushed the button this many times:',
),
new Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: new Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
从 mart.dart 可以发现,Flutter 不再需要写 xml 布局。只是使用 提供的 Widget 控件嵌入式布局。
main函数
同时,在 mart.dart 提供了一个 main 函数。我们知道,Dart 是一种单进程的语言,而这种单进程机制叫 isolate。其中,这个 main 函数就是一个 isolate ,它主要是通过一个 event loop(事件循环)机制来渲染 UI 。这里面我们一般不放耗时的操作。
StatelessWidget
说到 StatelessWidget ,就要和 StatefulWidget 进行比较。
StatelessWidget 初始化之后就无法改变,如果想改变,那便需要重新创建,new 另一个 StatelessWidget 进行替换。因为 StatelessWidget 因为是静态的,他没有办法重新创建自己。所以 StatefulWidget 便提供了这样的机制,通过调用 setState((){}) 标记自身为 dirty 状态,以等待下一次系统的重绘检查。
在 State 类中的调用 setState((){}) 更新视图,将会触发 State.build ! 也将间接的触发其每个子 Widget 的构造方法以及 build 方法。
这就是为什么 Flutter 创建的项目根目录是 StatelessWidget 的原因
总之:
- 优先使用 StatelessWidget
- 含有大量子 Widget(如根布局、次根布局)慎用 StatefulWidget,尽量在叶子节点使用 StatefulWidget
- 将会调用到 setState((){}) 的代码尽可能的和要更新的视图封装在一个尽可能小的模块里。
- 如果一个 Widget 需要 rebuild,那么它的子节点、兄弟节点、兄弟节点的子节点应该尽可能少
- 相较 Android 的 View,Flutter Widget 的构造方法和 build 方法可能被会执行很多次,做的事情应该尽可能的少。
BuildContext
构建Widget中的应用上下文
BuildContext 只出现在两个地方:
- 创建 StatelessWidget 的 build 方法里面
- State 对象中:一个是创建 StatefulWidget 的 State 对象的 build 方法中,另一个是State 的成员变量
BuildContext 实际是 Element , BuildContext 是为了阻止直接对 Element 操作而抽象出来的,所以 BuildContext 是 Element 的抽象类,所有 Element 都继承自BuildContext。 每一个 Widget 都有一个 BuildContext 。 BuildContext 是 Widget 在Widget 树中位置的句柄。
MaterialApp
这里说下它的属性吧
- title : 在任务管理窗口中所显示的应用名字
- theme : 应用各种 UI 所使用的主题颜色
- color : 应用的主要颜色值(primary color),也就是安卓任务管理窗口中所显示的应用颜色
- home : 应用默认所显示的界面 Widget
- routes : 应用的顶级导航表格,这个是多页面应用用来控制页面跳转的,类似于网页的网址
- initialRoute :第一个显示的路由名字,默认值为 Window.defaultRouteName
- onGenerateRoute : 生成路由的回调函数,当导航的命名路由的时候,会使用这个来生成界面
- onLocaleChanged : 当系统修改语言的时候,会触发å这个回调
- navigatorObservers : 应用 Navigator 的监听器
- debugShowMaterialGrid : 是否显示 纸墨设计 基础布局网格,用来调试 UI 的工具
- showPerformanceOverlay : 显示性能标签,https://flutter.io/debugging/#performanceoverlay
- checkerboardRasterCacheImages 、showSemanticsDebugger、debugShowCheckedModeBanner 各种调试开关
primaryColor和primarySwatch有什么区别?
primarySwatch 不能设置为白色,primarySwatch是一个组合颜色MaterialColor,而primaryColor是一种颜色,比如
static const MaterialColor deepPurple = MaterialColor(
_deepPurplePrimaryValue,
{
50: Color(0xFFEDE7F6),
100: Color(0xFFD1C4E9),
200: Color(0xFFB39DDB),
300: Color(0xFF9575CD),
400: Color(0xFF7E57C2),
500: Color(_deepPurplePrimaryValue),
600: Color(0xFF5E35B1),
700: Color(0xFF512DA8),
800: Color(0xFF4527A0),
900: Color(0xFF311B92),
},
);
theme: ThemeData(
primarySwatch: deepPurple,
primaryColor: Colors.deepPurple[800]
),
定义一组颜色,然后就可以进行引用。
Scaffold
在 State 里面的 build 方法里面有 Scaffold 控件,这块主要是用来布局的作用。它具有下面这些属性:
appBar:显示在界面顶部的一个 AppBar,也就是 Android 中的 ActionBar 、Toolbar
body:当前界面所显示的主要内容 Widget
floatingActionButton:纸墨设计中所定义的 FAB,界面的主要功能按钮
persistentFooterButtons:固定在下方显示的按钮,比如对话框下方的确定、取消按钮
drawer:侧边栏控件
backgroundColor: 内容的背景颜色,默认使用的是
ThemeData.scaffoldBackgroundColor 的值
bottomNavigationBar: 显示在页面底部的导航栏
resizeToAvoidBottomPadding:类似于 Android 中的
android:windowSoftInputMode=”adjustResize”,控制界面内容 body 是否重新布局来避免底部被覆盖了,比如当键盘显示的时候,重新布局避免被键盘盖住内容。默认值为 true。 显示 snackbar 或者 bottom sheet 的时候,需要使用当前的 BuildContext 参数调用 Scaffold.of 函数来获取 ScaffoldState 对象,然后使用 ScaffoldState.showSnackBar 和 ScaffoldState.showBottomSheet 函数来显示。
接下来的 AppBar ,Center , Column ,Text ,FloatingActionButton 都是各种布局控件,这里不多说了。