重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
在和lib平级 创建两个目录 assets 里面放置json文件
创新互联主要从事成都网站制作、网站设计、网页设计、企业做网站、公司建网站等业务。立足成都服务吴江,十余年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18982081108
在pubspec.yaml里面配置
注意打包的时候json文件会被当成资源打入到包中,所以我们访问的时候要在runApp之前配置下初始化访问二进制权限。否则会报错
Flutter支持稳定的桌面设备开发已经一段时间了,不得不说,Flutter多平台支持的特性真的很香。我本人并没有任何桌面开发的经验,但仍然使用Flutter开发出了一个桌面版小程序,功能很简单,就是对输入的json做格式化处理和转模型。
话不多说,先来看看实际效果。 项目源码地址
开发环境如下:
Flutter : 2.8.1
Dart : 2.15.1
IDE : VSCode
JSON作为我们日常开发工作中经常要打交道的一种数据格式,它共有6种数据类型: null , num , string , object , array , bool 。我们势必对它又爱又恨。爱他因为他作为数据处理的一种格式确实非常方便简洁。但是在我们做Flutter开发中,又需要接触到json解析时,就会感觉非常棘手,因为flutter没有反射,导致json转模型这块需要手写那繁杂的映射关系。就像下面这样子。
数据量少还能接受,一旦量大,那么光手写这个解析方法都能让你怀疑人生。更何况手写还有出错的可能。好在官方有个工具**json_serializable**可以自动生成这块转换代码,也解决了flutter界json转模型的空缺。当然,业界也有专门解析json的网站,可以自动生成dart代码,使用者在生成后复制进项目中即可,也是非常方便的。
本项目以json解析为切入点,和大家一起来看下flutter是如何开发桌面应用的。
要让我们的flutter项目支持桌面设备。我们首先需要修改下flutter的设置。如下,让我们的项目支持 windows 和 macos 系统。
接下来使用 flutter create 命令创建我们的模版工程。
创建完项目后,我们就可以 run 起来了。
先来看下整体界面,界面四块,分别为功能模块、文件选择模块、输入模块、输出模块。
我们在新建一个桌面应用时,默认的模版又一个Appbar,此时应用可以用鼠标拖拽移动,放大缩小,还可以缩到很小。但是,我们一旦去掉这个导航栏,那么窗口就不能用鼠标拖动了,并且我们往往不希望用户将我们的窗口缩放的很小,这会导致页面异常,一些重要信息都展示不全。因此这里需要借助第三方组件 bitsdojo_window 。通过 bitsdojo_window ,我们可以实现窗口的定制化,拖动,最小尺寸,最大尺寸,窗口边框,窗口顶部放大、缩小、关闭的按钮等。
通过 InkWell 组件,可以捕捉到手势、鼠标、触控笔的移动和停留位置
这个功能是鼠标移动后的UI交互界面。要在窗口上显示一个提示框,可以使用 Overlay 。需要注意的是,由于在 Overlay 上的 text 的根结点不是 Material 风格的组件,因此会出现黄色的下划线。因此一定要用 Material 包一下 text 。并且你必须给创建的 OverlayEntry 一个位置,否则它将全屏显示。
读取说表拖拽的文件一开始想尝试使用 InkWell 组件,但是这个组件无法识别拖拽中的鼠标,并且也无法从中拿到文件信息。因此放弃。后来从文章《Flutter-2天写个桌面端APP》中发现一个可读取拖拽文件的组件 desktop_drop ,能满足要求。
使用开源组件 file_picker ,选完图片后的操作和拖拽选择图片后的操作一致。
Textfield 如果要显示富文本,那么需要自定义 TextEditingController 。并重写 buildTextSpan 方法。
在做导出功能时遇到下列报错,保存提示为没有权限访问对应目录下的文件。
通过Apple的开发文档找到有关权限问题的说明。其中有个授权私钥的key为 com.apple.security.files.downloads.read-write ,表示 对用户的下载文件夹的读/写访问权限 。那么,使用Xcode打开Flutter项目中的mac应用,修改工程目录下的 DebugProfile.entitlements 文件,向 entitlements 文件中添加 com.apple.security.files.downloads.read-write ,并将值设置为YES,保存后重启Flutter项目。发现已经可以向下载目录中读写文件了。
当然,这是正常操作。还有个骚操作就是关闭系统的沙盒机制。将 entitlements 文件的 App Sandbox 设置为NO。这样我们就可以访问任意路径了。当然关闭应用的沙盒也就相当于关闭了应用的防护机制,因此这个选项慎用。
原文地址:
dynamic_widget 是一个可以用json来描述flutter widget的动态布局框架,json code和flutter widget code一一对应,如下图:
dynamic_widget:
由于 Flutter 不支持运行时反射,JSON 解析完全是手动的。
所谓手动解析,是指使用 dart:convert 库中内置的 JSON 解码器,将 JSON 字符串解析成自定义对象的过程。使用这种方式,我们需要先将 JSON 字符串传递给 JSON.decode 方法解析成一个 Map,然后把这个 Map 传给自定义的类,进行相关属性的赋值。
下面动手解析一个用户的信息
首先,我们根据 JSON 结构定义 User类,并创建一个工厂类,来处理 User 类属性成员与 JSON 字典对象的值之间的映射关系:
数据解析类创建好了,剩下的事情就相对简单了,我们只需要把 JSON 文本通过 JSON.decode 方法转换成 Map,然后把它交给 User 的工厂类 fromJson 方法,即可完成 User 对象的解析:
项目中往往会碰到 嵌套对象属性 情况,
面对这种情况,我们需要为每一个非基本类型属性创建一个解析类。
然后,我们只需要在 User 类中,增加 dog 属性及对应的 JSON 映射规则即可:
通过这种方法,无论对象有多复杂的非基本类型属性,我们都可以创建对应的解析类进行处理。
不过到现在为止,我们的 JSON 数据解析还是在主 Isolate 中完成。如果 JSON 的数据格式比较复杂,数据量又大,这种解析方式可能会造成短期 UI 无法响应。下面我们可以用 compute 函数优化一下
通过 compute 的改造,我们就不用担心 JSON 解析时间过长阻塞 UI 响应了。
使用注解@JSONField
其中name: "list"的list就是后台返回字段名称,deserialize(默认true)是否参与fromJson解析,serialize(默认true)是否参与tojson,
比如包含如下json
可以解析出来list中map的所有字段,并且每个list的map字段不同或者为null问题有会做出处理
helper文件内容
直接传递上面生成的entity就可以自动根据map解析出对应实例,并自动赋值
网络请求实例
dio请求部分
这些操作完成后自动生成如下文件
@JSONField作用在Field时,其name不仅定义了输入key的名称,为了防止后台返回数据不规范,但是flutter端需要按照驼峰命名
a_b_c_entity_helper.dart类提供了eitity类的tojson和fromjson代理方法
json_convert_content.dart提供了json_convert_content.dart.fromJsonAsT方法 根据泛型来解析json成对象
在此基础上,接下来我们看下Flutter中还有哪几种Json转模型的方式:
在上篇 [Flutter] 07-Flutter中反序列化Json 已经通过6个示例分析过了, 这里不再讨论。
json_serializable 是dart官方推荐和提供的JSON转Model的方式:
依赖分为项目依赖(dependencies),开发依赖(dev_dependencies),在 pubspec.yaml 中添加如下依赖:
由于很多朋友在这一步遇到了问题,这里贴出源码:
最后总结一下以json_serializable 的方式创建模型类必须5步:
备注1:
第五步实际就是创建两个方法:
备注2:
备注3:
UserFromJson(json) 和 ToJson() 调用方法,在未执行 生成对应的.g.dart文件指令 前该行可能会报错。
part 'computer.g.dart'; 和 part 'user.g.dart'; ,在未执行 生成对应的.g.dart文件指令 前该行可能会报错。
备注4:
toString方法不是必须的,只用来打印输出进行测试。
该操作有两种指令:一次性生成指令和 持续性生成指令。
一次性生成指令
在项目终端运行下面的指令:
持续性生成指令
如果感觉每次更改Model时都需要执行一次性生成指令比较繁琐,这时可以使用下面的持续生成指令:
在项目根目录下运行该指令后会启动观察器, 观察器可以监视我们项目中文件的变化,并在需要时自动构建必要的文件。只需启动一次观察器,然后它就会在后台运行,这种方式也很安全。
app.quicktype.io 是一个将 JSON 转换成模型类的工具网站,目前来看支持大部分常用语言,并且灵活的可选项也非常多:
优点: 这种方式操作起来会比使用json_serializable操作起来更简便一些,并且带下划线字段会自动转换为驼峰命名的属性名。
缺点: 如果数据过于复杂的话,在生成的时候可能会少了某一个类,并且不能进行父类抽取。
目前Android Studio(或IntelliJ)有几个插件,可以将json文件转成Model类,但插件质量参差不齐,甚至还有一些有抄袭嫌疑,故笔者在此不做优先推荐,读者有兴趣可以自行了解。
总体推荐使用后两种,可以大大提升开发效率,不用埋头去搞一些重复的序列化工作。