LoginSignup
3
1

More than 1 year has passed since last update.

【Flutter】スクリーンショットをSNSにシェアする

Posted at

概要

Flutterで作成したアプリにシェア機能を実装した際の備忘録です。
3つのパッケージを利用することで、簡単に任意のWidgetのスクリーンショットを添付してSNSなどへシェアすることができるようになります。

下記はiOSシミュレータでサンプルコードを実行した際の挙動になります。
シミュレータのためシェア先の候補が少ないですが、TwitterやInstagramなどがインストールされている場合は、シェア先の候補として自動的に表示されるようになります。
名称未設定.001.jpeg

サンプルコード

動作環境

$ flutter --version
Flutter 2.8.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 77d935af4d (8 weeks ago) • 2021-12-16 08:37:33 -0800
Engine • revision 890a5fca2e
Tools • Dart 2.15.1

使用するパッケージ

()内は本記事で使用しているパッケージのバージョン
share_plus(3.0.4)
screenshot(1.2.3)
path_provider(2.0.9)

要点

main.dart全文
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:screenshot/screenshot.dart';
import 'package:share_plus/share_plus.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _screenShotController = ScreenshotController();
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Screenshot(
      controller: _screenShotController,
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text(
                'You have pushed the button this many times:',
              ),
              Text(
                '$_counter',
                style: Theme.of(context).textTheme.headline4,
              ),
              ElevatedButton(
                onPressed: () async {
                  const _shareText = 'シェアするテキスト';
                  final _screenshot = await _screenShotController.capture(delay: const Duration(milliseconds: 10));

                  if (_screenshot != null) {
                    // スクリーンショットをドキュメントディレクトリに保存
                    final _documentDirectoryPath = await getApplicationDocumentsDirectory();
                    final imagePath = await File('${_documentDirectoryPath.path}/screenshot.png').create();
                    await imagePath.writeAsBytes(_screenshot);
                    // スクリーンショットとテキストをシェア
                    await Share.shareFiles([imagePath.path], text: _shareText);
                  }
                },
                child: const Text('スクリーンショットをシェア'),
              ),
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        ),
      ),
    );
  }
}


1. 必要なパッケージをimportします。

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:screenshot/screenshot.dart';
import 'package:share_plus/share_plus.dart';

2. ScreenshotControllerクラスのインスタンスを作成します。

// FYI: https://github.com/sakatech-jp/flutter_screenshot_share/blob/master/lib/main.dart#L36
final _screenShotController = ScreenshotController();

3. スクリーンショットに含めたいWidgetをScreenshotでWrapして、controllerに2.で宣言した_screenShotControllerを指定します。

// FYI: https://github.com/sakatech-jp/flutter_screenshot_share/blob/master/lib/main.dart#L47-L48
@override
Widget build(BuildContext context) {
  return Screenshot(
    controller: _screenShotController,
    child: Scaffold(....)
  );
}

4. シェア用のボタンがタップされた際の挙動をonPressedに定義します。

// FYI: https://github.com/sakatech-jp/flutter_screenshot_share/blob/master/lib/main.dart#L64-L79
onPressed: () async {
  const _shareText = 'シェアするテキスト';
  final _screenshot = await _screenShotController.capture(delay: const Duration(milliseconds: 10));

  if (_screenshot != null) {
    // スクリーンショットをドキュメントディレクトリに保存
    final _documentDirectoryPath = await getApplicationDocumentsDirectory();
    final imagePath = await File('${_documentDirectoryPath.path}/screenshot.png').create();
    await imagePath.writeAsBytes(_screenshot);
    // スクリーンショットとテキストをシェア
    await Share.shareFiles([imagePath.path], text: _shareText);
  }
},
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1