Showing
2 changed files
with
64 additions
and
7 deletions
1 | +import 'dart:async'; | ||
1 | import 'dart:math'; | 2 | import 'dart:math'; |
2 | import 'dart:typed_data'; | 3 | import 'dart:typed_data'; |
3 | 4 | ||
@@ -100,6 +101,16 @@ class _PdfPreviewState extends State<PdfPreview> { | @@ -100,6 +101,16 @@ class _PdfPreviewState extends State<PdfPreview> { | ||
100 | 101 | ||
101 | Object error; | 102 | Object error; |
102 | 103 | ||
104 | + int preview; | ||
105 | + | ||
106 | + double updatePosition; | ||
107 | + | ||
108 | + final scrollController = ScrollController(); | ||
109 | + | ||
110 | + final transformationController = TransformationController(); | ||
111 | + | ||
112 | + Timer previewUpdate; | ||
113 | + | ||
103 | static const Map<String, PdfPageFormat> defaultPageFormats = | 114 | static const Map<String, PdfPageFormat> defaultPageFormats = |
104 | <String, PdfPageFormat>{ | 115 | <String, PdfPageFormat>{ |
105 | 'A4': PdfPageFormat.a4, | 116 | 'A4': PdfPageFormat.a4, |
@@ -178,6 +189,8 @@ class _PdfPreviewState extends State<PdfPreview> { | @@ -178,6 +189,8 @@ class _PdfPreviewState extends State<PdfPreview> { | ||
178 | @override | 189 | @override |
179 | void didUpdateWidget(covariant PdfPreview oldWidget) { | 190 | void didUpdateWidget(covariant PdfPreview oldWidget) { |
180 | if (oldWidget.build != widget.build) { | 191 | if (oldWidget.build != widget.build) { |
192 | + preview = null; | ||
193 | + updatePosition = null; | ||
181 | pages.clear(); | 194 | pages.clear(); |
182 | _raster(); | 195 | _raster(); |
183 | } | 196 | } |
@@ -196,6 +209,8 @@ class _PdfPreviewState extends State<PdfPreview> { | @@ -196,6 +209,8 @@ class _PdfPreviewState extends State<PdfPreview> { | ||
196 | }); | 209 | }); |
197 | } | 210 | } |
198 | 211 | ||
212 | + previewUpdate?.cancel(); | ||
213 | + previewUpdate = Timer(const Duration(seconds: 1), () { | ||
199 | final mq = MediaQuery.of(context); | 214 | final mq = MediaQuery.of(context); |
200 | dpi = (min(mq.size.width - 16, widget.maxPageWidth ?? double.infinity)) * | 215 | dpi = (min(mq.size.width - 16, widget.maxPageWidth ?? double.infinity)) * |
201 | mq.devicePixelRatio / | 216 | mq.devicePixelRatio / |
@@ -203,6 +218,7 @@ class _PdfPreviewState extends State<PdfPreview> { | @@ -203,6 +218,7 @@ class _PdfPreviewState extends State<PdfPreview> { | ||
203 | 72; | 218 | 72; |
204 | 219 | ||
205 | _raster(); | 220 | _raster(); |
221 | + }); | ||
206 | super.didChangeDependencies(); | 222 | super.didChangeDependencies(); |
207 | } | 223 | } |
208 | 224 | ||
@@ -242,8 +258,33 @@ class _PdfPreviewState extends State<PdfPreview> { | @@ -242,8 +258,33 @@ class _PdfPreviewState extends State<PdfPreview> { | ||
242 | 258 | ||
243 | return Scrollbar( | 259 | return Scrollbar( |
244 | child: ListView.builder( | 260 | child: ListView.builder( |
261 | + controller: scrollController, | ||
245 | itemCount: pages.length, | 262 | itemCount: pages.length, |
246 | - itemBuilder: (BuildContext context, int index) => pages[index], | 263 | + itemBuilder: (BuildContext context, int index) => GestureDetector( |
264 | + onDoubleTap: () { | ||
265 | + setState(() { | ||
266 | + updatePosition = scrollController.position.pixels; | ||
267 | + preview = index; | ||
268 | + transformationController.value.setIdentity(); | ||
269 | + }); | ||
270 | + }, | ||
271 | + child: pages[index], | ||
272 | + ), | ||
273 | + ), | ||
274 | + ); | ||
275 | + } | ||
276 | + | ||
277 | + Widget _zoomPreview() { | ||
278 | + return GestureDetector( | ||
279 | + onDoubleTap: () { | ||
280 | + setState(() { | ||
281 | + preview = null; | ||
282 | + }); | ||
283 | + }, | ||
284 | + child: InteractiveViewer( | ||
285 | + transformationController: transformationController, | ||
286 | + maxScale: 5, | ||
287 | + child: Center(child: pages[preview]), | ||
247 | ), | 288 | ), |
248 | ); | 289 | ); |
249 | } | 290 | } |
@@ -252,6 +293,26 @@ class _PdfPreviewState extends State<PdfPreview> { | @@ -252,6 +293,26 @@ class _PdfPreviewState extends State<PdfPreview> { | ||
252 | Widget build(BuildContext context) { | 293 | Widget build(BuildContext context) { |
253 | final theme = Theme.of(context); | 294 | final theme = Theme.of(context); |
254 | 295 | ||
296 | + Widget page; | ||
297 | + | ||
298 | + if (preview != null) { | ||
299 | + page = _zoomPreview(); | ||
300 | + } else { | ||
301 | + page = Container( | ||
302 | + constraints: widget.maxPageWidth != null | ||
303 | + ? BoxConstraints(maxWidth: widget.maxPageWidth) | ||
304 | + : null, | ||
305 | + child: _createPreview(), | ||
306 | + ); | ||
307 | + | ||
308 | + if (updatePosition != null) { | ||
309 | + Timer.run(() { | ||
310 | + scrollController.jumpTo(updatePosition); | ||
311 | + updatePosition = null; | ||
312 | + }); | ||
313 | + } | ||
314 | + } | ||
315 | + | ||
255 | final Widget scrollView = Container( | 316 | final Widget scrollView = Container( |
256 | decoration: widget.scrollViewDecoration ?? | 317 | decoration: widget.scrollViewDecoration ?? |
257 | BoxDecoration( | 318 | BoxDecoration( |
@@ -263,12 +324,7 @@ class _PdfPreviewState extends State<PdfPreview> { | @@ -263,12 +324,7 @@ class _PdfPreviewState extends State<PdfPreview> { | ||
263 | ), | 324 | ), |
264 | width: double.infinity, | 325 | width: double.infinity, |
265 | alignment: Alignment.center, | 326 | alignment: Alignment.center, |
266 | - child: Container( | ||
267 | - constraints: widget.maxPageWidth != null | ||
268 | - ? BoxConstraints(maxWidth: widget.maxPageWidth) | ||
269 | - : null, | ||
270 | - child: _createPreview(), | ||
271 | - ), | 327 | + child: page, |
272 | ); | 328 | ); |
273 | 329 | ||
274 | final actions = <Widget>[]; | 330 | final actions = <Widget>[]; |
-
Please register or login to post a comment