Переглянути джерело

Merge branch 'master' into progress

Rafal Wachol 7 роки тому
батько
коміт
54facef2f0

+ 1 - 0
README.md

@@ -143,6 +143,7 @@ Future<Null> launch(String url,
          String userAgent: null,
          String userAgent: null,
          bool withZoom: false,
          bool withZoom: false,
          bool withLocalStorage: true,
          bool withLocalStorage: true,
+         bool withLocalUrl: true,
          bool scrollBar: true});
          bool scrollBar: true});
 ```
 ```
 ```dart
 ```dart

+ 2 - 3
android/build.gradle

@@ -8,7 +8,7 @@ buildscript {
     }
     }
 
 
     dependencies {
     dependencies {
-        classpath 'com.android.tools.build:gradle:3.1.2'
+        classpath 'com.android.tools.build:gradle:3.2.1'
     }
     }
 }
 }
 
 
@@ -21,8 +21,7 @@ allprojects {
 apply plugin: 'com.android.library'
 apply plugin: 'com.android.library'
 
 
 android {
 android {
-    compileSdkVersion 25
-    buildToolsVersion '27.0.3'
+    compileSdkVersion 27
 
 
     defaultConfig {
     defaultConfig {
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

+ 3 - 5
example/android/app/build.gradle

@@ -16,7 +16,6 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
 
 
 android {
 android {
     compileSdkVersion 27
     compileSdkVersion 27
-    buildToolsVersion '27.0.3'
 
 
     lintOptions {
     lintOptions {
         disable 'InvalidPackage'
         disable 'InvalidPackage'
@@ -24,7 +23,6 @@ android {
 
 
     defaultConfig {
     defaultConfig {
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
-        
         // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
         // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
         applicationId "com.yourcompany.flutter_webview_plugin_example"
         applicationId "com.yourcompany.flutter_webview_plugin_example"
     }
     }
@@ -43,7 +41,7 @@ flutter {
 }
 }
 
 
 dependencies {
 dependencies {
-    androidTestCompile 'com.android.support:support-annotations:25.0.0'
-    androidTestCompile 'com.android.support.test:runner:0.5'
-    androidTestCompile 'com.android.support.test:rules:0.5'
+    androidTestImplementation 'com.android.support:support-annotations:27.0.0'
+    androidTestImplementation 'com.android.support.test:runner:1.0.2'
+    androidTestImplementation 'com.android.support.test:rules:1.0.2'
 }
 }

+ 0 - 2
example/android/app/src/main/AndroidManifest.xml

@@ -3,8 +3,6 @@
     android:versionCode="1"
     android:versionCode="1"
     android:versionName="0.0.1">
     android:versionName="0.0.1">
 
 
-    <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" />
-
     <!-- The INTERNET permission is required for development. Specifically,
     <!-- The INTERNET permission is required for development. Specifically,
          flutter needs it to communicate with the running application
          flutter needs it to communicate with the running application
          to allow setting breakpoints, to provide hot reload, etc.
          to allow setting breakpoints, to provide hot reload, etc.

+ 1 - 1
example/android/build.gradle

@@ -8,7 +8,7 @@ buildscript {
     }
     }
 
 
     dependencies {
     dependencies {
-        classpath 'com.android.tools.build:gradle:3.1.1'
+        classpath 'com.android.tools.build:gradle:3.2.1'
     }
     }
 }
 }
 
 

+ 92 - 68
example/lib/main.dart

@@ -14,6 +14,8 @@ void main() {
 }
 }
 
 
 class MyApp extends StatelessWidget {
 class MyApp extends StatelessWidget {
+  final flutterWebviewPlugin = new FlutterWebviewPlugin();
+
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
     return new MaterialApp(
     return new MaterialApp(
@@ -37,6 +39,29 @@ class MyApp extends StatelessWidget {
                   child: Text('Waiting.....'),
                   child: Text('Waiting.....'),
                 ),
                 ),
               ),
               ),
+              bottomNavigationBar: BottomAppBar(
+                  child: Row(
+                children: <Widget>[
+                  IconButton(
+                    icon: const Icon(Icons.arrow_back_ios),
+                    onPressed: () {
+                      flutterWebviewPlugin.goBack();
+                    },
+                  ),
+                  IconButton(
+                    icon: const Icon(Icons.arrow_forward_ios),
+                    onPressed: () {
+                      flutterWebviewPlugin.goForward();
+                    },
+                  ),
+                  IconButton(
+                    icon: const Icon(Icons.autorenew),
+                    onPressed: () {
+                      flutterWebviewPlugin.reload();
+                    },
+                  ),
+                ],
+              )),
             )
             )
       },
       },
     );
     );
@@ -168,77 +193,76 @@ class _MyHomePageState extends State<MyHomePage> {
       appBar: new AppBar(
       appBar: new AppBar(
         title: const Text('Plugin example app'),
         title: const Text('Plugin example app'),
       ),
       ),
-      body: new Column(
-        mainAxisAlignment: MainAxisAlignment.center,
-        children: [
-          new Container(
-            padding: const EdgeInsets.all(24.0),
-            child: new TextField(controller: _urlCtrl),
-          ),
-          new RaisedButton(
-            onPressed: () {
-              flutterWebviewPlugin.launch(selectedUrl,
-                  rect: new Rect.fromLTWH(
-                      0.0, 0.0, MediaQuery.of(context).size.width, 300.0),
-                  userAgent: kAndroidUserAgent);
-            },
-            child: const Text('Open Webview (rect)'),
-          ),
-          new RaisedButton(
-            onPressed: () {
-              flutterWebviewPlugin.launch(selectedUrl, hidden: true);
-            },
-            child: const Text('Open "hidden" Webview'),
-          ),
-          new RaisedButton(
-            onPressed: () {
-              flutterWebviewPlugin.launch(selectedUrl);
-            },
-            child: const Text('Open Fullscreen Webview'),
-          ),
-          new RaisedButton(
-            onPressed: () {
-              Navigator.of(context).pushNamed('/widget');
-            },
-            child: const Text('Open widget webview'),
-          ),
-          new Container(
-            padding: const EdgeInsets.all(24.0),
-            child: new TextField(controller: _codeCtrl),
-          ),
-          new RaisedButton(
-            onPressed: () {
-              final future =
-                  flutterWebviewPlugin.evalJavascript(_codeCtrl.text);
-              future.then((String result) {
-                setState(() {
-                  _history.add('eval: $result');
+      body: SingleChildScrollView(
+        child: new Column(
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: [
+            new Container(
+              padding: const EdgeInsets.all(24.0),
+              child: new TextField(controller: _urlCtrl),
+            ),
+            new RaisedButton(
+              onPressed: () {
+                flutterWebviewPlugin.launch(selectedUrl,
+                    rect: new Rect.fromLTWH(0.0, 0.0, MediaQuery.of(context).size.width, 300.0), userAgent: kAndroidUserAgent);
+              },
+              child: const Text('Open Webview (rect)'),
+            ),
+            new RaisedButton(
+              onPressed: () {
+                flutterWebviewPlugin.launch(selectedUrl, hidden: true);
+              },
+              child: const Text('Open "hidden" Webview'),
+            ),
+            new RaisedButton(
+              onPressed: () {
+                flutterWebviewPlugin.launch(selectedUrl);
+              },
+              child: const Text('Open Fullscreen Webview'),
+            ),
+            new RaisedButton(
+              onPressed: () {
+                Navigator.of(context).pushNamed('/widget');
+              },
+              child: const Text('Open widget webview'),
+            ),
+            new Container(
+              padding: const EdgeInsets.all(24.0),
+              child: new TextField(controller: _codeCtrl),
+            ),
+            new RaisedButton(
+              onPressed: () {
+                final future = flutterWebviewPlugin.evalJavascript(_codeCtrl.text);
+                future.then((String result) {
+                  setState(() {
+                    _history.add('eval: $result');
+                  });
                 });
                 });
-              });
-            },
-            child: const Text('Eval some javascript'),
-          ),
-          new RaisedButton(
-            onPressed: () {
-              setState(() {
-                _history.clear();
-              });
-              flutterWebviewPlugin.close();
-            },
-            child: const Text('Close'),
-          ),
-          new RaisedButton(
-            onPressed: () {
-              flutterWebviewPlugin.getCookies().then((m) {
+              },
+              child: const Text('Eval some javascript'),
+            ),
+            new RaisedButton(
+              onPressed: () {
                 setState(() {
                 setState(() {
-                  _history.add('cookies: $m');
+                  _history.clear();
+                });
+                flutterWebviewPlugin.close();
+              },
+              child: const Text('Close'),
+            ),
+            new RaisedButton(
+              onPressed: () {
+                flutterWebviewPlugin.getCookies().then((m) {
+                  setState(() {
+                    _history.add('cookies: $m');
+                  });
                 });
                 });
-              });
-            },
-            child: const Text('Cookies'),
-          ),
-          new Text(_history.join('\n'))
-        ],
+              },
+              child: const Text('Cookies'),
+            ),
+            new Text(_history.join('\n'))
+          ],
+        ),
       ),
       ),
     );
     );
   }
   }

+ 25 - 1
ios/Classes/FlutterWebviewPlugin.m

@@ -15,7 +15,7 @@ static NSString *const CHANNEL_NAME = @"flutter_webview_plugin";
                methodChannelWithName:CHANNEL_NAME
                methodChannelWithName:CHANNEL_NAME
                binaryMessenger:[registrar messenger]];
                binaryMessenger:[registrar messenger]];
     
     
-    UIViewController *viewController = (UIViewController *)registrar.messenger;
+    UIViewController *viewController = [UIApplication sharedApplication].delegate.window.rootViewController;
     FlutterWebviewPlugin* instance = [[FlutterWebviewPlugin alloc] initWithViewController:viewController];
     FlutterWebviewPlugin* instance = [[FlutterWebviewPlugin alloc] initWithViewController:viewController];
     
     
     [registrar addMethodCallDelegate:instance channel:channel];
     [registrar addMethodCallDelegate:instance channel:channel];
@@ -58,6 +58,15 @@ static NSString *const CHANNEL_NAME = @"flutter_webview_plugin";
     } else if ([@"stopLoading" isEqualToString:call.method]) {
     } else if ([@"stopLoading" isEqualToString:call.method]) {
         [self stopLoading];
         [self stopLoading];
         result(nil);
         result(nil);
+    } else if ([@"back" isEqualToString:call.method]) {
+        [self back];
+        result(nil);
+    } else if ([@"forward" isEqualToString:call.method]) {
+        [self forward];
+        result(nil);
+    } else if ([@"reload" isEqualToString:call.method]) {
+        [self reload];
+        result(nil);
     } else {
     } else {
         result(FlutterMethodNotImplemented);
         result(FlutterMethodNotImplemented);
     }
     }
@@ -204,6 +213,21 @@ static NSString *const CHANNEL_NAME = @"flutter_webview_plugin";
         [self.webview stopLoading];
         [self.webview stopLoading];
     }
     }
 }
 }
+- (void)back {
+    if (self.webview != nil) {
+        [self.webview goBack];
+    }
+}
+- (void)forward {
+    if (self.webview != nil) {
+        [self.webview goForward];
+    }
+}
+- (void)reload {
+    if (self.webview != nil) {
+        [self.webview reload];
+    }
+}
 
 
 #pragma mark -- WkWebView Delegate
 #pragma mark -- WkWebView Delegate
 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction

+ 0 - 3
lib/src/base.dart

@@ -148,15 +148,12 @@ class FlutterWebviewPlugin {
   Future close() => _channel.invokeMethod('close');
   Future close() => _channel.invokeMethod('close');
 
 
   /// Reloads the WebView.
   /// Reloads the WebView.
-  /// This is only available on Android for now.
   Future reload() => _channel.invokeMethod('reload');
   Future reload() => _channel.invokeMethod('reload');
 
 
   /// Navigates back on the Webview.
   /// Navigates back on the Webview.
-  /// This is only available on Android for now.
   Future goBack() => _channel.invokeMethod('back');
   Future goBack() => _channel.invokeMethod('back');
 
 
   /// Navigates forward on the Webview.
   /// Navigates forward on the Webview.
-  /// This is only available on Android for now.
   Future goForward() => _channel.invokeMethod('forward');
   Future goForward() => _channel.invokeMethod('forward');
 
 
   // Hides the webview
   // Hides the webview

+ 86 - 49
lib/src/webview_scaffold.dart

@@ -2,6 +2,7 @@ import 'dart:async';
 
 
 import 'package:flutter/foundation.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter/rendering.dart';
 
 
 import 'base.dart';
 import 'base.dart';
 
 
@@ -73,6 +74,7 @@ class _WebviewScaffoldState extends State<WebviewScaffold> {
   @override
   @override
   void dispose() {
   void dispose() {
     super.dispose();
     super.dispose();
+    _resizeTimer?.cancel();
     webviewReference.close();
     webviewReference.close();
     if (widget.hidden) {
     if (widget.hidden) {
       _onStateChanged.cancel();
       _onStateChanged.cancel();
@@ -82,64 +84,99 @@ class _WebviewScaffoldState extends State<WebviewScaffold> {
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
-    if (_rect == null) {
-      _rect = _buildRect(context);
-      webviewReference.launch(widget.url,
-          headers: widget.headers,
-          withJavascript: widget.withJavascript,
-          clearCache: widget.clearCache,
-          clearCookies: widget.clearCookies,
-          enableAppScheme: widget.enableAppScheme,
-          userAgent: widget.userAgent,
-          rect: _rect,
-          withZoom: widget.withZoom,
-          withLocalStorage: widget.withLocalStorage,
-          withLocalUrl: widget.withLocalUrl,
-          scrollBar: widget.scrollBar,
-          hidden: widget.hidden);
-    } else {
-      final rect = _buildRect(context);
-      if (_rect != rect) {
-        _rect = rect;
-        _resizeTimer?.cancel();
-        _resizeTimer = new Timer(new Duration(milliseconds: 300), () {
-          // avoid resizing to fast when build is called multiple time
-          webviewReference.resize(_rect);
-        });
-      }
-    }
-    return new Scaffold(
-        appBar: widget.appBar,
-        persistentFooterButtons: widget.persistentFooterButtons,
-        bottomNavigationBar: widget.bottomNavigationBar,
-        body: widget.initialChild ?? const Center(child: const CircularProgressIndicator()));
+    return Scaffold(
+      appBar: widget.appBar,
+      persistentFooterButtons: widget.persistentFooterButtons,
+      bottomNavigationBar: widget.bottomNavigationBar,
+      body: _WebviewPlaceholder(
+        onRectChanged: (Rect value) {
+          if (_rect == null) {
+            _rect = value;
+            webviewReference.launch(
+              widget.url,
+              headers: widget.headers,
+              withJavascript: widget.withJavascript,
+              clearCache: widget.clearCache,
+              clearCookies: widget.clearCookies,
+              enableAppScheme: widget.enableAppScheme,
+              userAgent: widget.userAgent,
+              rect: _rect,
+              withZoom: widget.withZoom,
+              withLocalStorage: widget.withLocalStorage,
+              withLocalUrl: widget.withLocalUrl,
+              scrollBar: widget.scrollBar,
+            );
+          } else {
+            if (_rect != value) {
+              _rect = value;
+              _resizeTimer?.cancel();
+              _resizeTimer = Timer(const Duration(milliseconds: 250), () {
+                // avoid resizing to fast when build is called multiple time
+                webviewReference.resize(_rect);
+              });
+            }
+          }
+        },
+        child: widget.initialChild ?? const Center(child: const CircularProgressIndicator()),
+      ),
+    );
+  }
+}
+
+class _WebviewPlaceholder extends SingleChildRenderObjectWidget {
+  const _WebviewPlaceholder({
+    Key key,
+    @required this.onRectChanged,
+    Widget child,
+  }) : super(key: key, child: child);
+  
+  final ValueChanged<Rect> onRectChanged;
+
+  @override
+  RenderObject createRenderObject(BuildContext context) {
+    return _WebviewPlaceholderRender(
+      onRectChanged: onRectChanged,
+    );
+  }
+  
+  @override
+  void updateRenderObject(BuildContext context, _WebviewPlaceholderRender renderObject) {
+    renderObject..onRectChanged = onRectChanged;
   }
   }
+}
 
 
-  Rect _buildRect(BuildContext context) {
-    final fullscreen = widget.appBar == null;
+class _WebviewPlaceholderRender extends RenderProxyBox {
+  ValueChanged<Rect> _callback;
+  Rect _rect;
 
 
-    final mediaQuery = MediaQuery.of(context);
-    final topPadding = widget.primary ? mediaQuery.padding.top : 0.0;
-    final top = fullscreen ? 0.0 : widget.appBar.preferredSize.height + topPadding;
+  _WebviewPlaceholderRender({
+    RenderBox child,
+    ValueChanged<Rect> onRectChanged,
+  })  : _callback = onRectChanged,
+        super(child);
 
 
-    var height = mediaQuery.size.height - top;
+  Rect get rect => _rect;
 
 
-    if (widget.bottomNavigationBar != null) {
-      height -= 56.0 +
-          mediaQuery.padding.bottom; // todo(lejard_h) find a way to determine bottomNavigationBar programmatically
+  set onRectChanged(ValueChanged<Rect> callback) {
+    if (callback != _callback) {
+      _callback = callback;
+      notifyRect();
     }
     }
+  }
 
 
-    if (widget.persistentFooterButtons != null) {
-      height -= 53.0; // todo(lejard_h) find a way to determine persistentFooterButtons programmatically
-      if (widget.bottomNavigationBar == null) {
-        height -= mediaQuery.padding.bottom;
-      }
+  void notifyRect() {
+    if (_callback != null && _rect != null) {
+      _callback(_rect);
     }
     }
+  }
 
 
-    if (height < 0.0) {
-      height = 0.0;
+  @override
+  void paint(PaintingContext context, Offset offset) {
+    super.paint(context, offset);
+    final rect = offset & size;
+    if (_rect != rect) {
+      _rect = rect;
+      notifyRect();
     }
     }
-
-    return new Rect.fromLTWH(0.0, top, mediaQuery.size.width, height);
   }
   }
 }
 }

+ 1 - 0
pubspec.yaml

@@ -6,6 +6,7 @@ authors:
 - Pedia <kpedia@163.com>
 - Pedia <kpedia@163.com>
 homepage: https://github.com/dart-flitter/flutter_webview_plugin
 homepage: https://github.com/dart-flitter/flutter_webview_plugin
 version: 0.2.1+2
 version: 0.2.1+2
+maintainer: Simon Lightfoot (@slightfoot)
 
 
 environment:
 environment:
   sdk: ">=2.0.0-dev <3.0.0"
   sdk: ">=2.0.0-dev <3.0.0"