是否可以使用 flutter_share 或其他共享插件从 Flutter image_picker 共享文本和照片?

Is it possible to share both text and a photo from Flutter image_picker using flutter_share or another share plugin?

使用 flutter_share 插件,我可以在我的 Flutter ListView 中成功共享我的 firestore 集合中的文本:

child: IconButton(
icon: Icon(
  Icons.share,
   onPressed: () => Share.share(
   '${(snapshot.data.documents[index]['title'])}',
       ))),

我现在向 ListView 添加了一个新的 flutter listtile 部分,其中包括来自 image_picker 插件的照片,用户可以在其中 select 从他们的图库中拍摄照片或拍摄新照片并附加它位于 Firestore 数据文本下方。

 void _openImagePicker(BuildContext context) {
 showModalBottomSheet(context: context, builder: (BuildContext context) {
   return Container(
     height: 180.0,
     padding: EdgeInsets.all(10.0),
   child: Column(
     children: [
     Text('Choose photo',
       style:TextStyle(fontWeight: FontWeight.bold),),
       SizedBox(height: 10.0),
       FlatButton(
         textColor: Theme.of(context).primaryColor,
         child: Text('Use Camera'),
       onPressed: () {
           _getImage(context, ImageSource.camera);
       },),
       FlatButton(
         textColor: Theme.of(context).primaryColor,child:
       Text('Open Gallery'),
         onPressed: () {
           _getImage(context, ImageSource.gallery);
         },),

     ]
   ),);
 });
 }
 @override
 Widget build(BuildContext context) {
 return Column(
   children: <Widget>[
     OutlineButton(
     onPressed: () {
       _openImagePicker(context);
     },
     child:Row(
         mainAxisAlignment: MainAxisAlignment.start,
         children: <Widget>[
           Icon(Icons.camera_alt),
           SizedBox(
             width:1.0,
           ),
           // Text('Add Image'),
         ]
     ),//Row
 ),//outline button

    SizedBox(height: 10.0),
     _imageFile == null ?  Text('Add an Image') : Image.file(_imageFile,
         fit: BoxFit.cover,
         height: 200.0,
      width: 200.0,       
       alignment: Alignment.topCenter,
     ),
   ],
 );}}

我的问题是,这个 flutter_share 插件或其他插件是否有办法将新图像与原始共享的 firestore 文本结合起来,以便用户可以共享文本和照片组合,而不是只是文字?还是只能发送一个或另一个?

图像不会存储在 Firestore 中,只会存储文本,因此图像可以用用户相机拍摄或从他们的画廊上传,然后附加到共享文本。


这是添加了 esys 共享的完整代码,它没有发送 image_picker 图片

class ImageInput extends StatefulWidget {


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

class _ImageInputState extends State<ImageInput> {


  File _imageFile;

  void _getImage(BuildContext context, ImageSource source){
   ImagePicker.pickImage(source: source, maxWidth: 200.0).then((File image){
   setState((){
    _imageFile = image;
  //        _imageFile = await ImagePicker.pickImage(source: source);
  //        List<int> imageBytes = await _imageFile.readAsBytes();
  //        var uint8List = Uint8List.fromList(imageBytes);


  });
  Navigator.pop(context);

  });
 }


  void _openImagePicker(BuildContext context) {

  showModalBottomSheet(context: context, builder: (BuildContext context) {
  return Container(
    height: 180.0,
    padding: EdgeInsets.all(10.0),
  child: Column(
    children: [
    Text('Choose photo',
      style:TextStyle(fontWeight: FontWeight.bold),),
      SizedBox(height: 10.0),
      FlatButton(
        textColor: Theme.of(context).primaryColor,
        child: Text('Use Camera'),
      onPressed: () {
          _getImage(context, ImageSource.camera);
      },),
      FlatButton(
        textColor: Theme.of(context).primaryColor,child:
      Text('Open Gallery'),
        onPressed: () {
          _getImage(context, ImageSource.gallery);
        },)

    ]
  ),);
 });
 }


 @override
 Widget build(BuildContext context) {
 return Column(
 children: <Widget>[
    OutlineButton(
    onPressed: () {
      _openImagePicker(context);
    },
    child:Row(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          Icon(Icons.camera_alt),
          SizedBox(
            width:1.0,
          ),
          // Text('Add Image'),
        ]
    ),//Row
  ),//outline button

   SizedBox(height: 10.0),
    _imageFile == null ?  Text('Add an Image') : Image.file(_imageFile,
        fit: BoxFit.cover,
        height: 200.0,
     width: 200.0,
     // width: MediaQuery.of(context).size.width,
      alignment: Alignment.topCenter,
    ),

    MaterialButton(
      child: Text('Share mixed'),
      onPressed: () async => await _shareMixed(),
    ),

  ],
);
}
}


Future<void> _shareMixed() async {
try {
final ByteData bytes1 = await rootBundle.load('_imageFile');
//final ByteData bytes2 = await rootBundle.load('assets/image2.png');
// final ByteData bytes3 = await rootBundle.load('assets/addresses.csv');

await Share.files(
    'esys images',
    {
      '_imageFile': bytes1.buffer.asUint8List(),
      //'bluedan.png': bytes2.buffer.asUint8List(),
      //'addresses.csv': bytes3.buffer.asUint8List(),
    },
    '*/*',
    text: 'My optional text.');
} catch (e) {
print('error: $e');
}
}

您可以复制粘贴运行下面的完整代码
您可以使用包 https://pub.dev/packages/esys_flutter_share

工作演示

完整代码

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';
import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'dart:typed_data';

class ImageInput extends StatefulWidget {
  @override
  _ImageInputState createState() => _ImageInputState();
}

class _ImageInputState extends State<ImageInput> {
  File _imageFile;

  void _getImage(BuildContext context, ImageSource source) {
    ImagePicker.pickImage(source: source, maxWidth: 200.0).then((File image) {
      setState(() {
        _imageFile = image;
        //        _imageFile = await ImagePicker.pickImage(source: source);
        //        List<int> imageBytes = await _imageFile.readAsBytes();
        //        var uint8List = Uint8List.fromList(imageBytes);
      });
      Navigator.pop(context);
    });
  }

  Future<void> _shareImageAndText() async {
    try {
      List<int> imageBytes = await _imageFile.readAsBytes();
      var uint8List = Uint8List.fromList(imageBytes);
      await Share.file('esys image', 'esys.jpg', uint8List, 'image/jpeg',
          text: 'My optional text.');
    } catch (e) {
      print('error: $e');
    }
  }

  void _openImagePicker(BuildContext context) {
    showModalBottomSheet(
        context: context,
        builder: (BuildContext context) {
          return Container(
            height: 180.0,
            padding: EdgeInsets.all(10.0),
            child: Column(children: [
              Text(
                'Choose photo',
                style: TextStyle(fontWeight: FontWeight.bold),
              ),
              SizedBox(height: 10.0),
              FlatButton(
                textColor: Theme.of(context).primaryColor,
                child: Text('Use Camera'),
                onPressed: () {
                  _getImage(context, ImageSource.camera);
                },
              ),
              FlatButton(
                textColor: Theme.of(context).primaryColor,
                child: Text('Open Gallery'),
                onPressed: () {
                  _getImage(context, ImageSource.gallery);
                },
              )
            ]),
          );
        });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        OutlineButton(
          onPressed: () {
            _openImagePicker(context);
          },
          child: Row(
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                Icon(Icons.camera_alt),
                SizedBox(
                  width: 1.0,
                ),
                // Text('Add Image'),
              ]), //Row
        ), //outline button

        SizedBox(height: 10.0),
        _imageFile == null
            ? Text('Add an Image')
            : Image.file(
                _imageFile,
                fit: BoxFit.cover,
                height: 200.0,
                width: 200.0,
                // width: MediaQuery.of(context).size.width,
                alignment: Alignment.topCenter,
              ),

        MaterialButton(
          child: Text('Share mixed'),
          onPressed: () async => await _shareImageAndText(),
        ),
      ],
    );
  }
}

void main() => runApp(MyApp());

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

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ImageInput(),
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}