flutter 截圖和保存圖片到本地和相冊(cè)十籍,并做分享

一、截圖功能

使用RepaintBoundary實(shí)現(xiàn)
具體實(shí)現(xiàn):

1剃法、注冊(cè)全局的key與RepaintBoundary匹配碎捺,來(lái)標(biāo)明截圖內(nèi)容

//全局key-截圖key
final GlobalKey boundaryKey = GlobalKey();

2、將需要截圖的widget包裹在RepaintBoundary組建中贷洲,加入key屬性

SingleChildScrollView(
              child:RepaintBoundary(
            key: boundaryKey,
            child:Container(
                      color: MyColor.white,
                      child:Column(
              children: [
                Padding(
                  padding: EdgeInsets.fromLTRB(
                      MyDimens.margin, 10, MyDimens.margin, 10),
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      Visibility(
                          visible: result != null && result!.org.length > 0,
                          child: Image(
                            image: result != null &&
                                    result!.org.length > 0 &&
                                    result!.org[0].source!.jglx == "黨政機(jī)關(guān)"
                                ? AssetImage("assets/images/organ.png")
                                : AssetImage("assets/images/institution.png"),
                            width: 20,
                            height: 20,
                          )),
                      Visibility(
                          visible: result != null && result!.org.length > 0,
                          child: SizedBox(
                            width: 5,
                          )),
                      Expanded(
                          child: Text(
                        _content,
                        style: MyStyle.text_style_bold,
                      ))
                    ],
                  ),
                ),
                Visibility(
                    visible: result != null &&
                        result!.org.length > 0 &&
                        result!.org[0].source != null &&
                        result!.web[0].source!.zwym != "--",
                    child: InkWell(
                      onTap: () {
                        launch('' + result!.web[0].source!.zwym.split(',')[0]);
                      },
                      child: Padding(
                          padding:
                              EdgeInsets.fromLTRB(42, 0, MyDimens.margin, 10),
                          child: Text(
                            result != null &&
                                    result!.org[0].source != null &&
                                    result!.org.length > 0
                                ? result!.web[0].source!.zwym.split(',')[0]
                                : "",
                            style: MyStyle.text_style_link,
                          )),
                    )),
                Container(
                  color: MyColor.background,
                  height: 0.5,
                ),
                Container(
                  color: MyColor.background,
                  height: 10,
                ),
                Padding(
                  padding: EdgeInsets.all(MyDimens.margin),
                  child: Text(
                    "基本信息",
                    style: MyStyle.text_style_bold,
                  ),
                ),
                Container(
                  color: MyColor.background,
                  height: 0.5,
                ),
                Padding(
                  padding: EdgeInsets.symmetric(horizontal: MyDimens.margin),
                  child: Column(
                    children: [
                      KeyValueSingle(
                          mKey: '機(jī)構(gòu)職能',
                          mValue: result != null && result!.org.length > 0
                              ? result!.org[0].source!.jgzz
                              : ""),
                    ],
                  ),
                ),
                Container(
                  color: MyColor.background,
                  height: 10,
                ),
                Padding(
                  padding: EdgeInsets.all(MyDimens.margin),
                  child: Text(
                    "網(wǎng)站開(kāi)辦信息",
                    style: MyStyle.text_style_bold,
                  ),
                ),
                Container(
                  color: MyColor.background,
                  height: 0.5,
                ),
                Padding(
                  padding: EdgeInsets.symmetric(horizontal: MyDimens.margin),
                  child: Column(
                    children: [
                      KeyValueSingle(
                          mKey: '網(wǎng)站名稱',
                          mValue: result != null && result!.org.length > 0
                              ? result!.web[0].source!.wzmc
                              : ""),
                      Container(
                        color: MyColor.background,
                        height: 0.5,
                      ),
                    
                    ],
                  ),
                ),
              ],
            ),
          ),
          )收厨,
)

注意點(diǎn):
1、如果直接包裹listView則不能截取全部?jī)?nèi)容优构,最好用SingleChildScrollView + colum 結(jié)合實(shí)現(xiàn)列表 才能截取全部?jī)?nèi)容
2诵叁、如果截取的內(nèi)容超出屏幕,則必須將RepaintBoundary直接包裹在滑動(dòng)內(nèi)容上(colum上)钦椭,否則屏幕外的內(nèi)容截取不到
滿足以上兩個(gè)條件拧额,才能實(shí)現(xiàn)截取整個(gè)widget的內(nèi)容
3、如果RepaintBoundary包裹的widget沒(méi)有背景色彪腔,在安卓上截圖會(huì)是默認(rèn)黑色背景侥锦,所以最好添加相應(yīng)的背景色。

二德挣、圖片保存

/*
 * @Author: 王長(zhǎng)春
 * @Date: 2022-03-14 09:24:34
 * @LastEditors: 王長(zhǎng)春
 * @LastEditTime: 2022-03-17 10:01:41
 * @Description: 截圖工具恭垦,生成截圖,保存到相冊(cè)或者保存本地cash文件夾返回文件路徑(供分享使用)
 */

import 'dart:io';
import 'dart:typed_data';
import 'dart:async';
import 'dart:ui';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';

import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';

//全局key-截圖key
final GlobalKey boundaryKey = GlobalKey();

class RepaintBoundaryUtils {
//生成截圖
  /// 截屏圖片生成圖片流ByteData
  Future<String> captureImage() async {
    RenderRepaintBoundary? boundary = boundaryKey.currentContext!
        .findRenderObject() as RenderRepaintBoundary?;
    double dpr = ui.window.devicePixelRatio; // 獲取當(dāng)前設(shè)備的像素比
    var image = await boundary!.toImage(pixelRatio: dpr);
    // 將image轉(zhuǎn)化成byte
    ByteData? byteData = await image.toByteData(format: ImageByteFormat.png);

    var filePath = "";

    Uint8List pngBytes = byteData!.buffer.asUint8List();
    // 獲取手機(jī)存儲(chǔ)(getTemporaryDirectory臨時(shí)存儲(chǔ)路徑)
    Directory applicationDir = await getTemporaryDirectory();
    // getApplicationDocumentsDirectory();
    // 判斷路徑是否存在
    bool isDirExist = await Directory(applicationDir.path).exists();
    if (!isDirExist) Directory(applicationDir.path).create();
    // 直接保存格嗅,返回的就是保存后的文件
    File saveFile = await File(
        applicationDir.path + "${DateTime.now().toIso8601String()}.jpg")
        .writeAsBytes(pngBytes);
    filePath = saveFile.path;
    // if (Platform.isAndroid) {
    //   // 如果是Android 的話署照,直接使用image_gallery_saver就可以了
    //   // 圖片byte數(shù)據(jù)轉(zhuǎn)化unit8
    //   Uint8List images = byteData!.buffer.asUint8List();
    //   // 調(diào)用image_gallery_saver的saveImages方法,返回值就是圖片保存后的路徑
    //   String result = await ImageGallerySaver.saveImage(images);
    //   // 需要去除掉file://開(kāi)頭吗浩。生成要使用的file
    //   File saveFile = new File(result.replaceAll("file://", ""));
    //   filePath = saveFile.path;
    //
    //
    // } else if (Platform.isIOS) {
    //   // 圖片byte數(shù)據(jù)轉(zhuǎn)化unit8
    //
    // }

    return filePath;
  }

//申請(qǐng)存本地相冊(cè)權(quán)限
  Future<bool> getPormiation() async {
    if (Platform.isIOS) {
      var status = await Permission.photos.status;
      if (status.isDenied) {
        Map<Permission, PermissionStatus> statuses = await [
          Permission.photos,
        ].request();
        // saveImage(globalKey);
      }
      return status.isGranted;
    } else {
      var status = await Permission.storage.status;
      if (status.isDenied) {
        Map<Permission, PermissionStatus> statuses = await [
          Permission.storage,
        ].request();
      }
      return status.isGranted;
    }
  }

//保存到相冊(cè)
  void savePhoto() async {
    RenderRepaintBoundary? boundary = boundaryKey.currentContext!
        .findRenderObject() as RenderRepaintBoundary?;

    double dpr = ui.window.devicePixelRatio; // 獲取當(dāng)前設(shè)備的像素比
    var image = await boundary!.toImage(pixelRatio: dpr);
    // 將image轉(zhuǎn)化成byte
    ByteData? byteData = await image.toByteData(format: ImageByteFormat.png);
  //獲取保存相冊(cè)權(quán)限建芙,如果沒(méi)有,則申請(qǐng)改權(quán)限
    bool permition = await getPormiation();
    
    var status = await Permission.photos.status;
    if (permition) {
      if (Platform.isIOS) {
        if (status.isGranted) {
          Uint8List images = byteData!.buffer.asUint8List();
          final result = await ImageGallerySaver.saveImage(images,
              quality: 60, name: "hello");
          EasyLoading.showToast("保存成功");
        }
        if (status.isDenied) {
          print("IOS拒絕");
        }
      } else {
        //安卓
        if (status.isGranted) {
          print("Android已授權(quán)");
          Uint8List images = byteData!.buffer.asUint8List();
          final result = await ImageGallerySaver.saveImage(images, quality: 60);
          if (result != null) {
            EasyLoading.showToast("保存成功");
          } else {
            print('error');
            // toast("保存失敗");
          }
        }
      }
    }else{
      //重新請(qǐng)求--第一次請(qǐng)求權(quán)限時(shí)懂扼,保存方法不會(huì)走禁荸,需要重新調(diào)一次
      savePhoto();
    }
  }
}

調(diào)用方法:

//保存本地 RepaintBoundaryUtils().savePhoto();

說(shuō)明:
我這里涉及到分享以及保存圖片到本地相冊(cè)兩個(gè)功能。
涉及到的框架有:

  #分享
  share_plus: ^3.0.1

  #微信三方-分享阀湿、登錄赶熟、小程序跳轉(zhuǎn)等(不帶支付)
  fluwx_no_pay: ^3.8.1

  #保存圖片到相冊(cè)
  image_gallery_saver: ^1.7.1

  #權(quán)限管理
  permission_handler: ^8.1.6

iOS權(quán)限設(shè)置:

在podfile中添加一下內(nèi)容:

 target.build_configurations.each do |config|
      # You can remove unused permissions here
      # for more infomation: https://github.com/BaseflowIT/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
      # e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
        'PERMISSION_PHOTOS=1',

      ]

    end

podfile整體做為參考:

ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
  'Debug' => :debug,
  'Profile' => :release,
  'Release' => :release,
}

def flutter_root
  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
  unless File.exist?(generated_xcode_build_settings_path)
    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
  end

  File.foreach(generated_xcode_build_settings_path) do |line|
    matches = line.match(/FLUTTER_ROOT\=(.*)/)
    return matches[1].strip if matches
  end
  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
      # You can remove unused permissions here
      # for more infomation: https://github.com/BaseflowIT/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
      # e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
        'PERMISSION_PHOTOS=1',

      ]

    end
  end
end

info.plist中添加字段

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>organization</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>$(FLUTTER_BUILD_NAME)</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>CFBundleURLName</key>
            <string>weixin</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>wx543b04c9d1aa9a3a</string>
            </array>
        </dict>
    </array>
    <key>CFBundleVersion</key>
    <string>$(FLUTTER_BUILD_NUMBER)</string>
    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>weixinULAPI</string>
        <string>baidumap</string>
        <string>iosamap</string>
        <string>comgooglemaps</string>
        <string>qqmap</string>
        <string>mqzone</string>
        <string>mqqwpa</string>
        <string>mqzoneopensdkapi19</string>
        <string>mqzoneopensdkapi</string>
        <string>mqzoneopensdk</string>
        <string>mqzoneopensdkapiV2</string>
        <string>mqqapi</string>
        <string>mqq</string>
        <string>wtloginmqq2</string>
        <string>mqqopensdkapiV3</string>
        <string>mqqopensdkapiV2</string>
        <string>mqqOpensdkSSoLogin</string>
        <string>weixin</string>
        <string>wechat</string>
    </array>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    <key>NSCameraUsageDescription</key>
    <string>需要訪問(wèn)您的相機(jī)設(shè)置頭像</string>
    <key>NSPhotoLibraryAddUsageDescription</key>
    <string>請(qǐng)?jiān)试SAPP保存圖片到相冊(cè)</string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>需要訪問(wèn)您的相冊(cè)設(shè)置頭像</string>
    <key>NSSupportsSuddenTermination</key>
    <false/>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIMainStoryboardFile</key>
    <string>Main</string>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationPortraitUpsideDown</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UIViewControllerBasedStatusBarAppearance</key>
    <false/>
</dict>
</plist>

添加urlSchemes

截屏2022-03-16 19.48.50.png

可以按我的添加,我這里除了基本功能陷嘴,就是微信sdk分享以及相冊(cè)相機(jī)權(quán)限映砖。

安卓權(quán)限

AndroidManifest.xml添加一下權(quán)限

<!-- 開(kāi)啟讀寫(xiě)storage權(quán)限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

三、分享:

分享這里提供兩種方案灾挨;

a邑退、share_plus 分享:不用在第三方平臺(tái)注冊(cè)app竹宋,這種分享出去的圖片,不帶app圖標(biāo)以及名稱地技,只有圖片
b蜈七、微信原生分享:fluwx_no_pay:需在微信開(kāi)發(fā)者賬號(hào)上注冊(cè)app,這種分享出去的圖片帶app圖標(biāo)以及名稱莫矗。

微信原生分享代碼:
/*
 * @Author: 王長(zhǎng)春
 * @Date: 2022-03-11 09:43:46
 * @LastEditors: 王長(zhǎng)春
 * @LastEditTime: 2022-03-16 09:56:14
 * @Description: 
 */

import 'dart:io';
import 'dart:typed_data';
import 'check.dart';
import 'package:fluwx_no_pay/fluwx_no_pay.dart' as fluwx;


class WxSdk {
  // static bool wxIsInstalled;
  static Future init() async {
    fluwx.registerWxApi(
        appId: "這里寫(xiě)你注冊(cè)的appid",
        doOnAndroid: true,
        doOnIOS: true,
        universalLink: "這里寫(xiě)你注冊(cè)的universalLink");
  
  }

  static Future<bool> wxIsInstalled() async {
    return await fluwx.isWeChatInstalled;
  }



  /**
   * 分享圖片到微信飒硅,
   * file=本地路徑
   * url=網(wǎng)絡(luò)地址
   * asset=內(nèi)置在app的資源圖片
   * scene=分享場(chǎng)景,1好友會(huì)話作谚,2朋友圈三娩,3收藏
   */
  static void ShareImage(
      {String? title,
      String? decs,
      String? file,
      String? url,
      String? asset,
      int scene = 1}) async {
    fluwx.WeChatScene wxScene = fluwx.WeChatScene.SESSION;
    if (scene == 2) {
      wxScene = fluwx.WeChatScene.TIMELINE;
    } else if (scene == 3) {
      wxScene = fluwx.WeChatScene.FAVORITE;
    }
    fluwx.WeChatShareImageModel? model;

    if (file != null) {
      model = fluwx.WeChatShareImageModel(fluwx.WeChatImage.file(File(file)),
          title: title, description: decs, scene: wxScene);
    } else if (url != null) {
      model = fluwx.WeChatShareImageModel(fluwx.WeChatImage.network(url),
          title: title, description: decs, scene: wxScene);
    } else if (asset != null) {
      model = fluwx.WeChatShareImageModel(fluwx.WeChatImage.asset(asset),
          title: title, description: decs, scene: wxScene);
    } else {
      throw Exception("缺少圖片資源信息");
    }
    fluwx.shareToWeChat(model);
  }

  /**
   * 分享文本
   * content=分享內(nèi)容
   * scene=分享場(chǎng)景,1好友會(huì)話妹懒,2朋友圈雀监,3收藏
   */
  static void ShareText(String content, {String? title, int scene = 1}) {
    fluwx.WeChatScene wxScene = fluwx.WeChatScene.SESSION;
    if (scene == 2) {
      wxScene = fluwx.WeChatScene.TIMELINE;
    } else if (scene == 3) {
      wxScene = fluwx.WeChatScene.FAVORITE;
    }
    fluwx.WeChatShareTextModel model =
        fluwx.WeChatShareTextModel(content, title: title, scene: wxScene);
    fluwx.shareToWeChat(model);
  }

/***
 * 分享視頻
 * videoUrl=視頻網(wǎng)上地址
 * thumbFile=縮略圖本地路徑
   * scene=分享場(chǎng)景,1好友會(huì)話彬伦,2朋友圈,3收藏
 */
  static void ShareVideo(String videoUrl,
      {String? thumbFile, String? title, String? desc, int scene = 1}) {
    fluwx.WeChatScene wxScene = fluwx.WeChatScene.SESSION;
    if (scene == 2) {
      wxScene = fluwx.WeChatScene.TIMELINE;
    } else if (scene == 3) {
      wxScene = fluwx.WeChatScene.FAVORITE;
    }
    fluwx.WeChatImage? image;
    if (thumbFile != null) {
      image = fluwx.WeChatImage.file(File(thumbFile));
    }
    var model = fluwx.WeChatShareVideoModel(
        videoUrl: videoUrl,
        thumbnail: image,
        title: title,
        description: desc,
        scene: wxScene);
    fluwx.shareToWeChat(model);
  }

  /**
   * 分享鏈接
   * url=鏈接
   * thumbFile=縮略圖本地路徑
   * scene=分享場(chǎng)景伊诵,1好友會(huì)話单绑,2朋友圈,3收藏
   */
  static void ShareUrl(String url,
      {String? thumbFile,
      Uint8List? thumbBytes,
      String? title,
      String? desc,
      int scene = 1,
      String? networkThumb,
      String? assetThumb}) {
    desc = desc ?? "";
    title = title ?? "";
    if (desc.length > 54) {
      desc = desc.substring(0, 54) + "...";
    }
    if (title.length > 20) {
      title = title.substring(0, 20) + "...";
    }
    fluwx.WeChatScene wxScene = fluwx.WeChatScene.SESSION;
    if (scene == 2) {
      wxScene = fluwx.WeChatScene.TIMELINE;
    } else if (scene == 3) {
      wxScene = fluwx.WeChatScene.FAVORITE;
    }
    fluwx.WeChatImage? image ;
    if (thumbFile != null) {
      image = fluwx.WeChatImage.file(File(thumbFile));
    } else if (thumbBytes != null) {
      image = fluwx.WeChatImage.binary(thumbBytes);
    } else if (strNoEmpty(networkThumb!)) {
      image = fluwx.WeChatImage.network(Uri.encodeFull(networkThumb));
    } else if (strNoEmpty(assetThumb!)) {
      image = fluwx.WeChatImage.asset(assetThumb, suffix: ".png");
    }
    var model = fluwx.WeChatShareWebPageModel(
      url,
      thumbnail: image,
      title: title,
      description: desc,
      scene: wxScene,
    );
    fluwx.shareToWeChat(model);
  }
}
分享功能封裝:
/*
 * @Author: 王長(zhǎng)春
 * @Date: 2022-03-15 15:17:19
 * @LastEditors: 王長(zhǎng)春
 * @LastEditTime: 2022-03-16 19:15:45
 * @Description: 分享工具
 */


import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:organization/common/utils/repaintBoundary_utils.dart';
import 'package:organization/common/utils/wechatSDK.dart';
import 'package:share_plus/share_plus.dart';

class ShareHelper {

  static bool wxIsInstalled = false;
//微信分享截圖
  static void onShareWx(BuildContext context) async {

    wxIsInstalled = await WxSdk.wxIsInstalled();
    //收回鍵盤(pán)曹宴,如果有輸入的情況下搂橙,先收回鍵盤(pán),再截圖
    FocusScope.of(context).requestFocus(FocusNode());
    
    if (wxIsInstalled) {
      //分享
      // WxSdk.ShareText("sdgsfds",title:"標(biāo)題");
      //獲取截圖地址
      String filePath = await RepaintBoundaryUtils().captureImage();

      print(filePath);
      WxSdk.ShareImage(title: "機(jī)構(gòu)檢索", decs: "", file: filePath);
    } else {
      //提示未安裝微信
      EasyLoading.showToast("未安裝微信");
    }
  }

  // static void checkWx() async {
  //   wxIsInstalled = await WxSdk.wxIsInstalled();
  // }

  //share_plus分享
  static void onSharePlusShare(BuildContext context) async {
    FocusScope.of(context).requestFocus(FocusNode());
    // A builder is used to retrieve the context immediately
    // surrounding the ElevatedButton.
    // The context's `findRenderObject` returns the first
    // RenderObject in its descendent tree when it's not
    // a RenderObjectWidget. The ElevatedButton's RenderObject
    // has its position and size after it's built.
    final box = context.findRenderObject() as RenderBox?;
    List<String> imagePaths = [];

    //獲取截圖地址
    String filePath = await RepaintBoundaryUtils().captureImage();
    //Share.shareFiles內(nèi)可以傳多張圖片笛坦,里面是個(gè)數(shù)組区转,所以每次要將數(shù)組清空,再將新的截圖添加到數(shù)組中
    imagePaths.clear();
    imagePaths.add(filePath);
    //分享
    await Share.shareFiles(imagePaths,
        text: "機(jī)構(gòu)詳情",
        subject: "",
        sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
  }
}

調(diào)用:
 //share_plus 分享
                ShareHelper.onSharePlusShare(context);
                //微信SDK分享
                // ShareHelper.onShareWx(context);

以上實(shí)現(xiàn)了圖片截圖以及保存本地分享內(nèi)容版扩,在安卓和iOS上親測(cè)沒(méi)問(wèn)題废离。
關(guān)于iOS微信原生分享,注冊(cè)u(píng)niversalLink的內(nèi)容礁芦,需要后臺(tái)配合蜻韭,我這里只是寫(xiě)了個(gè)demo,沒(méi)具體實(shí)現(xiàn)柿扣。
可以參考 : http://www.reibang.com/p/4c96b54ef8d1

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末肖方,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子未状,更是在濱河造成了極大的恐慌俯画,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件司草,死亡現(xiàn)場(chǎng)離奇詭異艰垂,居然都是意外死亡泡仗,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)材泄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)沮焕,“玉大人,你說(shuō)我怎么就攤上這事拉宗÷褪鳎” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵旦事,是天一觀的道長(zhǎng)魁巩。 經(jīng)常有香客問(wèn)我,道長(zhǎng)姐浮,這世上最難降的妖魔是什么谷遂? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮卖鲤,結(jié)果婚禮上肾扰,老公的妹妹穿的比我還像新娘。我一直安慰自己蛋逾,他們只是感情好集晚,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著区匣,像睡著了一般偷拔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上亏钩,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天莲绰,我揣著相機(jī)與錄音,去河邊找鬼姑丑。 笑死蛤签,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的栅哀。 我是一名探鬼主播顷啼,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼昌屉!你這毒婦竟也來(lái)了钙蒙?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤间驮,失蹤者是張志新(化名)和其女友劉穎躬厌,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡扛施,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年鸿捧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疙渣。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡匙奴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出妄荔,到底是詐尸還是另有隱情泼菌,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布啦租,位于F島的核電站哗伯,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏篷角。R本人自食惡果不足惜焊刹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望恳蹲。 院中可真熱鬧虐块,春花似錦、人聲如沸嘉蕾。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)荆针。三九已至敞嗡,卻和暖如春颁糟,著一層夾襖步出監(jiān)牢的瞬間航背,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工棱貌, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留玖媚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓婚脱,卻偏偏與公主長(zhǎng)得像今魔,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子障贸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容