安全区域

当直接使用小部件时会出现在左上角的状态栏附近

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import 'package:flutter/material.dart';

void main() {
runApp(
MaterialApp(
home: Scaffold(
backgroundColor: Colors.teal,
body: Container(
child: Text("Hello,nmk"),
),
),
),
);
}

使用Safeared进行摆放到安全区域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import 'package:flutter/material.dart';

void main() {
runApp(
MaterialApp(
home: Scaffold(
backgroundColor: Colors.teal,
body: SafeArea(
child: Container(
child: Text("Hello,nmk"),
),
),
),
),
);
}

圆形控件

可展示用户头像

1
2
3
4
5
6
7
                child: CircleAvatar(
radius: 50.0,
backgroundImage:
NetworkImage('https://s3.ax1x.com/2021/03/02/6FUzNt.jpg'),
),
NetworkImage 网络加载
AssetImage 本地加载

效果图

文本样式
1
2
3
4
5
6
7
8
9
10
Text(
"FlUTTER DEVELOPER",
style: TextStyle(
fontFamily: 'SourceSansPro',
color: Colors.white,
fontSize: 20,
letterSpacing: 2.5,
fontWeight: FontWeight.bold),
textAlign: TextAlign.left,
),

color: 文字颜色

fontStyle: 文字样式 斜体和正常

fontWeight: 字体粗细 粗体和正常

letterSpacing: 字母间隙(负值可以让字母更紧凑)

textAlign:文本的对齐方式;可以选择左对齐、右对齐还是居中。

height:该属性用于指定行高,但它并不是一个绝对值,而是一个因子,具体的行高等于fontSize*height

fontFamily :指定字体,由于不同平台默认支持的字体集不同,所以在手动指定字体时一定要先在不同平台测试一下。

fontSize:该属性和Text的textScaleFactor都用于控制字体大小。但是有两个主要区别:

  • fontSize可以精确指定字体大小,而textScaleFactor只能通过缩放比例来控制。
  • textScaleFactor主要是用于系统字体大小设置改变时对Flutter应用字体进行全局调整,而fontSize通常用于单个文本,字体大小不会跟随系统字体大小变化。

maxLinesoverflow:指定文本显示的最大行数,默认情况下,文本是自动折行的,如果指定此参数,则文本最多不会超过指定的行。如果有多余的文本,可以通过overflow来指定截断方式,默认是直接截断 TextOverflow.clip剪裁 TextOverflow.fade 渐隐 TextOverflow.ellipsis省略号

textScaleFactor:代表文本相对于当前字体大小的缩放因子,相对于去设置文本的样式style属性的fontSize,它是调整字体大小的一个快捷方式。该属性的默认值可以通过MediaQueryData.textScaleFactor获得,如果没有MediaQuery,那么会默认值将为1.0。

添加字体

可以在Flutter应用程序中使用不同的字体。例如,Google Fonts (opens new window)中的字体。

在Flutter中使用字体分两步完成。首先在pubspec.yaml中声明它们,以确保它们会打包到应用程序中。然后通过TextStyle (opens new window)属性使用字体。

在asset中声明

要将字体文件打包到应用中,和使用其它资源一样,要先在pubspec.yaml中声明它。然后将字体文件复制到在pubspec.yaml中指定的位置。如:

1
2
3
4
5
6
7
8
flutter:
fonts:
- family: Pacifico
fonts:
- asset: fonts/Pacifico-Regular.ttf
- family: SourceSansPro
fonts:
- asset: fonts/SourceSansPro-Regular.ttf
使用字体
1
2
3
4
5
Text(
"FlUTTER DEVELOPER",
style: TextStyle(
fontFamily: 'SourceSansPro',
),
添加水平横线
1
2
3
4
5
6
SizedBox(
height: 20.0,
width: 180.0,
child: Divider(
color: Colors.teal.shade100,
)),
更改图标文件

https://www.iconfont.cn/查找到喜欢的图标

https://appicon.co/ 把图标生成为ios和android可以使用的图标文件

Expanded

Expanded是用于展开RowColumnFlex的子child的Widget。

使用Expanded可以使[Row],[Column]或[Flex]的子项扩展以填充主轴中的可用空间(例如,水平用[Row]或垂直用[Column])。

如果扩展了多个子节点,则根据[flex]因子将可用空间划分为多个子节点。

[Expanded]小部件必须是[Row],[Column]或[Flex]的后代,并且从[Expanded]小部件到其封闭的[Row],[Column]或[Flex]的路径必须包含 只有[StatelessWidget]或[StatefulWidget]

构造函数

1
2
3
4
5
const Expanded({
Key key,
int flex = 1,
@required Widget child,
})
  • flex 分配空间的弹性系数,RowColumnFlex的每个Expanded的flex构成空间分配的比例,默认int flex = 1
  • child 即需要分配的子Widget

示例

1
2
3
4
5
6
7
8
9
10
11
12
Expanded(
child: FlatButton(
color: Colors.red,
onPressed: () {},
),
),
Expanded(
child: FlatButton(
color: Colors.orange,
onPressed: () {},
),
),

默认flex为1 所以颜色按比例1:1分配

image-20210316181002701
1
2
3
4
5
6
7
8
9
10
11
12
13
Expanded(
flex: 2,
child: FlatButton(
color: Colors.red,
onPressed: () {},
),
),
Expanded(
child: FlatButton(
color: Colors.orange,
onPressed: () {},
),
),

默认flex为2 所以颜色按比例2:1分配

image-20210316181208812
内边距
1
padding: EdgeInsets.only(left: 12,top: 12,bottom: 12),
外边距
1
margin: EdgeInsets.only(top:4),
flutter内容超出屏幕

编写flutter代码的时候,如果超出手机屏幕高度的话是会出错的,需要使用SingleChildScrollView来包裹

SingleChildScrollView和container用发一样, 直接包在外层就好了,里面是child’
它可以在主题内容超出Y轴的时候自动生成滚动条,类似overflow:auto
类似如下用法

1
2
3
4
5
return SingleChildScrollView(
child: Container(
child .....
)
)

进入flutter_app的android>app>src>main>res目录

image-20210303180252077
浮动按钮
1
2
3
4
5
6
return Scaffold(
floatingActionButton: FloatingActionButton(
child: IconButton(icon: Icon(Icons.add),onPressed: (){},),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);

写在scaffold的里面

通过floatingActionButtonLocation: FloatingActionButtonLocation.来控制浮动的位置

routes

默认页面的三种方式

1
2
3
4
5
6
7
8
第一种方式:
routes: {
'/': (context) => home(),
},
第二种方式:
home: home(),
第三种方式:
initialRoute: '/home',
ListTitle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const ListTile({
Key key,
this.leading, //左侧的组件
this.title, //中间的主标题
this.subtitle, //中间的副标题
this.trailing, //右侧组件,通常是一个值或者一个图标
this.isThreeLine = false, //是否显示三行
this.dense, //是否以垂直密集的方式显示,这样文字会更小
this.visualDensity,
this.shape, //定义外观形状
this.contentPadding, //内容与边框之间的边距,默认16
this.enabled = true, //是否可以互动事件
this.onTap, //点击事件
this.onLongPress, //长按事件
this.mouseCursor, //鼠标悬停在ListTile上时的处理效果,给web用的
this.selected = false, //如果是true,文本和图标将会以相同的颜色呈现
this.focusColor,
this.hoverColor, //指针悬停在ListTile上的颜色
this.focusNode, //聚焦事件
this.autofocus = false, //是否默认聚焦
this.tileColor, //listTile的背景颜色,selected=false时生效
this.selectedTileColor, //listTile的背景颜色,selected=true时生效
})
方法

定义没有返回值的方法

1
void name (){};

定义有返回值的方法

1
2
3
4
5
6
7
8
9
10
11
String name(){
return abc;
}

int name(){
return 1;
}

bool name(){
return true;
}
flutter导航
1
2
3
4
5
6
7
8
Navigator.push(context, MaterialPageRoute(builder: (context){return InputPage();},));
#push导航到新的页面

Navigator.pop(context);
#pop销毁当前页面

Navigator.pushNamed(context, '/');
#pushNamed通过路由名进行导航
根据设备类型显示不同小部件

方法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
引入包
import 'dart:io';

通过if进行判断设备返回不同小部件
Widget getPicker() {
if (Platform.isIOS) {
return iosPicker();
} else if (Platform.isAndroid) {
return androidDorpdown();
}
}
调用该方法
Container(
height: 100.0,
alignment: Alignment.center,
color: Colors.lightBlue,
child: getPicker()),

方法二

1
2
3
4
5
6
7
Container(
height: 120.0,
alignment: Alignment.center,
padding: EdgeInsets.only(bottom: 30.0),
color: Colors.lightBlue,
child: Platform.isIOS ? iosPicker() : androidDorpdown(),
),
import中的含义
1
2
3
4
5
6
import 'dart:io' show Platform;
只导入Platform
import 'dart:io' hide Platform;
除了Platform都导入
import 'dart:io' as http;
讲库重命名避免冲突
调用键盘时出现黄条 空间不够
1
2
3
4
5
6
7
8
9
10
11
加入Flexible

Flexible(
child: Hero(
tag: 'logo',
child: Container(
height: 200.0,
child: Image.asset('images/logo.png'),
),
),
),

会在调用键盘时 缩小该Widget

Android

iOS

Cupertino风格

CupertinoActivityIndicator
加载中组件
radius 默认10 加载图形的半径值
animating 默认true 是否播放加载动画
1
2
3
4
CupertinoActivityIndicator(
animating: true,
radius: 10.0,
)
CupertinoAlertDialog
对话框
action: List 对话框底部按钮
title 标题
content 内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class _MyHomePageState extends State<MyHomePage> {
void _showIOSDialog(BuildContext cxt) {
showCupertinoDialog<int>(
context: cxt,
builder: (cxt) {
return new CupertinoAlertDialog(
title: Text('提示'),
content: Text('是否退出应用'),
actions: <Widget>[
new Container(
decoration: BoxDecoration(
border: Border(
right: BorderSide(color: Color(0xFFD9D9D9), width: 0.5),
top: BorderSide(color: Color(0xFFD9D9D9), width: 0.5))),
child: CupertinoDialogAction(
child: new Text("确定"),
onPressed: () {
Navigator.pop(context);
},
),
),
new Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Color(0xFFD9D9D9), width: 0.5))),
child: CupertinoDialogAction(
child: new Text("取消"),
onPressed: () {
Navigator.pop(context);
},
),
)
],
);
});
}

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: const Text('首页')),
body: new Container(
alignment: Alignment.center,
child: RaisedButton(
onPressed: () => {_showIOSDialog(context)},
child: Text('点我弹框'),
),
));
}
}
CupertinoButton

展示IOS风格按钮
color 组件颜色
disableColor 禁用颜色
onPressed 按下事件
child 显示按钮的文本
enable 是否禁用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
CupertinoButton(
//按钮控件布局
child: Text('IOS风格按钮'),
//内边距
padding:EdgeInsets.all(10.0),
//背景颜色
color:Colors.blue,
//onPress 为 null,禁用点击的背景颜色
disabledColor:Colors.grey,
//最小尺寸
minSize : 44.0,
//按下的透明度
pressedOpacity : 0.1,
//边框圆角
borderRadius : const BorderRadius.all(Radius.circular(8.0)),
//点击事件
onPressed:()=>{
print('点我干嘛')
}
)
CupertinoDialogAction

通常用于CupertinoAlertDialog的一个button

1
2
3
4
5
6
7
8
9
10
CupertinoDialogAction(
child: new Text("确定"),
//是否为默认按钮
isDefaultAction: true,
//是否为取消操作按钮
isDestructiveAction: true,
onPressed: () {
Navigator.pop(context);
},
)
CupertinoSlider
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
CupertinoSlider(
//当前进度值
value:_progress,
//进度条监听事件
onChanged:(progress) => {
_progress = progress,
print("_progress$_progress"),
setState((){
})
},
//进度条开始监听
onChangeStart:(progress) => {
print("onChangeStart$progress"),
},
//进度条结束监听
onChangeEnd:(progress) => {
print("onChangeEnd$progress"),
},
//进度条最小值
min : 0.0,
//进度条最大值
max : 100.0,
//进度条分成多少分
divisions:1,
//进度条颜色
activeColor:Colors.blue,
)
CupertinoSwitch
1
2
3
4
5
6
7
8
9
10
11
CupertinoSwitch(
value: _isOpen,
onChanged: (isOpen) => {
_isOpen = isOpen,
setState((){

})
},
//开关颜色
activeColor: Colors.blue,
)
CupertinoPageRoute
1
2
3
4
5
onPressed: (){
Navigator.push(context, new CupertinoPageRoute(
builder: (context) => Details(),
));
},
CupertinoNavigationBar

iOS风格的导航栏. 通常和CupertinoPageScaffold一起使用。

cupertinoNavigationBar 导航栏结构组件
middle 中间组件,多为标题
trailing 右边 多为菜单按钮
leading 左边按钮,多为返回
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
new CupertinoNavigationBar(
//左边Widget(一般为返回按钮)
leading: const Icon(Icons.arrow_back_ios),
//如果为true并且middle为空的时候并且当前路由是CupertinoPageRoute,则自动用[Text]小部件填充,文本当前路由的“title”。
automaticallyImplyMiddle: true,
//上一页按钮
previousPageTitle: '上一页',
backgroundColor: Colors.blue,
middle: const Text(
'标题',
style: TextStyle(color: Colors.white),
),
//右边Widget
trailing: const Text(
'trailing',
style: TextStyle(color: Colors.white),
),
//边框
border: Border.all(color: Color(0xFFD9D9D9), width: 1.0),
//图标颜色
actionsForegroundColor: Colors.white,
//内边距
padding: EdgeInsetsDirectional.zero,
//是否在导航栏之间切换。
transitionBetweenRoutes: true,
)
CupertinoPageScaffold

一个iOS风格的页面的基本布局结构。包含内容和导航栏,和 CupertinoNavigationBar 一起使用。

cupertinoTabScaffold 选项卡组件
tabbar cupertinoTabbar
tabBuilderr: indexedWidgetBuilder 选项卡视图构造器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
new CupertinoPageScaffold(
navigationBar: new CupertinoNavigationBar(
middle: const Text(
'标题',
style: TextStyle(color: Colors.black),
),
),
child: new Container(
alignment: Alignment.center,
child: RaisedButton(
child: Text('跳转下一个页面'),
onPressed: () {
Navigator.push(
context,
new CupertinoPageRoute(
builder: (context) => Details(),
));
},
),
))
CupertinoTabScaffold 和 CupertinoTabBar

标签式iOS应用程序的结构。将选项卡栏放在内容选项卡之上

CupertinoTabBar 是 iOS风格的底部选项卡。 通常和CupertinoTabScaffold一起使用。

cupertinoTabbar 选项卡按钮组件,通常有BottomNavigationBarItem
items: list
backgroundcolor 按钮背景色
activeColor 前景色
iconSize 图标大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
new CupertinoTabScaffold(
tabBar: new CupertinoTabBar(
items: <BottomNavigationBarItem>[
new BottomNavigationBarItem(
icon: Icon(Icons.home),
activeIcon: Icon(Icons.hourglass_full),
title:Text('首页',
style: TextStyle(color: Colors.black))
),
new BottomNavigationBarItem(
icon: Icon(Icons.fiber_manual_record),
activeIcon: Icon(Icons.fiber_manual_record),
title:Text('社区',
style: TextStyle(color: Colors.black))
),
new BottomNavigationBarItem(
icon: Icon(Icons.add_shopping_cart),
activeIcon: Icon(Icons.add_shopping_cart),
title:Text('发现',
style: TextStyle(color: Colors.black))
),
new BottomNavigationBarItem(
icon: Icon(Icons.my_location),
activeIcon: Icon(Icons.my_location),
title:Text('我的',
style: TextStyle(color: Colors.black))
),
],
),
tabBuilder: (context,index) => new Container(
alignment: Alignment.center,
child: RaisedButton(
child: Text('跳转下一个页面$index'),
onPressed: () {
Navigator.push(
context,
new CupertinoPageRoute(
builder: (context) => Details(),
));
},
),
))
CupertinoTabView

选项卡视图组件,支持选项卡间并行导航项卡的根内容。通常与CupertinoTabScaffolde一起使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
tabBuilder: (context, index) => new CupertinoTabView(
//返回按钮描述文本
defaultTitle: '返回',
//注册跳转的路径和页面
routes: {
'/home': (context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('我是标题'),
),
child: Center(
child: Text('我是第二页'),
),
);
},
},
builder: (context) => new Container(
alignment: Alignment.center,
child: RaisedButton(
child: Text('跳转下一个页面$index'),
onPressed: () {
Navigator.of(context).pushNamed('/home');
},
),
),
)

使app支持多端

flutter使app支持web
1
2
3
4
5
6
7
8
flutter channel stable
flutter upgrade

Unable to 'pub upgrade' flutter tool. Retrying in five seconds
解决方法:删除 flutter SDK中 bin/cache 文件夹,然后再flutter upgrade就可以了。

如果报错使用
flutter upgrade --force

一旦开启了 Web 支持,运行 flutter devices,命令会输出一个名为 Chrome 的设备信息,开启一个为 Web 应用提供服务的 Web Sever,并打开 Chrome 浏览器并访问某个 URL 地址。

1
2
3
4
➜flutter devices
1 connected device:

Chrome (web) • chrome • web-javascript • Google Chrome 89.0.4389.128

要在 Chrome 的 localhost 中部署你的应用,从软件包根目录输入以下内容:

1
flutter run -d chrome

当前项目目录下,创建web文件

1
flutter create .

运行下面命令以生成发行版构建:

1
flutter build web

Release 构建产物使用 dart2js(不是 dartdevc)生成了一个单独的 JavaScript main.dart.js 文件。你可以通过 release 模式 (flutter run --release) 或者 flutter build web 创建一个发行构建。输出文件在 build/web 目录下,包括需要一起提供的 assets 资源文件。

目前通过两个仍在开发中的项目提供对桌面平台的支持。其中一个甚至是谷歌开发的,但有迹象表明该公司不支持它。可以在以下 Github 存储库中找到这些项目:

这两个项目都归类为 Custom Flutter Engine Embedders,也就是说,它们是 Flutter API 的实现,因此在此框架中开发的项目可以在 Flutter 项目(Android,Fuchsia 和 iOS)正式支持的操作系统之外运行。

本文使用第二种实现方式

安装需要依赖:GO GCC Git

访问https://github.com/go-flutter-desktop/hover

运行go version并确保您的Go版本为1.13或更高版本。

1
2
C:\Users\admin>go version
go version go1.15.6 windows/amd64

安装GCC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
exec: "gcc": executable file not found in %PATH%
这是因为Windows系统上没有GCC编译器。而编译代码中的包里面可能需要用到gcc编译器。

解决办法如下:

下载链接:https://sourceforge.net/projects/mingw-w64/files/mingw-w64/

个人建议:不要下载exe文件,网不好安装下载资源包很费劲。还是下载64位x86_64-posix-seh压缩包,直接解压就行。没有解压工具的自己下载一个。
解压完之后,配置环境变量。将安装路径对应的bin目录添加到PATH环境变量中。

C:\Users\admin\Desktop\gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=G:/x86_64-8.1.0-release-posix-seh-rt_v6-rev0/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-8.1.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-posix-seh-rev0, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/lib -L/c/mingw810/prerequisites/x86_64-zlib-static/lib -L/c/mingw810/prerequisites/x86_64-w64-mingw32-static/lib '
Thread model: posix
gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)

运行以下命令来安装hover

windows:

1
2
set GO111MODULE=on
go get -u -a github.com/go-flutter-desktop/hover

现有Flutter项目入门

进入到项目目录

1
2
3
4
cd flutter-app/

#第一次将悬停用于项目时,您需要初始化该项目以与悬停一起使用。可以将参数传递给hover init来设置项目路径。这通常是您在github或自托管git服务上的项目的路径。如果不确定使用hover init无路径。您可以稍后更改路径。
hover init github.com/nmk0718/flutter-app

运行

1
2
3
4
hover run
#热重载是手动的,因为您需要在终端中按“ r”来热重载应用程序。

#默认情况下,悬停使用文件lib/main_desktop.dart作为入口点。您可以使用该--target标志指定其他端点。

打包

1
hover build linux # or darwin or windows

首次使用时hover run启动没问题 打包报错 切换为beta版本在进行打包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
C:\Users\admin\Downloads\memos-main\memos-main>flutter channel beta
Switching to flutter channel 'beta'...
git: Branch 'beta' set up to track remote branch 'beta' from 'origin'.
git: Switched to a new branch 'beta'
Successfully switched to flutter channel 'beta'.
To ensure that you're on the latest build from this channel, run 'flutter upgrade'

C:\Users\admin\Downloads\memos-main\memos-main>hover build windows
hover: Downloading engine for platform windows-release at version a123e75c6082da3a08f229b9c565e64b5b24a8a3...
Download completed in 23.08s
hover: Cleaning the build directory
hover: Bundling flutter app
VersionCheckError: Command exited with code 128: git fetch __flutter_version_check__ beta
Standard error: fatal: unable to access 'https://github.com/flutter/flutter.git/': OpenSSL SSL_read: Connection was
reset, errno 10054


Flutter assets will be downloaded from https://storage.flutter-io.cn. Make sure you trust this source!
Downloading package sky_engine... 368ms
Downloading flutter_patched_sdk tools... 448ms
Downloading flutter_patched_sdk_product tools... 240ms
Downloading windows-x64 tools... 1,023ms
Downloading windows-x64/font-subset tools... 173ms
Running "flutter pub get" in memos-main... 839ms

Building with sound null safety

hover: Generating kernel snapshot
result 67978fb7-9906-4bd1-a022-0f2cb4d31ba0
lib/main_desktop.dart: Warning: Interpreting this as package URI, 'package:memos/main_desktop.dart'.
67978fb7-9906-4bd1-a022-0f2cb4d31ba0
nel_snapshot.dill 0
hover: Generating ELF snapshot
Warning: Generating ELF library without DWARF debugging information.
hover: Checking available release on Github
hover: Compiling 'go-flutter' and plugins
runtime/cgo
github.com/go-flutter-desktop/go-flutter/internal/currentthread
github.com/go-flutter-desktop/go-flutter/embedder
github.com/go-gl/glfw/v3.3/glfw
github.com/go-gl/gl/v3.3-core/gl
github.com/go-flutter-desktop/go-flutter/internal/priorityqueue
github.com/go-flutter-desktop/go-flutter/internal/keyboard
github.com/go-flutter-desktop/go-flutter/internal/opengl
github.com/go-flutter-desktop/go-flutter
hover: Successfully compiled executable binary for windows

编译windows不能直接进行使用,必须移动整个文件夹才能使用,所以使用以下命令打包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
C:\Users\admin\Downloads\memos-main\memos-main>hover build windows-msi
hover: Using engine from cache
hover: Cleaning the build directory
hover: Bundling flutter app

Building with sound null safety

hover: Generating kernel snapshot
result 19414483-7af2-49ad-99fa-98b0c4ca254f
lib/main_desktop.dart: Warning: Interpreting this as package URI, 'package:memos/main_desktop.dart'.
19414483-7af2-49ad-99fa-98b0c4ca254f
nel_snapshot.dill 0
hover: Generating ELF snapshot
Warning: Generating ELF library without DWARF debugging information.
hover: Compiling 'go-flutter' and plugins
hover: Successfully compiled executable binary for windows
hover: Packaging app for windows-msi
hover: Missing/Empty `author` field in pubspec.yaml. Please add it or otherwise you may publish your app with a wrong author. Continuing with `DESKTOP-D5VSCI4\admin` as a placeholder author.
hover: Missing/Empty `license` field in go/hover.yaml. Please add it or otherwise you may publish your app with a wrong license. Continuing with `NOASSERTION` as a placeholder license.
hover: Failed to read `go/packaging/windows-msi/upgrade-code.txt`: open C:\Users\admin\Downloads\memos-main\memos-main\go\packaging\windows-msi\upgrade-code.txt: The system cannot find the file specified.
hover: Please re-init windows-msi to generate the `go/packaging/windows-msi/upgrade-code.txt`
hover: or put a GUID from https://www.guidgen.com/ into a new `go/packaging/windows-msi/upgrade-code.txt` file.

如果报错To package windows-msi these tools are required: candle
请前往https://wixtoolset.org/releases/进行下载安装
启动下载好的Wix程序,会提示缺少.netframework3.5.1,windows的控制面板>程序>启用和关闭windows功能>勾选.netframework3.5
安装好.netfamework后再次启动Wix进行安装,安装完毕,目录为C:\Program Files (x86)\WiX Toolset v3.11
运行命令后还是缺少candle.exe,把C:\Program Files (x86)\WiX Toolset v3.11\bin加入系统环境变量的Path中即可

Failed to read `go/packaging/windows-msi/upgrade-code.txt
按照提示信息访问 https://www.guidgen.com/复制页面中的code
创建go/packaging/windows-msi/upgrade-code.txt文件,粘贴code到文本中保存即可

问题

Your Flutter application is created using an older version of the Android

embedding. It’s being deprecated in favor of Android embedding v2.

解决办法:打开android/app/main文件夹下的AndroidManifest.xml文件,在activity标签的下面增加如下代码:

1
2
3
<meta-data
android:name="flutterEmbedding"
android:value="2" />

[!] Your app isn’t using AndroidX.

To avoid potential build failures, you can quickly migrate your app by following the steps on https://goo.gl/CP92wY.

解决办法:在android文件夹的gradle.properties中添加如下代码即可:

1
2
android.enableJetifier=true
android.useAndroidX=true

error: resource android:attr/fontVariationSettings not found

解决办法

更改android目录下app下的build.gradle文件中的编译版本由27改为28即可

1
2
3
4
5
6
7
android {
compileSdkVersion 28
#更改该参数为28

lintOptions {
disable 'InvalidPackage'
}

flutter已经pub get下载完插件,但是会报错 Error: Type ‘PathProviderWindows’ not found.

使用命令

1
2
flutter clean
flutter pub cache repair

等下完即可

[!] The following Swift pods cannot yet be integrated as static libraries:

The Swift pod DKPhotoGallery depends upon SDWebImage, which does not define modules. To opt into those targets generating module maps (which is necessary to import them from Swift when building as static libraries), you may set use_modular_headers! globally in your Podfile, or specify :modular_headers => true for particular dependencies.

1
2
3
4
5
6
在ios/Podfile中修改

target 'Runner' do
use_frameworks! #add here
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

Automatically assigning platform iOS with version 9.0 on target 你的工程名称 because no platform was specified. Please specify a platform for this target in your Podfile. See https://guides.cocoapods.org/syntax/podfile.html#platform

这是在使用cocoapods安装三方库配置podfile之后的一个警告信息。

1
2
# Uncomment this line to define a global platform for your project
platform :ios, '9.0'

只需要将第二行platform前面的注销# 符号去掉 就可以了