以下の記事で「screenshot」パッケージでいけそうと書いていますが、更に調査するとダメでした。画面内の要素(スクリーン高さ)までしか撮れていないことがわかりました。
「来期アニメ」アプリで、自分が今期観ているアニメや来期観る予定のアニメを一覧にしてSNSにシェアする機能を作りたいと思ってます。
テキストでやるとTwitterの140文字制限にかかってしまうので、スクリーンショット画像を共有出来ればよいと考えました。
そこで必要となるのは、スクロール外にあるWidgetまでスクリーンショットの対象とする機能、です。たくさんのアニメを見る人の場合、スクロールが発生する可能性があるからです。
いくつかパッケージを調べて「screenshot」パッケージなら出来るみたいなことをstack overflowで見たので試してみました。

dependencies:
screenshot: ^1.2.3
Widgetツリー内の指定Widgetを撮る方法と、Widgetツリー外のWidgetを撮る方法があるようです。
- Widgetツリー内のWidgetを撮る方法
# キャプチャを実行する
onPressed: () {
screenshotController
.capture(delay: Duration(milliseconds: 10))
.then((capturedImage) async {
ShowCapturedWidget(context, capturedImage!);
}).catchError((onError) {
print(onError);
});
},
# キャプチャしたい範囲を囲む
Screenshot(
controller: screenshotController,
child: ...
# キャプチャした画像を表示する
Future<dynamic> ShowCapturedWidget(
BuildContext context, Uint8List capturedImage) {
return showDialog(
useSafeArea: false,
context: context,
builder: (context) => Scaffold(
appBar: AppBar(
title: Text("Captured widget screenshot"),
),
body: SingleChildScrollView(
child: Center(
child: capturedImage != null
? Image.memory(capturedImage)
: Container()),
),
),
);
}
結果は以下の通り。
最初にスクリーンショットの対象となる画面。「あいうえ」の下にスクロール(「おかきくけこ」)できます。「フルスクリーンショット」ボタンで、スクリーンショットを撮ります。

撮ったスクリーンショット画像を別画面で表示しました。
「あいうえ」より下にスクロールできません。
つまり、画面の見えている部分しかスクリーンショット撮れていないということです。
これは期待の動作ではありません。

- Widgetツリー外のWidgetを撮る方法
# キャプチャを実行する
onPressed: () {
# キャプチャしたいウィジェット(スクロールあり)を作る
var container = SingleChildScrollView(
child: Container(
padding: const EdgeInsets.all(30.0),
decoration: BoxDecoration(
border: Border.all(
color: Colors.blueAccent, width: 5.0),
color: Colors.redAccent,
),
child: Column(
children: [
Text('か', style: TextStyle(fontSize: 50)),
Text('き', style: TextStyle(fontSize: 50)),
Text('く', style: TextStyle(fontSize: 50)),
Text('け', style: TextStyle(fontSize: 100)),
Text('こ', style: TextStyle(fontSize: 100)),
Text('さ', style: TextStyle(fontSize: 100)),
Text('し', style: TextStyle(fontSize: 100)),
Text('す', style: TextStyle(fontSize: 100)),
Text('せ', style: TextStyle(fontSize: 100)),
Text('そ', style: TextStyle(fontSize: 100)),
],
),
),
);
# キャプチャを実行する
screenshotController
.captureFromWidget(
InheritedTheme.captureAll(
context, Material(child: container)),
delay: Duration(seconds: 1))
.then((capturedImage) {
ShowCapturedWidget(context, capturedImage);
});
},
),
# キャプチャした画像を表示する(↑と同じ)
Future<dynamic> ShowCapturedWidget(
BuildContext context, Uint8List capturedImage) {
return showDialog(
useSafeArea: false,
context: context,
builder: (context) => Scaffold(
appBar: AppBar(
title: Text("Captured widget screenshot"),
),
body: SingleChildScrollView(
child: Center(
child: capturedImage != null
? Image.memory(capturedImage)
: Container()),
),
),
);
}
結果は以下の通り。
最初にスクリーンショット対象画面。Widgetツリー外のため、画面には見えていませんが「かきくけこさしすせそ」(スクロールあり)を仕込んでいます。
「ウィジェットツリー外のウィジェットをとる」ボタンで、スクリーンショットを撮ります。

撮ったスクリーンショットを別画面で表示しました。
「かきくけ」より下にスクロールして、「さし」まで表示できます。
つまり、画面の見えてない部分のスクリーンショットが撮れている期待の動作です!
しかし、スクロールは出来ますが、「さし」までしか出ません(「すせそ」までスクロールできないう)。この原因は調べる必要があります。もしかしたら画像の縦サイズの最大値が決まっている?

↓スクロール

今日のところは、スクロール外の部分までスクリーンショットを撮れる可能性がわかったところまでとします。「さし」までしか出ない問題は明日以降に調査する予定です。
個人開発で自作アプリ作ってます。是非インストールお願いします。
コメント
[…] Flutterで画面外の要素も含めたフルスクリーンショットを撮る方法を調べて… […]