rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
dependencies {
// 这里的xxx是.flutter-plugins中注册的名字
compileOnly rootProject.findProject(":xxx")
}
怎样使用IDE看这里:https://flutterchina.club/using-ide/
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
export PATH=$PATH:~/android/flutter/bin
通过flutter help可以查看有哪些命令
Google 把 Flutter 作为 Fuchsia 的用户界面,Dart 作为主要的编程语言,从颜色和展示效果上看,使用的是 Material Design UI 理念。
在Flutter中,依赖包由Pub仓库管理,项目依赖配置在项目根目录下pubspec.yaml文件中声明即可(类似于NPM的版本声明 Pub Versioning Philosophy),对于未发布在Pub仓库的插件可以使用git仓库地址或文件路径
url_launcher: ">=0.1.2 <0.2.0"
collection: "^0.1.2"
plugin1:
git:
url: "git://github.com/flutter/plugin1.git"
plugin2:
path: ../plugin2/
在Flutter中,所有功能都可以通过组合多个Widget来实现,包括对齐方式、按行排列、按列排列、网格排列甚至事件处理等等。在Flutter中“一切皆是控件”,通过组合、嵌套不同类型的控件,就可以构建出任意功能、任意复杂度的界面
Widget实际上就是Element的配置数据,Widget树实际上是一个配置树,而真正的UI渲染树是由Element构成; 一个Widget可以对应多个Element,这是因为同一个Widget对象可以被添加到UI树的不同部分。 而在stateful widget中,State对象也和StatefulElement具有对应关系(一对一)。因此Widget和State 也是一对多的关系。State实例只会在第一次插入到树中时被创建,当在重新构建时,如果widget被修改了,Flutter framework会 动态设置State.widget为新的widget实例,而State本身不会重建。
默认情况下,flutter run命令会使用调试版本配置。 编译release包: flutter build apk 安装:flutter install 注意:这三个命令都要在项目根目录下执行
在Flutter中Widget是不可变的,不会直接更新,而必须使用Widget的状态才能更新。所以Widget仅支持一帧,并且在每一帧上,Flutter的框架都会创建一个Widget实例树(译者语:相当于一次性绘制整个界面)。 这里要注意的重要一点是无状态和有状态widget的核心特性是相同的,每一帧它们都会重新构建,不同之处在于StatefulWidget有一个State对象,它可以跨帧存储状态数据并恢复它。 所以Flutter中不存在添加或删除组件,您可以传入一个函数,该函数返回一个widget给父项,并通过布尔值控制该widget的创建,可以理解成重新动态创建。
body: new Center(
child: _getToggleChild(),
)
_getToggleChild() {
if (toggle) {
return new Text('Toggle One');
} else {
return new MaterialButton(onPressed: () {}, child: new Text('Toggle Two'));
}
}
Flutter拥抱组合:widget由较小的widget构建而成,您可以以各种方式组合,以制作自定义widget。例如,RaisedButton将一个Material widget与一个GestureDetector widget组合在一起,而不是对一个通用按钮widget进行子类化。Material widget提供了可视化设计,而GestureDetector widget提供了交互设计。
Hot Reload通过将更新的源代码文件注入正在运行的Dart VM(虚拟机)中工作。这不仅包括添加新类,还包括向现有类添加方法和字段,以及更改现有函数。尽管有几种类型的代码更改无法热重新:
由于在Android和iOS平台上支持后台执行的基本差异,在后台运行代码具有特定于平台的API。 在Android上,android_alarm_manager 即使您的Flutter应用程序不在前台,该插件也可让您在后台运行Dart代码。 在iOS上,我们目前不支持此功能。请留意Bug 6192的更新。
Widget _buildSuggestions() {
return new ListView.builder(
// 该方法至少执行一次,哪怕列表是空的
itemBuilder: (context, i) {
final index = i ~/ 2;
// 如果是建议列表中最后一个单词对
if (index >= _suggestions.length) {
// ...接着再生成10个单词对,然后添加到建议列表,不需要调用setState方法
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
}
);
}
Widget getRow(int i) {
return new GestureDetector(
child: new Padding(
padding: new EdgeInsets.all(10.0),
child: new Text("Row $i")),
onTap: () {
// 必须调用setState
setState(() {
widgets = new List.from(widgets);
widgets.add(getRow(widgets.length + 1));
print('row $i');
});
},
);
}
在Flutter中,事件流是“向上”传递的,而状态流是“向下”传递的(译者语:这类似于React/Vue中父子组件通信的方式:子widget到父widget是通过事件通信,而父到子是通过状态),重定向这一流程的共同父元素是State。更形象的理解是,父元素State是一个桥梁,子widget出发事件->State中的变量->更新其他Widget,这样可以达到责任分离允许将复杂性逻辑封装在各个widget中,同时保持父项的简单性。
Scaffold 是 Material library 中提供的一个widget, 它提供了默认的导航栏、标题和包含主屏幕widget树的body属性
和Android相似,您可以在AndroidManifest.xml中声明您的Activities,在Flutter中,您可以将具有指定Route的Map传递到顶层MaterialApp实例
void main() {
runApp(new MaterialApp(
home: new MyAppHome(), // becomes the route named '/'
routes: <String, WidgetBuilder> {
'/a': (BuildContext context) => new MyPage(title: 'page A'),
'/b': (BuildContext context) => new MyPage(title: 'page B'),
'/c': (BuildContext context) => new MyPage(title: 'page C'),
},
));
}
然后,您可以通过Navigator来切换到命名路由的页面。
Navigator.of(context).pushNamed('/b');
插件工程结构和普通的flutter工程结构一样,也可以直接运行,只是多了个example目录,example目录就是一个引用了插件的普通工程,实际上运行的就是这个工程。
注意点:
android {
// url_launcher是依赖的插件的名称
dependencies {
provided rootProject.findProject(":url_launcher")
}
}
添加文档 建议将以下文档添加到所有软件包:
创建方式有两种:
flutter module和普通flutter工程目录结构相同,也可以直接用android studio打开并且运行(.android目录也可以直接用android studio打开)。区别:
注意点:
Flutter工程的Android打包,其实只是在Android的Gradle任务中插入了一个flutter.gradle的任务,而这个flutter.gradle主要做了三件事:(这个文件可以在Flutter库中的[flutter/packages/flutter_tools/gradle]目录下能找到。)
一个进程里面最多只会初始化一个Dart VM,然而一个进程可以有多个Flutter Engine, 多个Engine实例共享同一个Dart VM,只是不同Engine实例加载的代码跑在各自独立的Isolate。 Flutter Engine自己不创建管理线程,Flutter Engine线程的创建和管理是由embedder负责的。 Mobile平台上面每一个Engine实例启动的时候会为UI,GPU,IO Runner各自创建一个新的线程。所有Engine实例共享同一个Platform Runner和线程。
注意点:
参考文章: