Flutter内部访问插件internal的使用
Flutter内部访问插件internal的使用
你将通过编辑此README文件来学习如何在Bitbucket中编辑文件。
编辑一个文件
你将从编辑此README文件开始,以了解如何在Bitbucket中编辑文件。
- 点击左侧的源码。
- 从文件列表中点击README.md链接。
- 点击编辑按钮。
- 删除以下文本:删除此行以从Bitbucket更改README。
- 完成更改后,点击提交,然后在对话框中再次点击提交。提交页面将会打开,并且你会看到刚刚所做的更改。
- 返回到源码页面。
创建一个文件
接下来,你将在该仓库中添加一个新文件。
- 在源码页面顶部点击新建文件按钮。
- 给文件命名为contributors.txt。
- 在空白文件空间中输入你的名字。
- 点击提交,然后在对话框中再次点击提交。
- 返回到源码页面。
在继续之前,你可以探索一下仓库。你已经见过源码页面,但请检查一下提交记录、分支和设置页面。
克隆一个仓库
使用以下步骤从SourceTree克隆。克隆允许你在本地工作于你的文件。如果你还没有SourceTree,下载并安装它。如果你更喜欢从命令行克隆,可以参见克隆一个仓库。
- 在源码标题下,你会看到克隆按钮。点击那个按钮。
- 现在点击在SourceTree中检出。你可能需要创建或登录SourceTree账户。
- 当你在SourceTree中看到新建克隆对话框时,如果愿意可以更新目标路径和名称,然后点击克隆。
- 打开你刚创建的目录,查看你的仓库文件。
现在你对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
更多关于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使用。