go-flutter开发桌面应用(二) 创建go-flutter插件

1,347 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言: 今天刚看到,可以【搬运自己的原创文章】参加“程序员必备小知识”活动,十分激动。 想起来之前在某平台上还有几篇技术文章,觉着掘金技术氛围更浓厚,正想搬过来。

原文链接: go-flutter开发桌面应用(二) 创建go-flutter插件 - 知乎 (zhihu.com)

正文

需要先声明下,本节教程不是go-flutter官网创建plugin和发布plugin的方式,是自己写桌面应用时能实现Dart端调用Go端的代码。

本教程github代码

android和ios目录下的文件理论上不需要。

编写go-flutter插件

在hellogoflutter工程下新建go_plugin目录,在go_plugin目录下新建hello目录,

在hello目录中创建go语言代码文件hello.go。

hellogoflutter/go_plugin/hello.go

package hello

import (
	"github.com/go-flutter-desktop/go-flutter"
	"github.com/go-flutter-desktop/go-flutter/plugin"
)

// go-flutter插件需要声明包名和函数名
// dart代码中调用时需要指定相应的包名和函数名
const (
	channelName = "bettersun.go-flutter.plugin.hello"
	hello       = "hello"
)

// 声明插件结构体
type HelloPlugin struct{}

// 指定为go-flutter插件
var _ flutter.Plugin = &HelloPlugin{}

// 初始化插件
func (HelloPlugin) InitPlugin(messenger plugin.BinaryMessenger) error {
	channel := plugin.NewMethodChannel(messenger, channelName, plugin.StandardMethodCodec{})
	channel.HandleFunc(hello, helloFunc)
	return nil
}

// 插件中具体的执行函数
func helloFunc(arguments interface{}) (reply interface{}, err error) {
	return "hello go-flutter", nil
}

执行 go mod init 命令在hello目录中创建 go.mod 文件。

go mod init hello

执行命令后的go.mod文件

hellogoflutter/go_plugin/go.mod

module hello

go 1.13

require github.com/go-flutter-desktop/go-flutter v0.42.0

执行 go mod tidy命令处理依赖关系

go mod tidy

在helloflutter/go中引入插件

在go.mod中添加引入。

helloflutter/go/go.mod

module hellogoflutter/go

go 1.13

require (
	// 非真实存在的github仓库,在下方被改写
	github.com/bettersun/go-flutter-plugin/hello v0.0.0

	github.com/go-flutter-desktop/go-flutter v0.42.0
	github.com/pkg/errors v0.9.1
)

// 使用本地目录改写上方的github仓库
replace github.com/bettersun/go-flutter-plugin/hello => ../go_plugin/hello

修改helloflutter/go/cmd目录下的options.go,main.go无需修改。

helloflutter/go/cmd/options.go

package main

import (
	// go.mod中引入的路径
	"github.com/bettersun/go-flutter-plugin/hello"
	"github.com/go-flutter-desktop/go-flutter"
)

var options = []flutter.Option{
	// 设置窗口宽高
	flutter.WindowInitialDimensions(800, 600),

	// 添加插件
	flutter.AddPlugin(hello.HelloPlugin{}),
}

编写go-flutter插件对应的Dart接口

在lib下创建plugin目录,在plugin目录下创建go目录,在go目录中创建hello_plugin.dart.

hellogoflutter/lib/plugin/go/hello_plugin.dart

import 'dart:async';

import 'package:flutter/services.dart';

class HelloPlugin {
  // go-flutter插件中的包名,两者必须一致
  static const _channel = const MethodChannel("bettersun.go-flutter.plugin.hello");

  // go-flutter插件中的函数名
  static Future<String> hello() async => _channel.invokeMethod("hello");
}

创建一个确认用的画面

在hellogoflutter/lib目录下创建module,在module目录下创建hello目录,在hello目录下创建hello_page.dart。该画面调用go-flutter插件对应的Dart接口。

hellogoflutter/lib/module/hello/hello_page.dart

import 'package:flutter/material.dart';
import 'package:hellogoflutter/plugin/go/plugin.dart';

class HelloPage extends StatefulWidget {
  @override
  _HelloPageState createState() => _HelloPageState();
}

class _HelloPageState extends State<HelloPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Hello'),
      ),
      body: Center(
          child: Column(
        children: <Widget>[
          FutureBuilder<String>(
            future: HelloPlugin.hello(),
            builder: (c, snapshot) {
              if (!snapshot.hasData) {
                return Text('Hello插件执行出错');
              }
              return Text(snapshot.data);
            },
          )
        ],
      )),
    );
  }
}

修改main.dart中FAB的点击处理,点击FAB跳转到上面创建的画面。

main.dart FAB 部分代码:

import './module/hello/hello_page.dart';
      floatingActionButton: FloatingActionButton(
        // onPressed: _incrementCounter,
        onPressed:() async {
                  await Navigator.of(context).push(
                    MaterialPageRoute(builder: (_) {
                      return HelloPage();
                    }),
                  );
                },

        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),

执行hover run启动程序

程序启动后,点击FAB,会跳转到确认画面。

确认画面会显示 hello go-flutter,即插件的具体处理函数的返回结果。

image.png