Flutter支持稳定的桌面设备开发已经一段时间了,不得不说,Flutter多平台支持的特性真的很香。我本人并没有任何桌面开发的经验,但仍然使用Flutter开发出了一个桌面版小程序,功能很简单,就是对输入的json做格式化处理和转模型。
网站设计制作、成都网站建设介绍好的网站是理念、设计和技术的结合。创新互联公司拥有的网站设计理念、多方位的设计风格、经验丰富的设计团队。提供PC端+手机端网站建设,用营销思维进行网站设计、采用先进技术开源代码、注重用户体验与SEO基础,将技术与创意整合到网站之中,以契合客户的方式做到创意性的视觉化效果。
话不多说,先来看看实际效果。 项目源码地址
开发环境如下:
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。这样我们就可以访问任意路径了。当然关闭应用的沙盒也就相当于关闭了应用的防护机制,因此这个选项慎用。
原文地址:
emotional flutter
感情的浮动
笑颜(えがお)残(のこ)る 帰(かえ)り道(みち)に
いつかなくした 声(こえ)探(さが)してる
归途中,残留着你的笑容
寻找着,曾几何时的声音
记忆(きおく)の暗(やみ)が刻(きざ)む时(とき)
今(いま)も终(お)わらなくて
烙印在黑暗中的记忆
那一刻始终无法没灭
空(そら)の中(なか)舞(ま)い降(お)りる
白(しろ)い羽(はね) 揺(ゆ)らして
舞动洁白的双翼
从空中飘舞而降
手(て)を伸(の)ばし 駆(か)け抜(ぬ)け
あなたの影(かげ) 追(お)いかけていく
出双手,奔向前方
追寻着你熟悉的身影
白(しろ)い雪(ゆき)が降(ふ)り积(つ)もれば
包(つつ)み隠(かく)すの 悲(かな)しみの色(いろ)
皑皑的白雪从天而降
为我掩盖悲伤的色彩
心(こころ)の奥(おく)に潜(ひそ)む爱(あい)
どうか忆(おぼ)えていて
将我心底潜藏的爱
毫无保留的献予你
空(そら)高(たか)く舞(ま)い上(あ)がる
白(しろ)い羽(はね) 広(ひろ)げて
舒展洁白的双翼
轻舞飞扬于广阔的天际
柔(やわ)らかな阳(ひ)の中(なか)
あなたの梦(ゆめ)みていたい
在柔和的阳光里
满怀着你的梦想
远(とお)く空(そら) 舞(ま)い踊(おど)る
白(しろ)い羽(はね) 缠(まと)って
身披洁白的双翼
翩翩起舞于悠远的天空
ふたつの手(て) 重(かさ)ねて
未来(みらい)を离(はな)さないでいて
我们的双手紧紧牵系
把握住未来,请不要放手
是 Never Grow Up 吧 ~
Your little hand's wrapped around my finger 你的小手握着我的手指
And it's so quiet in the world tonight今晚,这个世界好安静
Your little eyelids flutter cause you're dreaming 你的眼皮因为你正做的梦微微的颤动着
So I tuck you in, turn on your favorite night light 我帮你盖上被子,打开了你最喜爱的小夜灯
To you everything's funny, you got nothing to regret 对你而言,这一切是多么的有趣,没有事情让你感到遗憾
I'd give all I have, honey 亲爱的,我给了你一切我所拥有的
If you could stay like that 希望你能一直保持这样
Oh darling, don't you ever grow up 亲爱的, 你可以就这样不要长大吗
Don't you ever grow up, just stay this little就这样不要长大,就一直这样小小的
Oh darling, don't you ever grow up亲爱的, 你可以就这样不要长大吗
Don't you ever grow up, it could stay this simple就这样不要长大,世界就会这样一直简简单单的
I won't let nobody hurt you, won't let no one break your heart 我不会让任何人伤害你,我不会让任何人打碎你的心
And no one will desert you 没有人会抛弃你
Just try to never grow up, never grow up 试着的不要长大,不要长大
You're in the car on the way to the movies 你坐在车里,在去看电影的路上
And you're mortified your mom's dropping you off 因为妈妈送你,而让你感到羞愧
At 14 there's just so much you can't do 当你14岁的时候,有许许多多的事情你没有办法做
And you can't wait to move out someday and call your own shots你等不及有一天,你会搬出去,拥有自己的房子,掌握着自己的一切
But don't make her drop you off around the block 但是别让她送你到离目的地一个街区远的地方(怕被别人看见)
Remember that she's getting older too 记得,她也在慢慢的变老
And don't lose the way that you dance around in your pj's getting ready for school
不要忘了你曾是如此兴奋的穿着睡衣一边跳着舞,一边做着准备去学校,
Oh darling, don't you ever grow up亲爱的, 你可以就这样不要长大吗
Don't you ever grow up, just stay this little就这样不要长大,就这样一直小小的
Oh darling, don't you ever grow up亲爱的, 你可以就这样不要长大吗
Don't you ever grow up, it could stay this simple就这样不要长大,世界就会这样一直简简单单的
No one's ever burned you, nothing's ever left you scarred 没有人伤害你,永远不会有人让你一个人害怕
And even though you want to, just try to never grow up即使你盼望着,也请试着不要长大吧
Take pictures in your mind of your childhood room 把你童年房间的样子印在记忆里
Memorize what it sounded like when your dad gets home 记忆听上去好像爸爸到家时的脚步声一般温馨
Remember the footsteps, remember the words said 记得那个脚步声,记得那些话语
And all your little brother's favorite songs 还有所有你弟弟最爱的歌
I just realized everything I have is someday gonna be gone 我才意识到,我现在拥有的一切都会在未来的某一天消失
So here I am in my new apartment现在, 我站在我的新的公寓里
In a big city, they just dropped me off 在一个大城市, 他们开车送我到这里
It's so much colder that I thought it would be 比我想象的要寒冷的许多
So I tuck myself in and turn my night light on 我盖上了自己的被子,打开了自己的小夜灯
Wish I'd never grown up 真希望我没有长大
I wish I'd never grown up 我祈祷着,我还没有长大
Oh I don't wanna grow up, wish I'd never grown up 我不想长大,真希望我没有长大
I could still be little 我依旧是那样小小的
Oh I don't wanna grow up, wish I'd never grown up我不想长大,真希望我没有长大
It could still be simple 世界依旧是那样的简单
Oh darling, don't you ever grow up 亲爱的, 你可以就这样不要长大吗
Don't you ever grow up, just stay this little就这样不要长大,就一直这样小小的
Oh darling, don't you ever grow up亲爱的, 你可以就这样不要长大吗
Don't you ever grow up, it could stay this simple就这样不要长大,世界就会这样一直简简单单的
Won't let nobody hurt you 我不会让任何人伤害你
Won't let no one break your heart不会让任何人打碎你的心
And even though you want to, please try to never grow up 即使你盼望着,也请你试着不要长大
Oh, don't you ever grow up 不要长大
Oh, never grow up, just never grow up
不要长大,就这样不要长大
在和lib平级 创建两个目录 assets 里面放置json文件
在pubspec.yaml里面配置
注意打包的时候json文件会被当成资源打入到包中,所以我们访问的时候要在runApp之前配置下初始化访问二进制权限。否则会报错
由于 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 响应了。