Flutter之RepaintBoundary组件
Posted sundaysme
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
以上是关于Flutter之RepaintBoundary组件的主要内容,如果未能解决你的问题,请参考以下文章