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