Flutter内部访问插件internal的使用

Flutter内部访问插件internal的使用

你将通过编辑此README文件来学习如何在Bitbucket中编辑文件。


编辑一个文件

你将从编辑此README文件开始,以了解如何在Bitbucket中编辑文件。

  1. 点击左侧的源码
  2. 从文件列表中点击README.md链接。
  3. 点击编辑按钮。
  4. 删除以下文本:删除此行以从Bitbucket更改README。
  5. 完成更改后,点击提交,然后在对话框中再次点击提交。提交页面将会打开,并且你会看到刚刚所做的更改。
  6. 返回到源码页面。

创建一个文件

接下来,你将在该仓库中添加一个新文件。

  1. 源码页面顶部点击新建文件按钮。
  2. 给文件命名为contributors.txt
  3. 在空白文件空间中输入你的名字。
  4. 点击提交,然后在对话框中再次点击提交
  5. 返回到源码页面。

在继续之前,你可以探索一下仓库。你已经见过源码页面,但请检查一下提交记录分支设置页面。


克隆一个仓库

使用以下步骤从SourceTree克隆。克隆允许你在本地工作于你的文件。如果你还没有SourceTree,下载并安装它。如果你更喜欢从命令行克隆,可以参见克隆一个仓库

  1. 源码标题下,你会看到克隆按钮。点击那个按钮。
  2. 现在点击在SourceTree中检出。你可能需要创建或登录SourceTree账户。
  3. 当你在SourceTree中看到新建克隆对话框时,如果愿意可以更新目标路径和名称,然后点击克隆
  4. 打开你刚创建的目录,查看你的仓库文件。

现在你对Bitbucket仓库更加熟悉了,可以继续在本地添加一个新文件。你可以使用SourceTree推送你的更改回Bitbucket,或者你可以从命令行添加、提交推送


示例代码

以下是演示如何在Flutter应用中使用internal插件的完整示例代码。

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:internal/internal.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _platformVersion = 'Unknown';
  late BuildContext _context;
  final _internalPlugin = Internal();

  [@override](/user/override)
  void initState() {
    super.initState();
    // 初始化平台状态
  }

  // 平台消息是异步的,因此我们在异步方法中初始化
  Future<void> initPlatformState() async {
    String platformVersion;
    // 平台消息可能会失败,因此我们使用try/catch捕获PlatformException。
    // 我们还处理消息可能返回null的情况。
    try {
      List list1 = [
        {'msg': 'HAIDILAO Richmond', 'type': 'big'},
        {'msg': '海底捞 - 列治文店', 'type': 'big'},
        {'msg': '5890 No.3Rd Room 200 Richmond, BC. V6X 3P6', 'type': ''},
        {'msg': '6043706665', 'type': ''},
        {'msg': '', 'type': 'line'},
        {'msg': 'Order#: O17104609576091149', 'type': ''},
        {'msg': 'TXN: 17104609576091149', 'type': ''},
        {'msg': 'Payment Method: QR Code', 'type': ''},
        {'msg': 'Payment Code: V***9351', 'type': ''},
        {'msg': 'Total: \$0.01', 'type': 'big'},
        {
          'msg': 'https://bravoupca/gift/24489d1eb106te10317fbb216b49bft5',
          'type': 'qrcode'
        },
      ];

      platformVersion = "";

      platformVersion = await _internalPlugin.internalRequest(list1) ?? 'Unknown';
    } on Exception {
      platformVersion = 'Failed to get request result.';
    }

    // 如果小部件在异步平台消息还在飞行时被树移除,则我们想丢弃回复而不是调用setState来更新我们的不存在的外观。
    if (!mounted) return;

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  getBody(context) {
    _context = context;
    return Scaffold(
      appBar: AppBar(
        title: const Text('插件示例应用'),
      ),
      body: Center(
        child: Column(children: [
          Text('结果: $_platformVersion\n'),
          ElevatedButton(
              onPressed: () {
                int time = 1736289905000;
                int yesterday = time - 86400000;
                int nowtime = time;
                int yesterdaytime = yesterday;
                int lasttime = 10000;
                nowtime += lasttime;
                yesterdaytime += lasttime;
                List data = [
                      {
                        'entrytime': '${nowtime + lasttime * 1}',
                        'amount': 0,
                        'tip': 0
                      },
                      {
                        'entrytime': '${yesterdaytime + lasttime * 1}',
                        'amount': 1,
                        'tip': 0
                      },
                      {
                        'entrytime': '${nowtime + lasttime * 2}',
                        'amount': 2,
                        'tip': 50
                      },
                      {
                        'entrytime': '${yesterdaytime + lasttime * 2}',
                        'amount': 3,
                        'tip': 108
                      },
                      {
                        'entrytime': '${nowtime + lasttime * 3}',
                        'amount': 4,
                        'tip': 1
                      },
                      {
                        'entrytime': '${yesterdaytime + lasttime * 3}',
                        'amount': 5,
                        'tip': 380
                      },
                      {
                        'entrytime': '${nowtime + lasttime * 4}',
                        'amount': 6,
                        'tip': 480
                      },
                      {
                        'entrytime': '${yesterdaytime + lasttime * 4}',
                        'amount': 7,
                        'tip': 108
                      },
                      {
                        'entrytime': '${nowtime + lasttime * 5}',
                        'amount': 8,
                        'tip': 109
                      },
                      {
                        'entrytime': '${nowtime + lasttime * 6}',
                        'amount': 9,
                        'tip': 1180
                      },
                      {
                        'entrytime': '${yesterdaytime + lasttime * 5}',
                        'amount': 10,
                        'tip': 1280
                      },
                      {
                        'entrytime': '${nowtime + lasttime * 7}',
                        'amount': 11,
                        'tip': 1380
                      },
                      {
                        'entrytime': '${nowtime + lasttime * 7}',
                        'amount': 12,
                        'tip': 1380
                      },
                      {
                        'entrytime': '${nowtime + lasttime * 7}',
                        'amount': 13,
                        'tip': 1380
                      },
                      {
                        'entrytime': '${nowtime + lasttime * 7}',
                        'amount': 14,
                        'tip': 1380
                      },
                      {
                        'entrytime': '${nowtime + lasttime * 7}',
                        'amount': 15,
                        'tip': 1380
                      },
                      {
                        'entrytime': '${nowtime + lasttime * 7}',
                        'amount': 16,
                        'tip': 1380
                      },
                      {
                        'entrytime': '${nowtime + lasttime * 7}',
                        'amount': 17,
                        'tip': 1380
                      },
                      {
                        'entrytime': '${nowtime + lasttime * 7}',
                        'amount': 18,
                        'tip': 1380
                      },
                    ];
                for(int i = 0; i < 2000; i++) {
                  data.add({
                        'entrytime': '${yesterdaytime + lasttime * 5 + i}',
                        'amount': 12 + i,
                        'tip': 1380 + i
                      });
                }
                List list1 = [
                  {
                    'type': 'table',
                    'name': 'historytransaction',
                    'title': '交易记录',
                    'where': 'entrytime=@today order by entrytime desc', // '2024-03-13'
                    'orderby': 'date desc',
                    'orderasc': 'desc',
                    'columns': [
                      {
                        "id": "entrytime",
                        "dbid": "entrytime",
                        "type": "datetime",
                        "label": "日期",
                        "defaultValue": "",
                        "required": false,
                        "minLength": 0,
                        "length": 255,
                        "hash": false,
                        "unit": "字符",
                        "prefixIcon": null,
                        "inputType": "datetime",
                        "fontSize": null,
                        "letterSpacing": 0.0,
                        "isPrimary": false,
                        "isKeyword": false,
                        "droplist": "",
                        "uniqueKey": "",
                        "isUnique": false,
                        "colType": "java.lang.Long",
                        "isFile": false,
                        "seq": 10,
                        "canshow": true,
                        "fromsource": "",
                        "isFrozen": false,
                        "addNewCheck": false,
                        "isWholePage": false,
                        "after": "",
                        "showrange": "table",
                        "Advanced search": true,
                      },
                      {
                        "id": "amount",
                        "dbid": "amount",
                        "type": "money",
                        "label": "金额",
                        "defaultValue": "",
                        "required": false,
                        "minLength": 0,
                        "length": 80,
                        "hash": false,
                        "unit": "字符",
                        "prefixIcon": null,
                        "inputType": "money",
                        "fontSize": null,
                        "letterSpacing": 0.0,
                        "isPrimary": false,
                        "isKeyword": false,
                        "droplist": "",
                        "uniqueKey": "",
                        "isUnique": false,
                        "colType": "java.lang.Long",
                        "isFile": false,
                        "seq": 20,
                        "canshow": true,
                        "fromsource": "",
                        "isFrozen": false,
                        "addNewCheck": false,
                        "isWholePage": false,
                        "after": "",
                        "showrange": "",
                        "sumtype": "sum",
                      },
                      {
                        "id": "tip",
                        "dbid": "tip",
                        "type": "money",
                        "label": "小费",
                        "defaultValue": "",
                        "required": false,
                        "minLength": 0,
                        "length": 80,
                        "hash": false,
                        "unit": "字符",
                        "prefixIcon": null,
                        "inputType": "money",
                        "fontSize": null,
                        "letterSpacing": 0.0,
                        "isPrimary": false,
                        "isKeyword": false,
                        "droplist": "",
                        "uniqueKey": "",
                        "isUnique": false,
                        "colType": "java.lang.Long",
                        "isFile": false,
                        "seq": 30,
                        "canshow": true,
                        "fromsource": "",
                        "isFrozen": false,
                        "addNewCheck": false,
                        "isWholePage": false,
                        "after": "",
                        "showrange": "",
                        "sumtype": "sum",
                      },
                    ],
                    'data': data,
                    'context': _context,
                  },
                ];
                _internalPlugin.internalRequest(list1);
              },
              child: const Text('表格示例')),
          ElevatedButton(
              onPressed: () async {
                List list1 = [
                  {'type': 'getSerial(SUNMI)'}
                ];
                dynamic serial =
                    await _internalPlugin.internalRequest(list1) ?? '未知';

                setState(() {
                  _platformVersion = serial;
                });
              },
              child: const Text('获取序列号')),
          ElevatedButton(
              onPressed: () {
                initPlatformState();
              },
              child: const Text('打印收据')),
          ElevatedButton(
              onPressed: () async {
                List list1 = [
                  {'type': 'getScanCode()'}
                ];
                dynamic scancode =
                    await _internalPlugin.internalRequest(list1) ?? '未知';

                setState(() {
                  _platformVersion = scancode;
                });
              },
              child: const Text('获取扫描码')),
        ]),
      ),
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Builder(builder: (context) => getBody(context)),
    );
  }
}

更多关于Flutter内部访问插件internal的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter内部访问插件internal的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter开发中,访问和使用内部插件(通常指平台特定的原生代码)是一个常见的需求。Flutter提供了插件机制,允许开发者通过MethodChannel、BasicMessageChannel等通信方式与原生平台(iOS和Android)进行交互。虽然直接访问“internal”插件可能涉及到一些不推荐或未公开API的使用,但我会展示一个标准的方式来创建和使用一个自定义插件,这在实践中是访问内部功能的标准做法。

以下是一个简单的例子,展示如何创建一个Flutter插件来访问原生平台的功能。

1. 创建Flutter插件项目

首先,你需要创建一个Flutter插件项目。如果你还没有Flutter SDK,请先安装它。

flutter create --template=plugin my_custom_plugin
cd my_custom_plugin

2. 实现原生代码

iOS (Swift)

ios/Classes/MyCustomPlugin.swift中,添加如下代码:

import Flutter

public class MyCustomPlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterRegistrar) {
    let channel = FlutterMethodChannel(name: "my_custom_plugin", binaryMessenger: registrar.messenger())
    let instance = MyCustomPlugin()
    registrar.addMethodCallDelegate(instance, channel: channel)
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    switch call.method {
    case "getPlatformVersion":
      let version = UIDevice.current.systemVersion
      result(version)
    default:
      result(FlutterMethodNotImplemented)
    }
  }
}

Android (Kotlin)

android/src/main/kotlin/com/example/my_custom_plugin/MyCustomPlugin.kt中,添加如下代码:

package com.example.my_custom_plugin

import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import android.os.Build
import android.content.Context

class MyCustomPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
  private lateinit var channel: MethodChannel
  private var context: Context? = null

  override fun onAttachedToEngine(binding: FlutterPluginBinding) {
    channel = MethodChannel(binding.binaryMessenger, "my_custom_plugin")
    channel.setMethodCallHandler(this)
  }

  override fun onMethodCall(call: MethodCall, result: Result) {
    if (call.method == "getPlatformVersion") {
      result.success(Build.VERSION.RELEASE)
    } else {
      result.notImplemented()
    }
  }

  override fun onDetachedFromEngine(binding: FlutterPluginBinding) {
    channel.setMethodCallHandler(null)
  }

  override fun onAttachedToActivity(binding: ActivityPluginBinding) {
    context = binding.activity
  }

  override fun onDetachedFromActivityForConfigChanges() {
    context = null
  }

  override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
    context = binding.activity
  }

  override fun onDetachedFromActivity() {
    context = null
  }
}

3. 在Flutter中使用插件

在你的Flutter项目的pubspec.yaml文件中添加对本地插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  my_custom_plugin:
    path: ../my_custom_plugin

然后,在Flutter代码中调用插件:

import 'package:flutter/material.dart';
import 'package:my_custom_plugin/my_custom_plugin.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  static const platform = MethodChannel('my_custom_plugin');

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Center(
          child: FutureBuilder<String>(
            future: platform.invokeMethod('getPlatformVersion'),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasError) {
                  return Text('Failed to get platform version: ${snapshot.error}');
                } else {
                  return Text('Running on: ${snapshot.data}');
                }
              } else {
                return CircularProgressIndicator();
              }
            },
          ),
        ),
      ),
    );
  }
}

这个示例展示了如何创建一个简单的Flutter插件,该插件在iOS和Android平台上获取系统版本信息,并在Flutter应用中显示。这是访问和使用Flutter内部插件功能的一种标准做法。如果你需要访问更复杂的内部功能,通常也是通过类似的方式封装原生代码并提供给Flutter使用。

回到顶部