@@ -2,6 +2,7 @@ import 'dart:async';
22
33import 'package:flutter/foundation.dart' ;
44import 'package:flutter/material.dart' ;
5+ import 'package:flutter/rendering.dart' ;
56
67import 'base.dart' ;
78
@@ -60,72 +61,108 @@ class _WebviewScaffoldState extends State<WebviewScaffold> {
6061 @override
6162 void dispose () {
6263 super .dispose ();
64+ _resizeTimer? .cancel ();
6365 webviewReference.close ();
6466 webviewReference.dispose ();
6567 }
6668
6769 @override
6870 Widget build (BuildContext context) {
69- if (_rect == null ) {
70- _rect = _buildRect (context);
71- webviewReference.launch (widget.url,
72- headers: widget.headers,
73- withJavascript: widget.withJavascript,
74- clearCache: widget.clearCache,
75- clearCookies: widget.clearCookies,
76- enableAppScheme: widget.enableAppScheme,
77- userAgent: widget.userAgent,
78- rect: _rect,
79- withZoom: widget.withZoom,
80- withLocalStorage: widget.withLocalStorage,
81- withLocalUrl: widget.withLocalUrl,
82- scrollBar: widget.scrollBar);
83- } else {
84- final rect = _buildRect (context);
85- if (_rect != rect) {
86- _rect = rect;
87- _resizeTimer? .cancel ();
88- _resizeTimer = new Timer (new Duration (milliseconds: 300 ), () {
89- // avoid resizing to fast when build is called multiple time
90- webviewReference.resize (_rect);
91- });
92- }
93- }
94- return new Scaffold (
95- appBar: widget.appBar,
96- persistentFooterButtons: widget.persistentFooterButtons,
97- bottomNavigationBar: widget.bottomNavigationBar,
98- body: const Center (child: const CircularProgressIndicator ()));
71+ return Scaffold (
72+ appBar: widget.appBar,
73+ persistentFooterButtons: widget.persistentFooterButtons,
74+ bottomNavigationBar: widget.bottomNavigationBar,
75+ body: _WebviewPlaceholder (
76+ onRectChanged: (Rect value) {
77+ if (_rect == null ) {
78+ _rect = value;
79+ webviewReference.launch (
80+ widget.url,
81+ headers: widget.headers,
82+ withJavascript: widget.withJavascript,
83+ clearCache: widget.clearCache,
84+ clearCookies: widget.clearCookies,
85+ enableAppScheme: widget.enableAppScheme,
86+ userAgent: widget.userAgent,
87+ rect: _rect,
88+ withZoom: widget.withZoom,
89+ withLocalStorage: widget.withLocalStorage,
90+ withLocalUrl: widget.withLocalUrl,
91+ scrollBar: widget.scrollBar,
92+ );
93+ } else {
94+ if (_rect != value) {
95+ _rect = value;
96+ _resizeTimer? .cancel ();
97+ _resizeTimer = Timer (const Duration (milliseconds: 250 ), () {
98+ // avoid resizing to fast when build is called multiple time
99+ webviewReference.resize (_rect);
100+ });
101+ }
102+ }
103+ },
104+ child: const Center (
105+ child: CircularProgressIndicator (),
106+ ),
107+ ),
108+ );
99109 }
110+ }
100111
101- Rect _buildRect (BuildContext context) {
102- final fullscreen = widget.appBar == null ;
112+ class _WebviewPlaceholder extends SingleChildRenderObjectWidget {
113+ const _WebviewPlaceholder ({
114+ Key key,
115+ @required this .onRectChanged,
116+ Widget child,
117+ }) : super (key: key, child: child);
103118
104- final mediaQuery = MediaQuery .of (context);
105- final topPadding = widget.primary ? mediaQuery.padding.top : 0.0 ;
106- final top =
107- fullscreen ? 0.0 : widget.appBar.preferredSize.height + topPadding;
119+ final ValueChanged <Rect > onRectChanged;
108120
109- var height = mediaQuery.size.height - top;
121+ @override
122+ RenderObject createRenderObject (BuildContext context) {
123+ return _WebviewPlaceholderRender (
124+ onRectChanged: onRectChanged,
125+ );
126+ }
110127
111- if (widget.bottomNavigationBar != null ) {
112- height -= 56.0 +
113- mediaQuery.padding
114- .bottom; // todo(lejard_h) find a way to determine bottomNavigationBar programmatically
115- }
128+ @override
129+ void updateRenderObject ( BuildContext context, _WebviewPlaceholderRender renderObject) {
130+ renderObject..onRectChanged = onRectChanged;
131+ }
132+ }
116133
117- if (widget.persistentFooterButtons != null ) {
118- height -=
119- 53.0 ; // todo(lejard_h) find a way to determine persistentFooterButtons programmatically
120- if (widget.bottomNavigationBar == null ) {
121- height -= mediaQuery.padding.bottom;
122- }
134+ class _WebviewPlaceholderRender extends RenderProxyBox {
135+ ValueChanged <Rect > _callback;
136+ Rect _rect;
137+
138+ _WebviewPlaceholderRender ({
139+ RenderBox child,
140+ ValueChanged <Rect > onRectChanged,
141+ }) : _callback = onRectChanged,
142+ super (child);
143+
144+ Rect get rect => _rect;
145+
146+ set onRectChanged (ValueChanged <Rect > callback) {
147+ if (callback != _callback) {
148+ _callback = callback;
149+ notifyRect ();
123150 }
151+ }
124152
125- if (height < 0.0 ) {
126- height = 0.0 ;
153+ void notifyRect () {
154+ if (_callback != null && _rect != null ) {
155+ _callback (_rect);
127156 }
157+ }
128158
129- return new Rect .fromLTWH (0.0 , top, mediaQuery.size.width, height);
159+ @override
160+ void paint (PaintingContext context, Offset offset) {
161+ super .paint (context, offset);
162+ final rect = offset & size;
163+ if (_rect != rect) {
164+ _rect = rect;
165+ notifyRect ();
166+ }
130167 }
131168}
0 commit comments