flutter_webview_plugin.dart 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import 'dart:async';
  2. import 'package:flutter/services.dart';
  3. import 'package:flutter/material.dart';
  4. const _kChannel = 'flutter_webview_plugin';
  5. // TODO: more genral state for iOS/android
  6. enum WebViewState { shouldStart, startLoad, finishLoad }
  7. /// Singleton Class that communicate with a fullscreen Webview Instance
  8. /// Have to be instanciate after `runApp` called.
  9. class FlutterWebViewPlugin {
  10. final MethodChannel _channel;
  11. final StreamController<Null> _onDestroy = new StreamController.broadcast();
  12. final StreamController<Null> _onBackPressed =
  13. new StreamController.broadcast();
  14. final StreamController<String> _onUrlChanged =
  15. new StreamController.broadcast();
  16. final StreamController<Null> _onStateChanged =
  17. new StreamController.broadcast();
  18. final StreamController<Null> _onError = new StreamController.broadcast();
  19. FlutterWebViewPlugin() : _channel = const MethodChannel(_kChannel) {
  20. _channel.setMethodCallHandler(_handleMessages);
  21. }
  22. Future<Null> _handleMessages(MethodCall call) async {
  23. switch (call.method) {
  24. case "onDestroy":
  25. _onDestroy.add(null);
  26. break;
  27. case "onBackPressed":
  28. _onBackPressed.add(null);
  29. break;
  30. case "onUrlChanged":
  31. _onUrlChanged.add(call.arguments["url"]);
  32. break;
  33. case "onState":
  34. _onStateChanged.add(call.arguments);
  35. break;
  36. case "onError":
  37. _onError.add(call.arguments);
  38. break;
  39. }
  40. }
  41. /// Listening the OnDestroy LifeCycle Event for Android
  42. /// content is Map for url
  43. Stream<Null> get onDestroy => _onDestroy.stream;
  44. /// Listening url changed
  45. /// iOS WebView: worked
  46. /// android: worked
  47. Stream<Null> get onUrlChanged => _onUrlChanged.stream;
  48. /// Listening the onBackPressed Event for Android
  49. /// content null
  50. /// iOS WebView: worked
  51. /// android: worked
  52. Stream<Null> get onBackPressed => _onBackPressed.stream;
  53. /// Listening the onState Event for iOS WebView and Android
  54. /// content is Map for type: {shouldStart|startLoad|finishLoad}
  55. /// more detail than other events
  56. /// iOS WebView: worked
  57. /// android: Not for now.
  58. Stream<Null> get onStateChanged => _onStateChanged.stream;
  59. /// Start the Webview with [url]
  60. /// - [withJavascript] enable Javascript or not for the Webview
  61. /// iOS WebView: Not implemented yet
  62. /// android: Implemented.
  63. /// - [clearCache] clear the cache of the Webview
  64. /// iOS WebView: Not implemented yet
  65. /// iOS WkWebView: TODO: later
  66. /// android: Implemented
  67. /// - [clearCookies] clear all cookies of the Webview
  68. /// iOS WebView: Not implemented yet
  69. /// iOS WkWebView: will implement later
  70. /// android: Implemented
  71. /// - [hidden] not show
  72. /// iOS WebView: not shown(addSubView) in ViewController
  73. /// android: Implemented
  74. /// [fullScreen]: show in full screen mode, default true
  75. /// iOS WebView: without rect, show in full screen mode
  76. /// android: Implemented
  77. /// [rect]: show in rect(not full screen)
  78. /// iOS WebView: worked
  79. /// android: Implemented
  80. /// [enableAppScheme]: false will enable all schemes, true only for httt/https/about
  81. /// iOS WebView: worked
  82. /// android: Not implemented yet
  83. /// [userAgent]: set the User-Agent of WebView
  84. /// iOS WebView: worked
  85. /// android: Implemented
  86. Future<Null> launch(String url,
  87. {bool withJavascript: true,
  88. bool clearCache: false,
  89. bool clearCookies: false,
  90. bool hidden: false,
  91. bool fullScreen: true,
  92. bool enableAppScheme: true,
  93. Rect rect: null,
  94. String userAgent: null}) async {
  95. Map<String, dynamic> args = {
  96. "url": url,
  97. "withJavascript": withJavascript,
  98. "clearCache": clearCache,
  99. "hidden": hidden,
  100. "clearCookies": clearCookies,
  101. "fullScreen": fullScreen,
  102. "enableAppScheme": enableAppScheme,
  103. "userAgent": userAgent
  104. };
  105. if (!fullScreen) assert(rect != null);
  106. if (rect != null) {
  107. args["rect"] = {
  108. "left": rect.left,
  109. "top": rect.top,
  110. "width": rect.width,
  111. "height": rect.height
  112. };
  113. }
  114. await _channel.invokeMethod('launch', args);
  115. }
  116. /// iOS WebView: worked
  117. /// android: implemented
  118. Future<String> evalJavascript(String code) {
  119. return _channel.invokeMethod('eval', {"code": code});
  120. }
  121. /// Close the Webview
  122. /// Will trigger the [onDestroy] event
  123. Future<Null> close() => _channel.invokeMethod("close");
  124. }