我有一个flutter应用程序,它为每个平台(移动、网络、窗口)使用不同的webview插件。
虽然我能够基于
import
和 web
的 mobile
平台,但我无法导入 Windows。
如果不是移动或网络,我尝试添加其他条件,但它正在使用
mobile
插件。
import 'package:eam_flutter/form/mobileui.dart'
if (dart.library.html) 'package:eam_flutter/form/webui.dart'
as multiPlatform;
import 'package:eam_flutter/form/windowui.dart'
if (dart.library.html) 'package:eam_flutter/form/webui.dart'
if (dart.library.io) 'package:eam_flutter/form/mobileui.dart'
as multiPlatform;
如何为 Windows 指定条件导入?
对于发现此问题的其他人,请注意,接受的答案并不是所提出问题的答案。问题的答案是你不能。无法使用条件导入来获得移动设备和桌面设备之间的不同行为;请参阅 Dart 团队的评论。
因为 window 属于 dart io,所以没有条件导入支持。
我有这个解决方法并发现它有效。
我最终使用不同的包导入为每个平台创建文件。
import 'package:flutter/foundation.dart' show kIsWeb;
import 'dart:io' as io;
if(kIsWeb){
{
return WebPage(); //your web page with web package import in it
}
else if (!kIsWeb && io.Platform.isWindows) {
return WindowsPage(); //your window page with window package import in it
}
else if(!kIsWeb && io.Platform.isAndroid) {
return AndroidPage(); //your android page with android package import in it
}
//you can add others condition...
检查这个示例 您需要创建 2 个文件,一个用于网络,另一个用于操作系统,并在导入时使用条件
改为使用该包。
universal_html
也许我们不再需要条件导入。 看下面的代码:
import 'package:package1/package1.dart';
import 'package:package2/package2.dart';
const keepFunc1 = bool.fromEnvironment('KEEP_FUNC1');
dynamic result2;
void main() {
if (keepFunc1) {
result2 = Calculator1()..addOne(1);
} else {
result2 = Calculator2()..addOne(1);
}
runApp(const MyApp());
}
如果
KEEP_FUNC1
环境变量未指定为true
。 package1
和类Caculator1
不会被打包到apk或ipa中。
更多详情,请参阅我写的答案这里。
因此我们可以导入所有包并使用 const 环境值来决定导入哪些包。摇树机制足够智能,可以删除未使用的部分。
平台条件导入是可能的,但很棘手。
首先,您必须检查编译时是否存在特定于平台的库(您可能想要使用):
my_widget.dart
:
export 'my_widget/stub.dart'
if (dart.library.js_util) 'my_widget/web.dart'
if (dart.library.io) 'my_widget/mobile.dart';
然后定义一个“存根”(认为是“接口”),它定义可用的方法,但可以直接编译:
my_widget/stub.dart
:
import 'package:flutter/material.dart';
typedef HandleEventFn = Future<void> Function();
Widget buildMyWidget({required BuildContext context, HandleEventFn? onEvent}) {
throw UnimplementedError("This is not implemented for the current platform");
}
现在您可以定义一个实际的实现,如果
dart.library.js_util
存在(例如在网络上):
my_widget/web.dart
:
import 'package:flutter/material.dart';
import 'stub.dart';
Widget buildMyWidget({required BuildContext context, HandleEventFn? onEvent}) {
return TextButton(onPressed: onEvent, child: const Text("Push me (WEB)"));
}
以及实际的实现,当
dart.library.io
存在时使用(例如在移动设备上):
my_widget/mobile.dart
:
import 'package:flutter/material.dart';
import 'stub.dart';
Widget buildMyWidget({required BuildContext context, HandleEventFn? onEvent}) {
return TextButton(onPressed: onEvent, child: const Text("Push me (MOBILE)"));
}
请注意,
onEvent
的类型在存根中定义为HandleEventFn
,这样您就可以轻松调整它,而无需更改多个文件(DRY原则)。
对我来说,解决方案是使用通用 html 包:
https://pub.dev/packages/universal_html
dependencies:
universal_html: ^2.2.4
import 'package:universal_html/html.dart' as html;
String getCurrentUrl() {
// Access the 'window.location' object from JavaScript
var url = html.window.location.href;
if (url.split(":").length > 1) {
return url;
}
return defaultUrl;
}