如何在 Flutter 移动端、Web 端和窗口端添加条件导入?

问题描述 投票:0回答:7

我有一个flutter应用程序,它为每个平台(移动、网络、窗口)使用不同的webview插件。
虽然我能够基于

import
web
mobile
平台,但我无法导入 Windows。

如果不是移动或网络,我尝试添加其他条件,但它正在使用

mobile
插件。

  1. 这就是我导入网络和移动包的方式(工作)。
import 'package:eam_flutter/form/mobileui.dart'
    if (dart.library.html) 'package:eam_flutter/form/webui.dart'
    as multiPlatform;   
  1. 这就是我导入 Web、移动和 Windows 包的方法(不工作,它显示移动 Web 视图异常,因为它不支持桌面)。
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 指定条件导入?

flutter dart import flutter-web flutter-windows
7个回答
19
投票

对于发现此问题的其他人,请注意,接受的答案并不是所提出问题的答案。问题的答案是你不能。无法使用条件导入来获得移动设备和桌面设备之间的不同行为;请参阅 Dart 团队的评论


6
投票

因为 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
投票

检查这个示例 您需要创建 2 个文件,一个用于网络,另一个用于操作系统,并在导入时使用条件


2
投票

改为使用该包。

universal_html

1
投票

也许我们不再需要条件导入。 看下面的代码:

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
不会被打包到apkipa中。

更多详情,请参阅我写的答案这里

因此我们可以导入所有包并使用 const 环境值来决定导入哪些包。摇树机制足够智能,可以删除未使用的部分。


0
投票

平台条件导入是可能的,但很棘手。

首先,您必须检查编译时是否存在特定于平台的库(您可能想要使用):

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原则)。


0
投票

对我来说,解决方案是使用通用 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;
}
© www.soinside.com 2019 - 2024. All rights reserved.