热门标签 | 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上,路由和全局变量上的坑还是挺严重的,但只要没有复杂的页面间逻辑,普通展示完全没问题。


推荐阅读
  • Flutter 2.* 路由管理详解
    本文详细介绍了 Flutter 2.* 中的路由管理机制,包括路由的基本概念、MaterialPageRoute 的使用、Navigator 的操作方法、路由传值、命名路由及其注册、路由钩子等。 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 为了确保iOS应用能够安全地访问网站数据,本文介绍了如何在Nginx服务器上轻松配置CertBot以实现SSL证书的自动化管理。通过这一过程,可以确保应用始终使用HTTPS协议,从而提升数据传输的安全性和可靠性。文章详细阐述了配置步骤和常见问题的解决方法,帮助读者快速上手并成功部署SSL证书。 ... [详细]
  • 今天我开始学习Flutter,并在Android Studio 3.5.3中创建了一个新的Flutter项目。然而,在首次尝试运行时遇到了问题,Gradle任务 `assembleDebug` 执行失败,退出状态码为1。经过初步排查,发现可能是由于依赖项配置不当或Gradle版本不兼容导致的。为了解决这个问题,我计划检查项目的 `build.gradle` 文件,确保所有依赖项和插件版本都符合要求,并尝试更新Gradle版本。此外,还将验证环境变量配置是否正确,以确保开发环境的稳定性。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 在探讨如何在Android的TextView中实现多彩文字与多样化字体效果时,本文提供了一种不依赖HTML技术的解决方案。通过使用SpannableString和相关的Span类,开发者可以轻松地为文本添加丰富的样式和颜色,从而提升用户体验。文章详细介绍了实现过程中的关键步骤和技术细节,帮助开发者快速掌握这一技巧。 ... [详细]
  • 深入浅出 webpack 系列(二):实现 PostCSS 代码的编译与优化
    在前一篇文章中,我们探讨了如何通过基础配置使 Webpack 完成 ES6 代码的编译。本文将深入讲解如何利用 Webpack 实现 PostCSS 代码的编译与优化,包括配置相关插件和加载器,以提升开发效率和代码质量。我们将详细介绍每个步骤,并提供实用示例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • MATLAB字典学习工具箱SPAMS:稀疏与字典学习的详细介绍、配置及应用实例
    SPAMS(Sparse Modeling Software)是一个强大的开源优化工具箱,专为解决多种稀疏估计问题而设计。该工具箱基于MATLAB,提供了丰富的算法和函数,适用于字典学习、信号处理和机器学习等领域。本文将详细介绍SPAMS的配置方法、核心功能及其在实际应用中的典型案例,帮助用户更好地理解和使用这一工具箱。 ... [详细]
  • 2018 HDU 多校联合第五场 G题:Glad You Game(线段树优化解法)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6356在《Glad You Game》中,Steve 面临一个复杂的区间操作问题。该题可以通过线段树进行高效优化。具体来说,线段树能够快速处理区间更新和查询操作,从而大大提高了算法的效率。本文详细介绍了线段树的构建和维护方法,并给出了具体的代码实现,帮助读者更好地理解和应用这一数据结构。 ... [详细]
  • 本文探讨了在使用 Outlook 时遇到的一个常见问题:无法加载 SAVCORP90 插件,导致软件功能受限。该问题通常表现为在启动 Outlook 时会收到错误提示,影响用户的正常使用体验。文章详细分析了可能的原因,并提供了多种解决方法,包括检查插件兼容性、重新安装插件以及更新 Outlook 版本等。通过这些步骤,用户可以有效解决这一问题,恢复 Outlook 的正常运行。 ... [详细]
  • 本文探讨了 Kafka 集群的高效部署与优化策略。首先介绍了 Kafka 的下载与安装步骤,包括从官方网站获取最新版本的压缩包并进行解压。随后详细讨论了集群配置的最佳实践,涵盖节点选择、网络优化和性能调优等方面,旨在提升系统的稳定性和处理能力。此外,还提供了常见的故障排查方法和监控方案,帮助运维人员更好地管理和维护 Kafka 集群。 ... [详细]
  • Netty框架中运用Protobuf实现高效通信协议
    在Netty框架中,通过引入Protobuf来实现高效的通信协议。为了使用Protobuf,需要先准备好环境,包括下载并安装Protobuf的代码生成器`protoc`以及相应的源码包。具体资源可从官方下载页面获取,确保版本兼容性以充分发挥其性能优势。此外,配置好开发环境后,可以通过定义`.proto`文件来自动生成Java类,从而简化数据序列化和反序列化的操作,提高通信效率。 ... [详细]
  • 在尝试对从复杂 XSD 生成的类进行序列化时,遇到了 `NullReferenceException` 错误。尽管已经花费了数小时进行调试和搜索相关资料,但仍然无法找到问题的根源。希望社区能够提供一些指导和建议,帮助解决这一难题。 ... [详细]
  • Python 并发编程进阶:从初学者到高手的进程与模块开发指南
    Python 并发编程进阶:从初学者到高手的进程与模块开发指南 ... [详细]
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社区 版权所有