Go Flutter Desktop (一) 初探 - caijinglong的博客

文章推薦指數: 80 %
投票人數:10人

Flutter 在去年的时候就有一个第三方的桌面引擎, 是用golang 开发的. Github 地址是:https://github.com/go-flutter-desktop/go-flutter. 2019年7月4日 | flutter |阅读 Flutter在去年的时候就有一个第三方的桌面引擎,是用golang开发的 Github地址是:https://github.com/go-flutter-desktop/go-flutter 目前在mac,linux,windows均可用,作为一个mac用户,除了retina下字显得有点小,感觉没有单独适配外,总体感觉是优于官方的desktop引擎的 另外我是真实的golang脑残粉,我觉得golang这东西真的太好了,用golang,准不会错 开发环境 环境安装 go语言环境安装 go-flutter的环境 运行example 将原项目改为desktop 测试基础的项目 事件响应 ListView滚动 图片 网络图片 文件 内存 资产 输入框 输入响应 显示行为 系统快捷键+鼠标行为 插件 创建并编写插件 go端 dart端 发布插件 引入插件 运行 后记 开发环境 需要的开发环境,因为我是MacOS,我以macOS为例,其他的请参考对应的系统 Xcode命令行体系,这个东西包含很多开发套件(Git),无论你是否用XCode开发,都建议装一个… Flutter环境和配套工具,这个跑不掉,作为flutter开发者… go语言环境(使用brew安装),1.12+,IDE用Jetbrains家的goland(你用VSCode的话看你自己的情况) 环境安装 对flutter桌面版本感兴趣的一定接触过flutter开发,我就默认你有flutter全套开发环境 go语言环境安装 $brewinstallgo 如果你的go比较老,请升级,使用$brewupgradego 配置GOPATH环境变量 $vi~/.bash_profile exportGOPATH=~/code/go#这个是必须配置的,等号后的部分根据你的情况修改,简单来说里面放的是你自己的代码,不是go的SDK,不是go的SDK,不是go的SDK,具体的话是你go语言的三方库源码/自己写的go代码/中间产物/应用程序所在的目录 PATH=$PATH:$GOPATH/bin#这个是选配,但是强烈建议配置,不然以后的go工具链需要全路径引用 你下载的go相关的东西会被装在这个文件夹里 go-flutter的环境 需要使用一个叫做hover的工具,这个工具是由go编写的,编译打包运行都使用这个工具 $goget-ugithub.com/go-flutter-desktop/hover,这样这个工具会被安装到$GOPATH/bin目录下 当你可以直接在命令行输入hover可以出现如下情况时就说明可用了 ➜~hover-h HoverhelpsdeveloperstoreleaseFlutterapplicationsondesktop. Usage: hover[flags] hover[command] AvailableCommands: buildBuildadesktoprelease helpHelpaboutanycommand initInitializeaflutterprojecttousego-flutter runBuildandstartadesktoprelease,withhot-reloadsupport Flags: -h,--helphelpforhover Use"hover[command]--help"formoreinformationaboutacommand. ➜~ 安装hover出现问题的话可以参考这里 运行example 官方提供了几个example:https://github.com/go-flutter-desktop/examples.git cd/tmp gitclonehttps://github.com/go-flutter-desktop/examples.gitflutter-examples cdflutter-examples/pointer_demo flutterpubget hoverrun 通过以上几个步骤就可以把项目跑起来了 是一个关于鼠标移入移出监听的demo 将原项目改为desktop 官方说明文档是这样的,不想看英文的,可以跳过官方文档直接看我的中文说明 这里要注意,因为插件系统的原因,如果不是纯dart插件,则插件内容不能用 我模拟一下这个过程,创建一个+++的helloworld工程,你如果是要改造已有项目,则应该cd到你的flutter的根目录进行$hoverinit项目url的操作,这里根据官方说,url无所谓,后面可改 fluttercreateflutter_example_1 cdflutter_example_1 flutterpubget hoverinitgithub.com/Caijinglong/flutter-go-example#初始化desktop工程 这时候运行项目$hoverrun会有一个提示:Targetfile"lib/main_desktop.dart"notfound. 我们查询可知,可能是考虑到兼容性的问题,go引擎的项目使用main_desktop.dart作为入口,我们创建一个文件 main_desktop.dart: import'package:flutter/foundation.dart'; import'package:flutter/widgets.dart'; import'main.dart'; voidmain(){ debugDefaultTargetPlatformOverride=TargetPlatform.fuchsia; runApp(MyApp()); } $hoverrun 这样项目就跑起来了 测试基础的项目 测试下常用的几项: 事件响应 ListView 图片 输入框情况 事件响应 点击事件是可行的,数字可加,说明鼠标事件能响应,其他的长按双击等等都是flutter实现的,理论上就不需要测试了 最开始的官方demo中有鼠标移入移出事件 ListView滚动 import'package:flutter/material.dart'; classListViewPageextendsStatefulWidget{ @override _ListViewPageStatecreateState()=>_ListViewPageState(); } class_ListViewPageStateextendsState{ @override Widgetbuild(BuildContextcontext){ returnScaffold( appBar:AppBar(), body:ListView.builder( itemBuilder:_buildItem, ), ); } Widget_buildItem(BuildContextcontext,intindex){ returnListTile( title:Text(index.toString()), ); } } 没有移动端的惯性,可以响应鼠标滚轮上下 改成横向的 Widgetbuild(BuildContextcontext){ returnScaffold( appBar:AppBar(), body:ListView.builder( itemBuilder:_buildItem, scrollDirection:Axis.horizontal, ), ); } 横向同样没惯性,shift+滚动可以横向 图片 网络图片 import'package:flutter/material.dart'; classImagePageextendsStatefulWidget{ @override _ImagePageStatecreateState()=>_ImagePageState(); } class_ImagePageStateextendsState{ @override Widgetbuild(BuildContextcontext){ returnScaffold( appBar:AppBar(), body:ListView( children:[ Container( width:500, height:500, child:Image.network( "https://raw.githubusercontent.com/kikt-blog/image/master/img/20190704171705.png"), ), ], ), ); } } 网络图片可行 文件 File的图片,直接使用本地图片就可以了,我因为是mac,所以是这样的,windows可能是c:\\XXXX\\XXX\\X.jpg Container( width:500, height:500, child:Image.file(File("/Users/cai/Desktop/auto-angle.jpg")), ), 内存 memory,这里需要模拟一下 读取上面的文件,然后转为Uint8List Container( width:500, height:500, child:Image.memory( Uint8List.fromList( File("/Users/cai/Desktop/auto-angle.jpg").readAsBytesSync(), ), ), ), 资产 asset:这种方式的加载我印象中去年这个引擎需要使用约定式文件夹,与flutter-web的方式类似 而现在不需要这种方式了,直接与flutter官方的方式一致,只需要在pubspec.yaml中配置即可 flutter: #ThefollowinglineensuresthattheMaterialIconsfontis #includedwithyourapplication,sothatyoucanusetheiconsin #thematerialIconsclass. uses-material-design:true #Toaddassetstoyourapplication,addanassetssection,likethis: assets: -assets/ Container( width:500, height:500, child:Image.asset(R.ASSETS_HAVE_EXIF_JPG), ), ///generatebyresouce_generatorlibrary,shouldn'tedit. classR{ ///![preview](file:///private/tmp/flutter-go-example/./assets/have-exif.jpg) staticconstStringASSETS_HAVE_EXIF_JPG="assets/have-exif.jpg"; } 这里插入一句,图片会根据exif信息旋转至正确的方向 但是图片多了后ListView的滚动性能似乎变差了 输入框 使用Material体系的TextField作为测试,Cupertino和Widget体系的输入框请自行测试吧 有如下几个测试方向(有其他的需求可说,我会加入) 输入响应 显示行为 系统快捷键 鼠标行为 输入响应 这个很好理解,就是用键盘能否输入字符…因为flutter上的官方的plugin就没法输入(我都是道听途说) import'package:flutter/material.dart'; classInputPageextendsStatefulWidget{ @override _InputPageStatecreateState()=>_InputPageState(); } class_InputPageStateextendsState{ @override Widgetbuild(BuildContextcontext){ returnScaffold( appBar:AppBar(title:Text('input')), body:Container( child:TextField(), ), ); } } 输入英文还算正常 试试中文: 文字位置正常,输入框没跟随 显示行为 单行没问题,试试多行,直接回车不行我们需要将TextField设置为多行,我这里分别设置10/50行 50行的话,一页放不下,滚动也算正常 但是这里有一个问题,中英文混合的情况下,水滴不正常 开头和结尾都是英文则没问题,都是中文同理 系统快捷键+鼠标行为 常用的几个快捷键(复制,粘贴,全选)都是OK的,基本行为和正常的输入框完全吻合,这里要给好评,比官方桌面引擎好用多了,其他系统的请自行测试 鼠标行为顺便一起测试了,基本符合正常的操作习惯 插件 这个版本的插件和官方的不一样,需要用golang去写,而不是各自平台的,当然如果各自平台有特殊的api,也需要使用golang去调用 总体有如下几个步骤: 创建插件 编写代码(go+dart) 引入插件 官方文档在此:https://hover.build/docs/create-a-plugin/ 创建并编写插件 go端 打开goland,或者其他的什么编辑器 具体的golang知识没法展开讲解, 可以理解为在gopath的src目录下创建一个包,大部分情况下模仿别人,建议放在github.com目录下 $mkdir-psrc/github.com/caijinglong/go-flutter-plugin/version 创建一个目录,这个就是我插件的文件夹 version.go: packageversion import( "github.com/go-flutter-desktop/go-flutter" "github.com/go-flutter-desktop/go-flutter/plugin" ) const( channelName="top.kikt/go/version" getVersion="getVersion" ) typeVersionPluginstruct{} var_flutter.Plugin=&VersionPlugin{} func(VersionPlugin)InitPlugin(messengerplugin.BinaryMessenger)error{ channel:=plugin.NewMethodChannel(messenger,channelName,plugin.StandardMethodCodec{}) channel.HandleFunc(getVersion,getVersionFunc) returnnil; } funcgetVersionFunc(argumentsinterface{})(replyinterface{},errerror){ return"0.0.1",nil } 这个文件就是我们的插件,必须要有的是结构体声明,初始化插件的方法 下面那个getVersionFunc就是我们处理的方法,这里可以使用golang编程,返回你需要通过golang获取的数据或任何东西,我这里返回了一个简单的字符串 dart端 import'package:flutter/services.dart'; classGetVersionPlugin{ staticconst_channel=constMethodChannel("top.kikt/go/version"); staticFuturegetversionasync=>_channel.invokeMethod("getVersion"); } 发布插件 为了让我们的flutter应用可以找到这个插件,需要一些配置 go-flutter使用的是gomodule的方案管理的go包 我们需要如下几步 cd$GOPATH/src/github.com/caijinglong/go-flutter-plugin/version exportGO111MODULE=on gomodinitgithub.com/caijinglong/go-flutter-plugin/version gomodtidy 目前我们的目录结构是这样的 /Users/cai/code/go/src/github.com/caijinglong/go-flutter-plugin/version ├──go.mod ├──go.sum └──version.go 要想发布,其实得发布到github上,这样别人才能访问,我们目前不这么做,仅本地使用 引入插件 这里需要修改desktop/cmd目录下的options.go文件 packagemain import( "github.com/caijinglong/go-flutter-plugin/version" "github.com/go-flutter-desktop/go-flutter" ) varoptions=[]flutter.Option{ flutter.WindowInitialDimensions(800,1280), flutter.AddPlugin(version.VersionPlugin{}), } 这时候重新运行下项目会报一个错 buildgithub.com/Caijinglong/flutter-go-example/desktop/cmd:cannotloadgithub.com/caijinglong/go-flutter-plugin/version:cannotfindmoduleprovidingpackagegithub.com/caijinglong/go-flutter-plugin/version 这个是因为插件没有发布到github所致,我们先在本地测试下,需要按照官方文档修改一下 modulegithub.com/Caijinglong/flutter-go-example/desktop go1.12 require( github.com/go-flutter-desktop/go-flutterv0.24.1 github.com/pkg/errorsv0.8.1 .com/stretchr/objxv0.2.0//indirect ) replacegithub.com/caijinglong/go-flutter-plugin/version=>/Users/cai/code/go/src/github.com/caijinglong/go-flutter-plugin/version//添加这行 接着就可以运行了 运行 代码如下: import'package:flutter/material.dart'; import'get_version_plugin.dart'; classPluginPageextendsStatefulWidget{ @override _PluginPageStatecreateState()=>_PluginPageState(); } class_PluginPageStateextendsState{ @override Widgetbuild(BuildContextcontext){ returnScaffold( appBar:AppBar(), body:FutureBuilder( future:GetVersionPlugin.version, builder:(c,snapshot){ if(!snapshot.hasData){ returnContainer(); } returnText(snapshot.data); }, ), ); } } 后记 本章简单使用了一下go-flutter项目,仓库地址:https://github.com/CaiJingLong/flutter-go-example 这里需要注意下,由于go插件的原因,直接clone是跑不起来的,你需要配置go以后,把go插件复制到$GOPATH/src/github.com/caijinglong/go-flutter-plugin/version目录内 后面有时间补测下打包产物 以上 SeeAlso FlutterDesktopMac版(二)插件初探 FlutterDesktopMac版(一)初探 dart中的生成器函数 把flutter作为framework添加到已存在的iOS中 把flutter项目作为aar添加到已有的Android工程上 flutter desktop go 最近文章 使用javassist,修改jar包方法实现 Githubaction的开发到发布 flutterJenkins+fastlane自动化打测试包,并上传蒲公英 编译go源码为android动态库(so) FlutterFocusNode焦点那点事-(二) FlutterFocusNode焦点那点事-(一) 用Caddy解决web开发中本地跨域的问题 NavigatorHelper2 flutter怎么实现app整体灰度 Flutter插件开发之引入aar到安卓部分并使用本地maven 分类 android(25) caddy(1) dart(5) docker(3) flutter(60) github(3) go(1) golang(1) iOS(6) ios(1) java(6) jetbrains(1) other(3) python(1) server(5) spring(3) tools(1) 杂项(1) 涂鸦(1) 标签 10 2.3 Clipboard Javassist Migrate aar actions aidl android androidQ androidX apk app appcode azure ble bottomsheet butterknife c caddy camera cameraX channel cocoapods cupertino dart dart-2.6 desktop dialog dmg doc docker docker-compose excel exists faq fastlane ffi ffmpeg flexmark flutter flutter-web focus focusNode form framework github go golang gradle http iOS ide idea index inside ios java jenkins jetbrains jsdelivr json json_serializable junit library live-template loadmore log mac macos maven mysql navigationbar navigator ndk nginx oc opencv poi pub python retrofit route server so spp sprintboot swift tap thymeleaf tips toast transition ui utf8 yield 二进制 交叉 交叉编译 介绍 代码规范 冲突 动态 发布 可执行 图床 城市 大文件 工具 已有项目 开发环境 总结 慢 打包 扫码 插件 文档 模板 渲染 源码解析 灰度 点击 焦点 爬虫 状态管理 百度地图 编码 编程技巧 编译 翻译 蓝牙 表单 路由 过场动画 隐私 友情链接 我的Github flutter官网 其它 文章RSS



請為這篇文章評分?