Flutter之RepaintBoundary组件

https://www.jianshu.com/p/6801ecbee03d

/**
 * const RepaintBoundary({ Key key, Widget child })
 */

//import 'dart:io';
//import 'dart:typed_data';
//import 'package:flutter/material.dart';
//import 'package:flutter/rendering.dart';
//import 'dart:ui'; //import 'package:path_provider/path_provider.dart'; class Widget_RepaintBoundary_State extends State<Widget_RepaintBoundary_Page> { GlobalKey globalKey = new GlobalKey(); Future<File> _capture() async { try { RenderRepaintBoundary boundary = globalKey.currentContext .findRenderObject(); //boundary.toImage()转化为ui.Image对象,不会自动为包裹的组件添加背景,不设置可能会缺失背景 var image = await boundary.toImage(pixelRatio: window.devicePixelRatio); //将image转化为byteData ByteData byteData = await image.toByteData(format: ImageByteFormat.png); //这个对象就是图片数据 Uint8List pngBytes = byteData.buffer.asUint8List(); String sTempDir = (await getTemporaryDirectory()).path; bool isDirExist = await Directory(sTempDir).exists(); if (!isDirExist) { Directory(sTempDir).create(); } Future<File> file = File(sTempDir + "/abc.png").writeAsBytes(pngBytes); return file; } catch (e) { print(e); } return null; } 


作者:习惯了_就好
链接:https://www.jianshu.com/p/6801ecbee03d
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

如何截图

前面说到本篇会用到RepaintBoundary组件,接下来把它套在你想要截图的组件的外层,想截全屏的话就套在最外面就可以,Flutter的这种写法习惯就好。
同时定义一个Key用来操作这个组件

class _MyHomePageState extends State<MyHomePage> { GlobalKey rootWidgetKey = GlobalKey(); ... @override Widget build(BuildContext context) { return RepaintBoundary( key: rootWidgetKey, child: Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Column( ..... ), ), ); } } 

通过rootWidgetKey可以拿到RenderRepaintBoundary的引用,进来拿到内部组件的截图:

class _MyHomePageState extends State<MyHomePage> { GlobalKey rootWidgetKey = GlobalKey(); Future<Uint8List> _capturePng() async { try { RenderRepaintBoundary boundary = rootWidgetKey.currentContext.findRenderObject(); var image = await boundary.toImage(pixelRatio: 3.0); ByteData byteData = await image.toByteData(format: ImageByteFormat.png); Uint8List pngBytes = byteData.buffer.asUint8List(); return pngBytes;//这个对象就是图片数据 } catch (e) { print(e); } return null; } ... } 

通过上面一系列的方法调用,就拿到了一个Unit8List类型的图片数据。

显示截图

而Unit8List类型的图片数据的显示也非常简单,通过Image.memory方法从内存中加载图片,下面附上完整的State代码:

class _MyHomePageState extends State<MyHomePage> { GlobalKey rootWidgetKey = GlobalKey(); List<Uint8List> images = List(); _capturePng() async { try { RenderRepaintBoundary boundary = rootWidgetKey.currentContext.findRenderObject(); var image = await boundary.toImage(pixelRatio: 3.0); ByteData byteData = await image.toByteData(format: ImageByteFormat.png); Uint8List pngBytes = byteData.buffer.asUint8List(); images.add(pngBytes); setState(() {}); return pngBytes; } catch (e) { print(e); } return null; } @override Widget build(BuildContext context) { return RepaintBoundary( key: rootWidgetKey, child: Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Column( children: <Widget>[ Image.network( "http://qiniu.nightfarmer.top/test.gif", width: 300, height: 300, ), FlatButton( onPressed: () { this._capturePng(); }, child: Text("全屏截图"), ), Expanded( child: ListView.builder( itemBuilder: (context, index) { return Image.memory( images[index], fit: BoxFit.cover, ); }, itemCount: images.length, scrollDirection: Axis.horizontal, ), ) ], ), ), ); } }


作者:NightFarmer
链接:https://www.jianshu.com/p/da3f23d0843b
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 
 
 
 
 

猜你喜欢

转载自www.cnblogs.com/sundaysme/p/12706793.html
今日推荐