这是一篇使用Flutter构建Web程序的避坑指南,包含了米饭在制作米饭博客程序时候遇到的一些奇怪问题和解决方法。
关于米饭的博客程序可以看这一篇:
[art]538[/art]
强制从Google下载字体
Flutter for web会强制从Google的字体CDN中下载字体,他的逻辑是:检测要显示的文字是否存在于已下载的字体中->不存在则下载对应字体。听起来没有什么问题,但是Flutter构建的网页并不会使用用户已经安装的字体(真的是很怪异的设定),这意味着无论显示任何内容它都会从CDN下载。
对于海外用户来说,从CDN下载似乎也没有什么问题,字体文件不大并且CDN速度很快,但是对于无法访问Google的大陆用户来说就是灾难性的,因为他无法下载任何字体,所以网页中所有文字都无法显示!!就像这个样子:
目前已知的解决办法就是在项目中添加一个字库满足需求的中文字体,并且设置为默认字体。这样Flutter就会优先加载项目自带的字体,并且在确认可以正常显示后不再去从CDN下载字体。
代码实现如下:
在Asset中添加自己需要的字体文件,然后在 pubspec.yaml
中添加配置:
fonts:
- family: Roboto
fonts:
- asset: assets/fonts/Roboto-Regular.ttf
- family: Noto Sans Symbols
fonts:
- asset: assets/fonts/Noto-Sans-Symbols.ttf
- family: LXGWWenKaiLite
fonts:
- asset: assets/fonts/LXGWWenKaiLite-Regular.ttf
之后在main.dart
中配置默认使用的字体:
theme: ThemeData(
fontFamily: 'LXGWWenKaiLite', //在这里配置字体
fontFamilyFallback: ['Arial',"Noto Sans Symbols",'华文细黑','Microsoft YaHei','微软雅黑','Roboto','sans-serif'], //这个Fallback功能貌似不生效
当然如果突然需要显示一个很复杂的繁体字或者其他语言(例如韩文那么他又将自动下载对应字体
之前尝试过要求Flutter使用浏览器自带的字体,并且在相关的GitHub Issue也找到了对应的方法,但是并没有任何效果(好像是因为官方觉得没有人会有这种奇怪的需求,CDN赛高 然后又取消了 雾
强制从Google CDN下载canvaskit.wasm
Flutter构建的网站默认使用Canvaskit进行渲染,所以需要下载canvaskit.wasm。并且他是从Google的CDN中下载。这将会导致无法正常访问Google的用户在访问网站时白屏,无法渲染任何内容。
目前中文社区中很多的教程(尤其是特别难用的CSDN 都是说在Dart.js文件中批量替换与Google有关的地址来解决 听起来就很不靠谱欸!!
所以又去英文社区搜索,得到了无数个不同的构建命令,最后发现貌似只有一个命令是正确的,就是:
flutter build web --web-renderer canvaskit --no-web-resources-cdn
使用--no-web-resources-cdn
参数告诉Flutter不要使用CDN内容 (按照官方的说法这个参数应该也会禁止从CDN处下载字体,但是并没有
目前流行的教程都说是添加--dart-define=FLUTTER_WEB_CANVASKIT_URL=assets/canvaskit/canvaskit.wasm
参数手动指定canvaskit位置 但是没有任何作用
在使用--no-web-resources-cdn
参数之后,不需要手动下载Canvaskit的相关文件到本地,编译过程中Flutter会自动下载
无法正常使用浏览器的返回按钮和更新URL地址
一开始编写的时候,会发现当你点击进入下一个页面之后,浏览器的网站地址并不会改变 返回上一页的按钮也不会按照预期功能实现。之后查阅资料找到了使用HTML库直接修改URL地址的方法,但是这个方法会导致网站强制刷新 用户体验不好。于是之后尝试使用Getx,发现通过Getx控制路由的话,网站地址会正常改变并且不会强制刷新。
注意的是:Getx控制路由后的路由逻辑与APP相同,也就是说如果你使用了类似于Get.offAllNamed(routePath);
这样的跳转到新页面并关闭之前所有页面的路由,那么点击浏览器的返回按钮就没有办法正常返回到上一页。
使用 Get.currentRoute
可以获取当前页面的路由地址 返回内容为String类型
使用Get.parameters['page']
可以获得page参数的内容 例如路由为 /page=23n
就会返回23n
Sting类型
设置网站标题
只需要在页面的任意位置添加Title
Widget即可,并且这个部件支持动态更改Title:
Title(
color: Theme.of(context).colorScheme.surface, //这里会控制浏览器颜色 例如安卓Chrome的地址栏和状态栏颜色
child: Text(""),
title: Gloablelogic.title.value,
),
网站说的Title部件要放在最外面是不对的,测试下来这个部件想放在哪一层就放哪,只要出现了浏览器标题就会改变
结束啦
以上大概就是米饭目前遇到的一些关于Flutter for web的小问题和解决办法,希望可以帮助到大家~
Flutter快支持使用用户自带的字体啊 可恶!!
参与讨论