Flutter社交分享插件share_plus的使用

发布于 1周前 作者 htzhanglong 来自 Flutter

Flutter社交分享插件share_plus的使用

简介

share_plus 是一个Flutter插件,允许你通过平台的分享对话框分享内容。它封装了Android上的ACTION_SEND Intent、iOS上的UIActivityViewController或等效的平台内容分享方法。

share_plus pub points pub package

平台支持

方法 Android iOS MacOS Web Linux Windows
share
shareUri
shareXFiles

注意:Windows和Linux通过 “mailto” 来分享文本。

需求

  • Flutter >=3.22.0
  • Dart >=3.4.0 <4.0.0
  • iOS >=12.0
  • MacOS >=10.14
  • Android compileSDK 34
  • Java 17
  • Android Gradle Plugin >=8.3.0
  • Gradle wrapper >=8.4

使用方法

添加依赖

在你的pubspec.yaml文件中添加share_plus作为依赖:

dependencies:
  share_plus: ^latest_version

导入库

import 'package:share_plus/share_plus.dart';

分享文本

Share.share('check out my website https://example.com');

你可以添加一个可选的主题参数,用于分享到邮件时:

Share.share('check out my website https://example.com', subject: 'Look what I made!');

还可以检查分享结果:

final result = await Share.share('check out my website https://example.com');

if (result.status == ShareResultStatus.success) {
  print('Thank you for sharing my website!');
}

分享文件

要分享一个或多个文件,可以使用shareXFiles方法:

final result = await Share.shareXFiles([XFile('${directory.path}/image.jpg')], text: 'Great picture');

if (result.status == ShareResultStatus.success) {
  print('Thank you for sharing the picture!');
}

对于多个文件:

final result = await Share.shareXFiles([XFile('${directory.path}/image1.jpg'), XFile('${directory.path}/image2.jpg')]);

if (result.status == ShareResultStatus.dismissed) {
  print('Did you not like the pictures?');
}

对于Web平台,如果浏览器支持Web Share API,则会使用该API;否则会下载文件。可以通过以下方式禁用文件下载:

Share.downloadFallbackEnabled = false;

分享数据

你可以从数据动态生成文件并分享:

Share.shareXFiles([XFile.fromData(utf8.encode(text), mimeType: 'text/plain')], fileNameOverrides: ['myfile.txt']);

分享URI

iOS支持从URI获取元数据:

Share.shareUri(uri: uri);

分享结果

所有分享方法都会返回一个ShareResult对象,包含以下信息:

  • status: ShareResultStatus
  • raw: 描述分享结果的字符串

注意:如果平台不支持识别用户操作,status将为ShareResultStatus.unavailable

示例代码

下面是一个完整的示例,展示了如何在Flutter应用中使用share_plus插件:

import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:share_plus/share_plus.dart';

void main() {
  // Set `downloadFallbackEnabled` to `false`
  // to disable downloading files if `shareXFiles` fails on web.
  Share.downloadFallbackEnabled = true;

  runApp(const DemoApp());
}

class DemoApp extends StatefulWidget {
  const DemoApp({super.key});

  @override
  DemoAppState createState() => DemoAppState();
}

class DemoAppState extends State<DemoApp> {
  String text = '';
  String subject = '';
  String uri = '';
  String fileName = '';
  List<String> imagePaths = [];

  void _onDeleteImage(int position) {
    setState(() {
      imagePaths.removeAt(position);
    });
  }

  void _onShareWithResult(BuildContext context) async {
    final box = context.findRenderObject() as RenderBox?;

    final scaffoldMessenger = ScaffoldMessenger.of(context);
    ShareResult shareResult;
    if (imagePaths.isNotEmpty) {
      final files = <XFile>[];
      for (var i = 0; i < imagePaths.length; i++) {
        files.add(XFile(imagePaths[i]));
      }
      shareResult = await Share.shareXFiles(
        files,
        text: text,
        subject: subject,
        sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
      );
    } else if (uri.isNotEmpty) {
      shareResult = await Share.shareUri(
        Uri.parse(uri),
        sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
      );
    } else {
      shareResult = await Share.share(
        text,
        subject: subject,
        sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
      );
    }
    scaffoldMessenger.showSnackBar(getResultSnackBar(shareResult));
  }

  void _onShareXFileFromAssets(BuildContext context) async {
    final box = context.findRenderObject() as RenderBox?;
    final scaffoldMessenger = ScaffoldMessenger.of(context);
    try {
      final data = await rootBundle.load('assets/flutter_logo.png');
      final buffer = data.buffer;
      final shareResult = await Share.shareXFiles(
        [
          XFile.fromData(
            buffer.asUint8List(data.offsetInBytes, data.lengthInBytes),
            name: 'flutter_logo.png',
            mimeType: 'image/png',
          ),
        ],
        sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
      );
      scaffoldMessenger.showSnackBar(getResultSnackBar(shareResult));
    } catch (e) {
      scaffoldMessenger.showSnackBar(
        SnackBar(content: Text('Error: $e')),
      );
    }
  }

  void _onShareTextAsXFile(BuildContext context) async {
    final box = context.findRenderObject() as RenderBox?;
    final scaffoldMessenger = ScaffoldMessenger.of(context);

    try {
      final shareResult = await Share.shareXFiles(
        [
          XFile.fromData(
            utf8.encode(text),
            mimeType: 'text/plain',
          ),
        ],
        sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
        fileNameOverrides: [fileName],
      );

      scaffoldMessenger.showSnackBar(getResultSnackBar(shareResult));
    } catch (e) {
      scaffoldMessenger.showSnackBar(
        SnackBar(content: Text('Error: $e')),
      );
    }
  }

  SnackBar getResultSnackBar(ShareResult result) {
    return SnackBar(
      content: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text("Share result: ${result.status}"),
          if (result.status == ShareResultStatus.success)
            Text("Shared to: ${result.raw}")
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Share Plus Plugin Demo',
      theme: ThemeData(
        useMaterial3: true,
        colorSchemeSeed: const Color(0x9f4376f8),
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Share Plus Plugin Demo'),
          elevation: 4,
        ),
        body: SingleChildScrollView(
          padding: const EdgeInsets.all(24),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisSize: MainAxisSize.min,
            children: [
              TextField(
                decoration: const InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'Share text',
                  hintText: 'Enter some text and/or link to share',
                ),
                maxLines: null,
                onChanged: (String value) => setState(() {
                  text = value;
                }),
              ),
              const SizedBox(height: 16),
              TextField(
                decoration: const InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'Share subject',
                  hintText: 'Enter subject to share (optional)',
                ),
                maxLines: null,
                onChanged: (String value) => setState(() {
                  subject = value;
                }),
              ),
              const SizedBox(height: 16),
              TextField(
                decoration: const InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'Share uri',
                  hintText: 'Enter the uri you want to share',
                ),
                maxLines: null,
                onChanged: (String value) {
                  setState(() => uri = value);
                },
              ),
              const SizedBox(height: 16),
              TextField(
                decoration: const InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'Share Text as File',
                  hintText: 'Enter the filename you want to share your text as',
                ),
                maxLines: null,
                onChanged: (String value) {
                  setState(() => fileName = value);
                },
              ),
              const SizedBox(height: 16),
              ElevatedButton.icon(
                label: const Text('Add image'),
                onPressed: () async {
                  final imagePicker = ImagePicker();
                  final pickedFile = await imagePicker.pickImage(
                    source: ImageSource.gallery,
                  );
                  if (pickedFile != null) {
                    setState(() {
                      imagePaths.add(pickedFile.path);
                    });
                  }
                },
                icon: const Icon(Icons.add),
              ),
              const SizedBox(height: 32),
              Builder(
                builder: (BuildContext context) {
                  return ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      foregroundColor: Theme.of(context).colorScheme.onPrimary,
                      backgroundColor: Theme.of(context).colorScheme.primary,
                    ),
                    onPressed: text.isEmpty && imagePaths.isEmpty
                        ? null
                        : () => _onShareWithResult(context),
                    child: const Text('Share'),
                  );
                },
              ),
              const SizedBox(height: 16),
              Builder(
                builder: (BuildContext context) {
                  return ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      foregroundColor: Theme.of(context).colorScheme.onPrimary,
                      backgroundColor: Theme.of(context).colorScheme.primary,
                    ),
                    onPressed: () {
                      _onShareXFileFromAssets(context);
                    },
                    child: const Text('Share XFile from Assets'),
                  );
                },
              ),
              const SizedBox(height: 16),
              Builder(
                builder: (BuildContext context) {
                  return ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      foregroundColor: Theme.of(context).colorScheme.onPrimary,
                      backgroundColor: Theme.of(context).colorScheme.primary,
                    ),
                    onPressed: fileName.isEmpty || text.isEmpty
                        ? null
                        : () => _onShareTextAsXFile(context),
                    child: const Text('Share text as XFile'),
                  );
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

这个示例展示了如何使用share_plus插件来分享文本、文件和资产文件,并处理分享结果。希望对你有所帮助!


更多关于Flutter社交分享插件share_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter社交分享插件share_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用share_plus插件来实现社交分享的示例代码。share_plus是一个流行的Flutter插件,用于在多种平台上共享文本、图片、链接等内容。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加share_plus依赖:

dependencies:
  flutter:
    sdk: flutter
  share_plus: ^4.0.3  # 请确保使用最新版本

然后运行flutter pub get来获取依赖。

2. 导入插件

在你的Dart文件中导入share_plus插件:

import 'package:share_plus/share_plus.dart';

3. 实现分享功能

下面是一个简单的示例,展示如何使用share_plus来分享文本和图片:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ShareExample(),
    );
  }
}

class ShareExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Share Plus Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () {
                // 分享文本
                _shareText('Check out this cool Flutter app!');
              },
              child: Text('Share Text'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                // 分享图片
                final ByteData imageBytes = await rootBundle.load('assets/sample_image.png');
                final Uint8List list = imageBytes.buffer.asUint8List();
                await Share.shareFiles([list], text: 'Here is a cool image!');
              },
              child: Text('Share Image'),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _shareText(String text) async {
    try {
      await Share.share(text);
    } catch (e) {
      print('Failed to share: $e');
    }
  }
}

4. 添加图片资源(可选)

如果你打算分享图片,确保在pubspec.yaml文件中添加图片资源,并将图片放在assets文件夹中:

flutter:
  assets:
    - assets/sample_image.png

5. 运行应用

确保一切设置正确后,运行你的Flutter应用。你应该能看到两个按钮,一个用于分享文本,另一个用于分享图片。

注意事项

  • 确保你已经在设备上正确配置了必要的权限(例如,对于Android设备,你可能需要在AndroidManifest.xml中添加存储权限,尽管share_plus通常会处理这些权限)。
  • share_plus插件支持多种平台(iOS、Android、Web等),但某些功能可能在特定平台上有所不同。

这个示例代码展示了如何在Flutter应用中使用share_plus插件来实现基本的社交分享功能。根据你的需求,你可以进一步定制和扩展这个示例。

回到顶部