配置环境
1、安装编辑器
通过官网安装VSCode
2、安装Flutter插件
在VSCode中EXTENSIONS栏中安装Flutter插件
3、检查Flutter插件
通过Command Palette中输入命令检查Flutter的运行环境
run flutter doctor
运行指令时会遇到下面这个错误
[flutter] flutter doctor
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
Building flutter tool...
解决方案:在命令行输入以下命令
xcode-select --install
4、配置Flutter SDK
运行flutter doctor
的时候会提示安装Flutter SDK,安装后通过提示设置SDK的路径
创建项目
1、New Project
通过Command Palette中输入命令New Project
创建项目
2、F5 Run
通过快捷键F5选择设备运行到虚拟机上,前提是Mac设备上安装有Android Studio和XCode开发工具,且有虚拟设备
3、快捷键
运行App后,在终端中按以下快捷键可以启用调试效果
- R:执行热加载
- P:在设备上显示布局网格
- O:切换Android和iOS的预览界面
- Q:退出调试模式
Hello Word
修改main.dart
文件中的代码为Hello Word代码
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
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 Text('Hello World'),
),
),
);
}
}
Flutter的核心思想是一切界面皆组件
- MaterialApp:有Material设计风格的Widget集合
- StatelessWidget:无状态的Widget, 不需要刷新数据的组件
- StatefulWidget:有状态的Widget,需要刷新数据的组件
- Scaffold:Material中一个Widget,它提供了默认的导航栏、标题和包含主屏幕widget树的body属性
- Center:基础Widget,位于视图中心
添加依赖
1、在pubspec.yaml中增加第三方依赖,运行程序或刷新程序,依赖会自动下载
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
english_words: ^3.1.0
如果我们正在本地开发一个包,可以通过下面例子依赖本地包
dependencies:
pkg1:
path: ../../code/pkg1
也可以依赖存储在Git仓库中的包,可以使用path参数指定Git仓库中包的相对位置
dependencies:
package1:
git:
url: git://github.com/flutter/packages.git
path: packages/package1
2、添加依赖
import 'package:english_words/english_words.dart';
3、使用依赖
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//实例化对象
final wordPair = new WordPair.random();
return new MaterialApp(
title: 'Welcome to Flutter',
home: new Scaffold(
appBar: new AppBar(
title: new Text('Welcome to Flutter'),
),
body: new Center(
//随机生成英文单词
child: new Text(wordPair.asPascalCase),
),
),
);
}
}
路由
1、路由管理
路由相当于跳转界面,Navigator是一个路由管理的widget,它通过一个栈来管理一个路由widget集合
onPressed: () {
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new SecondScreen()),
);
},
MaterialPageRoute表示占有整个屏幕空间的一个路由页面,它还定义了路由构建及切换时过渡动画的相关接口及属性
MaterialPageRoute({
WidgetBuilder builder,
RouteSettings settings,
bool maintainState = true,
bool fullscreenDialog = false,
})
- builder:是一个WidgetBuilder类型的回调函数,它的作用是构建路由页面的具体内容
- settings:包含路由的配置信息,如路由名称、是否初始路由
- maintainState:默认情况下,当入栈一个新路由时,原来的路由仍然会被保存在内存中,如果想在路由没用的时候释放其所占用的所有资源,可以设置maintainState为false
- fullscreenDialog:表示新的路由页面是否是一个全屏的模态对话框,在iOS中,如果fullscreenDialog为true,新页面将会从屏幕底部滑入,而不是水平方向
2、静态路由的使用
在开发中,我们可以事先在Widget中注册静态路由
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
//注册路由表
routes:{
"new_page":(context)=>NewRoute(),
} ,
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
通过路由名打开新的路由页
onPressed: () {
Navigator.pushNamed(context, "new_page").then((value) {
//返回数据的处理代码
});
},
返回上一层页面,并带返回数据
Navigator.of(context).pop('这个是要返回给上一个页面的数据');
注册静态路由有个缺点,如果新的路由中需要传递参数的话,通过事先注册好的路由,参数是不可变的
3、动态路由的使用
动态路由的跳转不需要注册,相当于直接构建匿名函数
Navigator.of(context).push(new MaterialPageRoute(builder: (_) {
return new NewRoute(title: '可传递参数的动态路由');
}));
4、路由动画
先构建好路由动画
static SlideTransition createTransition(
Animation<double> animation, Widget child) {
return new SlideTransition(
position: new Tween<Offset>(
begin: const Offset(1.0, 0.0),
end: const Offset(0.0, 0.0),
).animate(animation),
child: child,
);
}
实现路由的跳转
Navigator.push<String>(
context,
new PageRouteBuilder(pageBuilder: (BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation) {
// 跳转的路由对象
return new NewRoute();
}, transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) {
return MyStatefulWidgetState
.createTransition(animation, child);
}));
资源
1、加载Asset条件
Flutter需要在pubspec.yaml
文件上来注册应用程序所需的资源路径才能访问
flutter:
uses-material-design: true
assets:
- images/
2、加载文本Asset
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
Future<String> loadAsset() async {
return await rootBundle.loadString('assets/config.json');
}
3、加载图片Asset
new AssetImage('images/background.png')
new AssetImage('icons/heart.png', package: 'my_icons') //加载依赖包中的图片
或者
Image.asset('graphics/background.png');
new Image.asset('icons/heart.png', package: 'my_icons') //加载依赖包中的图片
封装组件
1、封装组件
StatefulWidget属于有状态的Widget,状态就必须通过createState
来创建
class RandomWords extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return new RandomWordState();
}
}
class RandomWordState extends State<RandomWords>{
@override
Widget build(BuildContext context) {
final wordPair = new WordPair.random();
return new Text(wordPair.asPascalCase);
}
}
2、使用组件
class MyApp extends StatelessWidget {
@override
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(),
),
),
);
}
}
3、组件参数
如果封装的组件需要传递参数,则在构造方法中将参数进行定义
class DayItem extends StatelessWidget{
String title;
DayItem({@required this.title});
@override
Widget build(BuildContext context) {
return Text(title);
}
}