文章

处理一个Web平台特定的导入

处理一个 Web 平台特定的导入

处理一个 Web 平台特定的导入

这里实现一个同时兼容移动端(Android、iOS)web端的网页嵌套功能,比如嵌套百度 https://www.baiducon

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import 'package:flutter/material.dart';
import 'package:xtbp_flutter/widgets/base_widget.dart';
import 'web_view_platform.dart';

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

  @override
  State<StatefulWidget> createState() => _CockpitWidgetState();
}

class _CockpitWidgetState extends State<CockpitWidget> {
  late CustomWebViewPlatform _platform;

  @override
  void initState() {
    super.initState();
    _platform = CustomWebViewPlatform(); // 使用工厂方法创建实例
  }

  @override
  void dispose() {
    _platform.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return BaseWidget(title: '驾驶舱', child: _platform.buildView(context));
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import 'package:flutter/material.dart';
import 'web_view_web.dart' if (dart.library.io) 'web_view_mobile.dart';

abstract class CustomWebViewPlatform {
  Widget buildView(BuildContext context);

  void dispose();

  void loadUrl(String url);

  factory CustomWebViewPlatform() {
    return MyWebView();
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'web_view_platform.dart';

class MyWebView implements CustomWebViewPlatform {
  late WebViewController controller;

  MyWebView() {
    _initMobileView();
  }

  void _initMobileView() {
    controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setNavigationDelegate(
        NavigationDelegate(
          onProgress: (int progress) => print('Loading: $progress%'),
          onPageStarted: (String url) => print('Started: $url'),
          onPageFinished: (String url) => print('Finished: $url'),
          onNavigationRequest: (NavigationRequest request) {
            return request.url.startsWith('https://www.baidu.com/')
                ? NavigationDecision.prevent
                : NavigationDecision.navigate;
          },
        ),
      )
      ..loadRequest(Uri.parse('https://baidu.com'));
  }

  @override
  Widget buildView(BuildContext context) {
    return WebViewWidget(controller: controller);
  }

  @override
  void dispose() {
    // 移动端可能需要清理资源
  }

  @override
  void loadUrl(String url) {
    controller.loadRequest(Uri.parse(url));
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import 'dart:ui_web' as ui_web;
import 'package:flutter/material.dart';
import 'package:web/web.dart' as web;
import 'web_view_platform.dart';


class MyWebView implements CustomWebViewPlatform {
  late String _viewType;
  late web.HTMLIFrameElement _iframe;

  MyWebView() {
    _initWebView();
  }

  void _initWebView() {
    _viewType = 'web-view-${DateTime.now().millisecondsSinceEpoch}';
    _iframe = web.document.createElement('iframe') as web.HTMLIFrameElement;
    _iframe.src = 'https://baidu.com';
    _iframe.style.border = 'none';
    _iframe.style.width = '100%';
    _iframe.style.height = '100%';
    _iframe.allowFullscreen = true;
    _iframe.allow = 'accelerometer; gyroscope';

    _iframe.onLoad.listen((_) {
      print('WebView loaded');
    });

    ui_web.platformViewRegistry.registerViewFactory(_viewType, (int viewId) => _iframe);
  }

  @override
  Widget buildView(BuildContext context) {
    return SizedBox(
      width: MediaQuery.of(context).size.width,
      height: MediaQuery.of(context).size.height,
      child: HtmlElementView(viewType: _viewType, onPlatformViewCreated: (_) {}),
    );
  }

  @override
  void dispose() {
    // Web端不需要特殊清理
  }

  @override
  void loadUrl(String url) {
    _iframe.src = url;
  }
}
本文由作者按照 CC BY 4.0 进行授权