Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 67 additions & 68 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -160,77 +160,76 @@ class _MyHomePageState extends State<MyHomePage> {
appBar: new AppBar(
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(() {
_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'))
],
),
),
);
}
Expand Down
139 changes: 88 additions & 51 deletions lib/src/webview_scaffold.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

import 'base.dart';

Expand Down Expand Up @@ -60,72 +61,108 @@ class _WebviewScaffoldState extends State<WebviewScaffold> {
@override
void dispose() {
super.dispose();
_resizeTimer?.cancel();
webviewReference.close();
webviewReference.dispose();
}

@override
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);
} 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: 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: const Center(
child: CircularProgressIndicator(),
),
),
);
}
}

Rect _buildRect(BuildContext context) {
final fullscreen = widget.appBar == null;
class _WebviewPlaceholder extends SingleChildRenderObjectWidget {
const _WebviewPlaceholder({
Key key,
@required this.onRectChanged,
Widget child,
}) : super(key: key, child: child);

final mediaQuery = MediaQuery.of(context);
final topPadding = widget.primary ? mediaQuery.padding.top : 0.0;
final top =
fullscreen ? 0.0 : widget.appBar.preferredSize.height + topPadding;
final ValueChanged<Rect> onRectChanged;

var height = mediaQuery.size.height - top;
@override
RenderObject createRenderObject(BuildContext context) {
return _WebviewPlaceholderRender(
onRectChanged: onRectChanged,
);
}

if (widget.bottomNavigationBar != null) {
height -= 56.0 +
mediaQuery.padding
.bottom; // todo(lejard_h) find a way to determine bottomNavigationBar programmatically
}
@override
void updateRenderObject(BuildContext context, _WebviewPlaceholderRender renderObject) {
renderObject..onRectChanged = onRectChanged;
}
}

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;
}
class _WebviewPlaceholderRender extends RenderProxyBox {
ValueChanged<Rect> _callback;
Rect _rect;

_WebviewPlaceholderRender({
RenderBox child,
ValueChanged<Rect> onRectChanged,
}) : _callback = onRectChanged,
super(child);

Rect get rect => _rect;

set onRectChanged(ValueChanged<Rect> callback) {
if (callback != _callback) {
_callback = callback;
notifyRect();
}
}

if (height < 0.0) {
height = 0.0;
void notifyRect() {
if (_callback != null && _rect != null) {
_callback(_rect);
}
}

return new Rect.fromLTWH(0.0, top, mediaQuery.size.width, height);
@override
void paint(PaintingContext context, Offset offset) {
super.paint(context, offset);
final rect = offset & size;
if (_rect != rect) {
_rect = rect;
notifyRect();
}
}
}