📱

Flutter で share_plus を利用してシェア機能を実装する

に公開

これなに

Flutter でのシェア機能実装の備忘録

利用するパッケージ

必須

今回の実装のキーパッケージ、OSのシェア機能を利用可能にする

https://pub.dev/packages/share_plus

任意

具体的な実装の際に画像ファイル取得のために利用しただけなので、ファイルピッカーから取得しても良いと思う

https://pub.dev/packages/screenshot

モジュール化したコード

  • flutter pub add share_plus でパッケージを取得
  • メソッド化した以下のコードを呼び出して共有を実装
  • 画像とシェアするときのメッセージにあたる image, subject は任意に設定
  • text は必須にしている
import 'package:flutter/material.dart';
import 'package:share_plus/share_plus.dart';

class ShareImageAndTextController {
  void shareImageAndText(XFile? image, String? subject, String text) async {
    try {
      if (image != null) {
        await Share.shareXFiles(
          [
            image,
          ],
          subject: subject,
          text: text,
        );
      } else {
        await Share.share(
          text,
          subject: subject,
        );
      }
    } catch (e) {
      debugPrint('*** ${DateTime.now()} | shareImageAndText: error: $e');
    }
  }
}

具体的なメソッドの実行を行ったコード

  • demo_share_project というサンプルプロジェクトを作成しました
  • このままコピペするだけだと呼び出せません
  • インポートパスは任意のものに変更して利用してください

main.dart

import 'package:flutter/material.dart';
import 'package:demo_share_project/view/my_home_page_view.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Demo app to share',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Demo app to share!'),
    );
  }
}

convert_image_data_controller.dart

import 'dart:io';
import 'dart:typed_data';
import 'package:share_plus/share_plus.dart';
import 'package:path_provider/path_provider.dart';

class ConvertImageDataController {
  Future<XFile> convertImageData(Uint8List? imageData) async {
    XFile res = XFile('');

    if (imageData != null) {
      final directory = await getTemporaryDirectory();
      final imagePath = '${directory.path}/screenshot.png';
      final imageFile = File(imagePath);
      await imageFile.writeAsBytes(imageData);
      res = XFile(imagePath);
    }

    return res;
  }
}

my_home_page_view.dart

import 'package:flutter/material.dart';
import 'package:screenshot/screenshot.dart';
import 'package:demo_share_project/controller/convert_image_data_controller.dart';
import 'package:demo_share_project/controller/share_image_and_text_controller.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  final ScreenshotController _screenShotController = ScreenshotController();
  final ShareImageAndTextController _shareImageAndTextController =
      ShareImageAndTextController();
  final ConvertImageDataController _convertImageDataController =
      ConvertImageDataController();

  
  Widget build(BuildContext context) {
    return Screenshot(
      controller: _screenShotController,
      child: Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
          title: Text(widget.title),
        ),
        body: Center(
          child: ElevatedButton(
            child: const Text('Take screenshot and share'),
            onPressed: () async {
              final screenshot = await _screenShotController.capture(
                delay: const Duration(milliseconds: 500),
              );
              final imageXfile = await _convertImageDataController
                  .convertImageData(screenshot);

              _shareImageAndTextController.shareImageAndText(
                  imageXfile, 'Test subject!', 'Test to share!');
            },
          ),
        ),
      ),
    );
  }
}

実際のスクリーンショット

image.png

image.png

サンプルリポジトリ

今回ついでに作成したので公開しておきます。
ご自由にご利用ください。

https://github.com/su3-hokkaido/demo_share_project

GitHubで編集を提案

Discussion