一、安装
详情见:https://flutterchina.club/setup-macos/
下载Flutter SDK :https://flutter.io/docs/development/tools/sdk/archive?tab=macos#macos
下载后解压,在目录下会看到./bin目录,将其路径设置进环境变量
vim ~/.bash_profile
添加path变量:
export PATH=~/document/code/flutter/bin:$PATH
如果你使用的是zsh,终端启动时 ~/.bash_profile 将不会被加载,解决办法就是修改 ~/.zshrc ,在其中添加:source ~/.bash_profile
执行
flutter doctor
会检查缺失了什么软件,如果你暂不需要开发安卓,可不理“Android Studio (not installed)”的提示
二、编辑器
我这里选用VScode,先安装扩展,搜索flutter,一般第一个就是。
调用 View>Command Palette(快捷键comm+shift+P),搜索doctor,选择‘Flutter: Run Flutter Doctor’ action,可执行flutter命令
详细可见:https://flutterchina.club/get-started/editor/#vscode
三、开发
Flutter框架包括:Framework和Engine,他们运行在各自的Platform上。
Framework是Dart语言开发的,包括Material Design风格的Widgets和Cupertino(iOS-style)风格的Widgets,以及文本、图片、按钮等基础Widgets;还包括渲染、动画、绘制、手势等基础能力。
Engine是C++实现的,包括Skia(二维图形库);Dart VM(Dart Runtime);Text(文本渲染)等。
实际上,Flutter的上层能力都是Engine提供的。Flutter正是通过Engine将各个Platform的差异化抹平。而我们今天要讲的Plugin,正是通过Engine提供的Platform Channel实现的通信。
1.Flutter的布局方法
Widgets 是用于构建UI的类.
Widgets 用于布局和UI元素.
通过简单的widget来构建复杂的widget
Flutter布局机制的核心就是widget。在Flutter中,几乎所有东西都是一个widget - 甚至布局模型都是widget。您在Flutter应用中看到的图像、图标和文本都是widget。 甚至你看不到的东西也是widget,例如行(row)、列(column)以及用来排列、约束和对齐这些可见widget的网格(grid)。
复杂的UI界面,都是可以拆解成一个个组合部分,如下:
1.排列方式
这里主要用到三种布局排列widgets:
Center
Colum
Row
使用children属性设置子widgets列表
2.对齐 widgets
有了整体排列方式,我们还需要设置内容各个widgets的间距
您可以控制行或列如何使用mainAxisAlignment和crossAxisAlignment属性来对齐其子项。 对于行(Row)来说,主轴是水平方向,横轴垂直方向。对于列(Column)来说,主轴垂直方向,横轴水平方向。
spaceEvenly:row的MainAxisAlignment排列下,均匀分配空闲的水平空间
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
new Image.asset('images/pic1.jpg'),
...
更多MainAxisAlignment属性查看:https://docs.flutter.io/flutter/rendering/MainAxisAlignment-class.html
如果布局太大而不适合设备,则会在受影响的边缘出现红色条纹。例如,以下截图中的行对于设备的屏幕来说太宽:
下面解决
3.调整 widget
可以将行或列的子项放置在Expanded widget中, 以控制沿着主轴方向的widget大小
Expanded widget具有一个flex属性,它是一个整数,用于确定widget的弹性系数,默认弹性系数是1
把之前的image widget都套上Expanded,使内容widget等分宽度
把其中一个的flex:2,代表这个widget宽度是其他的两倍
new Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
new Expanded(
child: new Image.asset('images/pic1.jpg'),
),
new Expanded(
flex: 2,
child: new Image.asset('images/pic2.jpg'),
),
new Expanded(
...
4.聚集 widgets
默认情况下,行或列沿着其主轴会尽可能占用尽可能多的空间,但如果要将孩子紧密聚集在一起,可以将mainAxisSize设置为MainAxisSize.min。 以下示例使用此属性将星形图标聚集在一起(如果不聚集,五张星形图标会分散开)
new Row(
mainAxisSize: MainAxisSize.min,
children: [
new Icon(Icons.star, color: Colors.green[500]),
new Icon(Icons.star, color: Colors.green[500]),
new Icon(Icons.star, color: Colors.green[500]),
new Icon(Icons.star, color: Colors.black),
new Icon(Icons.star, color: Colors.black),
],
);
5、Container 容器
自由使用容器来使用padding分隔widget,或者添加边框(border)或边距(margin)。您可以通过将整个布局放入容器并更改其背景颜色或图片来更改设备的背景。
添加padding, margins, borders
改变背景颜色或图片
包含单个子widget,但该子widget可以是Row,Column,甚至是widget树的根
主要属性:
alignment 对齐
decoration 装饰 ,可设置 border、color(背景色)、borderRadius、image(背景图片)
padding 内部边距
margin 外部边距
6、其他widgets
GridView :格子布局
ListView :列表布局 ListTile
Stack :重叠部件
2、State管理状态
由谁来管理状态
https://flutterchina.club/tutorials/interactive/#managing-state
1、Stateful 和 Stateless widgets
有状态的widget
重写createState()
class FavoriteWidget extends StatefulWidget {
@override
_FavoriteWidgetState createState() => new _FavoriteWidgetState();
}
创建State子类
class _FavoriteWidgetState extends State<FavoriteWidget> {
bool _isFavorited = true;
int _favoriteCount = 41;
void _toggleFavorite() {
setState(() {
// If the lake is currently favorited, unfavorite it.
if (_isFavorited) {
_favoriteCount -= 1;
_isFavorited = false;
// Otherwise, favorite it.
} else {
_favoriteCount += 1;
_isFavorited = true;
}
});
}
@override
Widget build(BuildContext context) {
return new Row(
mainAxisSize: MainAxisSize.min,
children: [
new Container(
padding: new EdgeInsets.all(0.0),
child: new IconButton(
icon: (_isFavorited
? new Icon(Icons.star)
: new Icon(Icons.star_border)),
color: Colors.red[500],
onPressed: _toggleFavorite,
),
),
new SizedBox(
width: 18.0,
child: new Container(
child: new Text('$_favoriteCount'),
),
),
],
);
}
}