热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

FlutterWeb开发进出坑总结

FlutterWeb开发进出坑总结-theme:smartblue在前一阵用flutter开发web的过程中,遇到了一些坑,遇到了一些与app端开发不一样的地方,当然也学到了

theme: smartblue

在前一阵用flutter开发web的过程中,遇到了一些坑,遇到了一些与app端开发不一样的地方,当然也学到了一些新知识点,所以总结一下,一方面帮助他人,另一方面,自己也能加深记忆,要不容易忘。(年纪大了?记忆力还不行了呢???)

一、启动运行乱码

没错,启动一个demo,遇到坑了,如图所示

点击Android Studio上方运行按钮,程序启动之后汉字文字显示乱码,这是由于flutter web有三种渲染模式,auto 、html 和 canvaskit,点击运行按钮(flutter build web命令)默认的渲染模式为auto,这种模式在移动端使用html渲染,在pc端使用canvaskit渲染。

解决办法 1: 用命令行运行,并指定渲染模式,就能解决问题。

// 指定渲染模式为html
flutter build web --web-renderer html

解决办法 2: 上面虽然能解决问题,但我习惯用按钮运行程序怎么办?当然也找到了其他办法。在程序包下web/index.html文件中body标签下copy如下代码。

 
  
  
  

二、Debug启动运行断点失败

web开发和APP端开发一样,也可以断点。项目之初断点是可以的,但是不知道怎么的,debug可以运行,但断不到,很奇怪,花了一上午,发现同事因为发版改了下web/index.htmlhead->base标签下 href="***"的值。

解决办法 :

// 之前,断点可用
 

// 同事改动,断点不可用
 

// 修复后,断点可用

不能断点开发实在是麻烦。

三、Hot Reload热重载、点击浏览器刷新,都会重启整个程序

在APP端开发时,在某个页面点hot reload按钮,只会重新运行当前页面,但是在web中,点热重载会重启,这只是开发中的不方便。已经上线的程序,用户只要点击浏览器刷新就会重启整个程序,无论在哪个页面,都会回到第一个页面,这与我浏览网页的习惯明显是不符的。

查找原因,发现是flutter底层问题,仔细观察web页面是通过不同的url来确定的,而Flutter从始至终都是一个url,只是flutter在一个网页中绘制了不同的页面(与APP端原理一致),所以想解决问题就是要每个页面都有自己的url。

解决办法 : 用静态路由的方式跳转页面和传参,具体代码如下。

  // 跳转与传参
  static Future toName(String pageName, Map params) {
    var uri = Uri(scheme: RoutePath.scheme, host: pageName, queryParameters: params);
    return Navigator.of(currentContext).pushNamed(uri.toString());
  }

  // 取参方式
  static Route generateRoute(RouteSettings settings) {
    return PageRouteBuilder(
        settings: settings,
        pageBuilder: (BuildContext c, Animation a,Animation sa) {
          var uri = Uri.parse(settings.name ?? ''); //解析页面名
          switch (uri.host) {
            case RoutePath.name:
              return NamePage(uri.queryParameters); 、、传参
            default:
              return Scaffold(
                body: Center(
                  child: Text('没有找到对应的页面:${settings.name}'),
                ),
              );
          }
        });
  }

通过以上方式,跳转时每个页面都会有自己的url和拼接的参数,这样刷新的时候就不会重启整个程序,会停留在当前页面。

四、用静态路由的方式跳转,全局变量,单例对象丢失,页面栈记录丢失。

没错,坑是连着的,我也是服了。当在某页面热重载或点击浏览器刷新,会停留在当前页面,但是无法返回,就算点击跳转至其他页面,也会报错,因为全局变量都已经丢失,比如:登录信息,用户信息,已经初始化的工具类对象等。

已经有人提了Issues,国内也有大神分析了原因和不完全结局方案

目前flutter web对于浏览器还是没有适配完全,无论Navigator1.0还是Navigator2.0,都存在不可解决的严重问题。目前来看google的对flutter web的意图,还是开发移动web并在App中通过webkit这种内核使用,并没有想开发者使用flutter web来开发真正的web应用,或者后续会完善这部分。

我的解决方案

  1. 除了登录页和首页,其他页面不用静态路由的方式跳转,这样做即使用户刷新,也不会回到登录页,而是回首页。
  2. 在有刷新需求的页面上提供刷新图标,可触发刷新,避免用户点击浏览器的刷新。
  3. 全局变量持久化,用html.window.localStorage并配合工厂模式持久化数据,当被触发刷新,会从本地重新赋值,比如:登录信息等。
  4. 弱化全局成员变量,非必要不使用全局类的变量,数据尽量放云端,页面间不耦合。

五、检测浏览器/标签页关闭还是刷新

解决办法 : 可以使用函数onBeforeUnload来检查选项卡是否正在关闭。它也可能检测到页面刷新。

import 'dart:html' as html;
html.window.onBeforeUnload.listen((event) async{
  // do something
});

或者

import 'dart:html' as html;
html.window.onUnload.listen((event) async{
  // do something
});

六、引用 import 'dart:html' 运行提示报错

多端运行,如果引用了html会提示报错。

解决办法 : 可以引用第三方universal_html 2.0.8,帮封装了一层,支持多端。

universal_html :适用于所有平台的“dart:html”,包括 Flutter 和服务器端。简化跨平台开发和 HTML / XML 处理。

七、可点击提示

在平常浏览网页时,鼠标滑动到可点击的文字或按钮上,鼠标“箭头”会变成一个“小手”,或背景出现颜色变化提示。
Flutter中常用的GestureDetector()手势工具,虽然可以实现点击等回调,但是鼠标滑动到可点击区域,鼠标“箭头”并不会变成“小手”,在交互上不符合大众使用网页的习惯。

解决办法 : 使用InkWell替换GestureDetector,用InkWell包住的按钮或文字,鼠标悬停,就会出现小手。

Ink(
        width: width,
        height: height,
        color: color,
        child: InkWell(
            focusColor: Colors.transparent,
            highlightColor: Colors.transparent,
            splashColor: Colors.transparent,
            hoverColor: const Color(0x0818a7fb),
            onTap: onTap,
            child: Center(child: this)))


分析源码可知,内部用MouseRegion监听了鼠标位置,那什么是MouseRegion呢?

八、鼠标监听控件 MouseRegion

相对于APP端,web端多了个鼠标,可以实现app实现不了的交互效果,比如悬停,划过,进入退出某区域等,都可以用MouseRegion实现。

MouseRegion的属性和说明
| 字段 | 属性 | Col3 |
| --- | --- | --- |
onEnter|PointerEnterEventListener|鼠标进入区域时的回调
onExit|PointerHoverEventListener|鼠标退出区域时的回调
onHover|PointerExitEventListener|鼠标在区域内移动时的回调
cursor|MouseCursor |鼠标悬停区域时的光标样式
opaque|bool |是否阻止检测鼠标
child|Widget |子组件

最后

这是目前遇到有价值的坑,后面遇到新的也会持续更新。

Flutter开发web上,路由和全局变量上的坑还是挺严重的,但只要没有复杂的页面间逻辑,普通展示完全没问题。


推荐阅读
  • 本文总结了在开发中使用gulp时的一些技巧,包括如何使用gulp.dest自动创建目录、如何使用gulp.src复制具名路径的文件以及保留文件夹路径的方法等。同时介绍了使用base选项和通配符来保留文件夹路径的技巧,并提到了解决带文件夹的复制问题的方法,即使用gulp-flatten插件。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • HDFS2.x新特性
    一、集群间数据拷贝scp实现两个远程主机之间的文件复制scp-rhello.txtroothadoop103:useratguiguhello.txt推pushscp-rr ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • 本文介绍了自动化测试专家Elfriede Dustin在2008年的文章中讨论了自动化测试项目失败的原因。同时,引用了IDT在2007年进行的一次软件自动化测试的研究调查结果,调查显示很多公司认为自动化测试很有用,但很少有公司成功实施。调查结果表明,缺乏资源是导致自动化测试失败的主要原因,其中37%的人认为缺乏时间。 ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
author-avatar
phpxiaofei
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有