@@ -2,6 +2,7 @@ import 'dart:async';
2
2
3
3
import 'package:flutter/foundation.dart' ;
4
4
import 'package:flutter/material.dart' ;
5
+ import 'package:flutter/rendering.dart' ;
5
6
6
7
import 'base.dart' ;
7
8
@@ -60,72 +61,108 @@ class _WebviewScaffoldState extends State<WebviewScaffold> {
60
61
@override
61
62
void dispose () {
62
63
super .dispose ();
64
+ _resizeTimer? .cancel ();
63
65
webviewReference.close ();
64
66
webviewReference.dispose ();
65
67
}
66
68
67
69
@override
68
70
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
+ );
99
109
}
110
+ }
100
111
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);
103
118
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;
108
120
109
- var height = mediaQuery.size.height - top;
121
+ @override
122
+ RenderObject createRenderObject (BuildContext context) {
123
+ return _WebviewPlaceholderRender (
124
+ onRectChanged: onRectChanged,
125
+ );
126
+ }
110
127
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
+ }
116
133
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 ();
123
150
}
151
+ }
124
152
125
- if (height < 0.0 ) {
126
- height = 0.0 ;
153
+ void notifyRect () {
154
+ if (_callback != null && _rect != null ) {
155
+ _callback (_rect);
127
156
}
157
+ }
128
158
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
+ }
130
167
}
131
168
}
0 commit comments