如何在颤振中为 Web 编写平台特定的代码?

时间:2021-07-20 13:17:11

标签: flutter flutter-web flutter-packages flutter-ios flutter-android

在 Flutter 中,我们使用平台通道来调用特定于平台的 API,无论是在 Android 上的 Kotlin 或 Java 代码中,还是在 iOS 上的 Swift 或 Objective-C 代码中。

如何在 flutter 中实现与 web 相同的功能?如何使用 npm 包并编写一些 javascript 代码并将结果发送到 flutter?这甚至可能吗?有为 Android 和 iOS 编写平台特定代码的官方文档,但我找不到任何为网络编写平台特定代码的文档。

另外,我尝试使用 js 包。如果这是必须用于这种情况的,如何使用它?

1 个答案:

答案 0 :(得分:0)

这就是我在 Flutter Web 上显示 Hubspot 聊天的方式。 我有一个 Hubspot 文件夹:

  • index.html
  • script.js
  • style.css

然后是带有 webview_flutter_plus 插件的 Flutter Widget:

class HubspotWebview extends StatefulWidget {
  @override
  _HubspotWebviewState createState() => _HubspotWebviewState();
}

class _HubspotWebviewState extends State<HubspotWebview> {
  final _javascriptChannels = Set<JavascriptChannel>();
  bool loading = true;

  @override
  void initState() {
    super.initState();
    _javascriptChannels.add(JavascriptChannel(
        onMessageReceived: (JavascriptMessage message) {
          debugPrint('message: ' + message.message);
          _toggleLoading();
        },
        name: 'Loading'));
  }

  @override
  Widget build(BuildContext context) {
    final path = '${kIsWeb ? 'assets/' : ''}assets/hubspot_web_page/index.html';
    final key = 'web_bot_key';
    if (kIsWeb) {
      ui.platformViewRegistry.registerViewFactory(
          key,
              (int viewId) => IFrameElement()
            ..width = '640'
            ..height = '360'
            ..src = path
            ..style.border = 'none'
            ..onLoadedData.listen((event) {
              _toggleLoading();
            }));
    }
    return Scaffold(
      appBar: new AppBar(
          backgroundColor: MyColors.blue_business,
          title: MyText.subtitle(
            getText('business_help_chat', backUpText: 'Help Chat'),
            color: MyColors.white_rice,
          )),
      body: Stack(
        children: [
          kIsWeb
              ? HtmlElementView(viewType: key)
              : WebViewPlus(
            javascriptMode: JavascriptMode.unrestricted,
            initialUrl: path,
            javascriptChannels: _javascriptChannels,
          ),
          if (loading)
            Center(child: CircularProgressIndicator()),
        ],
      ),
    );
  }

  void _toggleLoading() => setState(() => loading = !loading);
}

在 Javascript 文件 Loading.postMessage('') 上触发 toggleLoading() 在 Flutter 上:

  function onConversationsAPIReady() {
    window.hsConversationsSettings = {
      inlineEmbedSelector: '#hubspot-conversations-inline-parent',
      enableWidgetCookieBanner: true,
      disableAttachment: true
    };
    window.history.pushState({}, 'bot', '?bot=true');
    window.HubSpotConversations.widget.refresh({openToNewThread: true});
    Loading.postMessage('');
  }

  if (window.HubSpotConversations) {
    onConversationsAPIReady();
  } else {
    window.hsConversationsOnReady = [onConversationsAPIReady];
  }