この記事では、手軽に「Widgetを画像にしてSNS等にシェアする」方法をご紹介します(背景のカレンダーは関係ありません)。

画像にしたいWidgetを作成
画像にしたいWidget(仮にWidgetAとします)を、RepaintBoundary
で囲みます。そして、後でkeyを使ってこのRepaintBoundary
を探して取得する必要があるので、keyをつけておきます。convertWidgetToImageKeyはconvert_widget_to_image_key.dart
でグローバル変数として宣言しておきます。
x_widget.dart
import 'package:flutter/material.dart';
import 'convert_widget_to_image_key.dart';
return RepaintBoundary(
key: convertWidgetToImageKey,
child: WidgetA(), // 画像にしてシェアしたいWidget
);
convert_widget_to_image_key.dart
import 'package:flutter/material.dart';
final convertWidgetToImageKey = GlobalKey();
ここで注意しておくべきなのは、WidgetAが高さを持たない場合です。例えばColumnを使っている場合、うまく画像にすることができません。そういうときは、Container(height: 100, child: WidgetA())
のようにしてContainerで囲んで高さを指定しましょう。同じように、背景色を持たない場合はbackgroundColorを指定しましょう。
Widgetを画像にする
GlobalKey
を使ってWidgetを探し出し、そのWidgetがRenderRepaintBoundary
なら画像化してくれます。
widget_to_image_converter.dart
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
class WidgetToImageConverter {
Future<ByteData> exportToImage(GlobalKey globalKey) async {
final boundary =
globalKey.currentContext.findRenderObject() as RenderRepaintBoundary;
final image = await boundary.toImage(
pixelRatio: 3,
);
final byteData = await image.toByteData(
format: ui.ImageByteFormat.png,
);
return byteData;
}
}
シェアのロジック
flutter_esys_shareを使います。おそらく、現状画像をシェアするならこのライブラリが一番有力かと思います(2021年12月20日現在はshare_plusでもできるようです)。結構前からメンテされていないのが心配ですが、普通に使えます。
share_provider.dart
import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'package:flutter/material.dart';
class ShareProvider {
Future<void> shareImageAndText(
String text, GlobalKey globalKey) async {
final bytes = await WidgetToImageConverter().exportToImage(globalKey);
await Share.file(
'shared image', 'share.png', bytes.buffer.asUint8List(), 'image/png',
text: text);
}
}
シェアボタン
適当にボタンを使ってShareProvider().shareImageAndText(key)
を呼べば、シェアのボトムシートが出てきます。
import 'package:flutter/material.dart';
import 'convert_widget_to_image_key.dart';
IconButton(
onPressed: () {
ShareProvider().shareImageAndText('test', convertWidgekToImageKey);
},
icon: const Icon(
Icons.share,
),
);
たったこれだけです!簡単!
意外とこれを実装していないアプリは多いので、差別化になるかもしれません。