0

I've created a flutter project that show a staggeredgridview of images from firestore database. Once i click on one of the images it shows that image. What i want is a download button thats saves the image to my device. Ath the moment I've just used pop.

I've read some about the path provider package but i can't figure out how to implement this in the code. Perhaps there is a better solution?

StaggeredGridView Page

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:proj/screens/home/instafull.dart';
import 'dart:async';
import 'package:proj/services/auth.dart';
import 'package:proj/shared/constants.dart';



class Instapage extends StatefulWidget {
  @override
  _InstapageState createState() => _InstapageState();
}

class _InstapageState extends State<Instapage> {
  final AuthService _auth = AuthService();
  StreamSubscription<QuerySnapshot> subscription;
  List<DocumentSnapshot> wallpaperlist;
  final CollectionReference collectionReference = FirebaseFirestore.instance.collection('mediapost');

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    subscription = collectionReference.snapshots().listen((datasnapshot) {
      setState(() {
        wallpaperlist = datasnapshot.docs;
      });
    });
  }

  @override
  void dispose() {
    subscription?.cancel();
    // TODO: implement dispose
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: bas,
        body: wallpaperlist != null?
        StaggeredGridView.countBuilder(
          padding: const EdgeInsets.fromLTRB(10, 8, 10, 0),
          crossAxisCount: 4,
          itemCount: wallpaperlist.length,
          itemBuilder: (context, index){
            String imgPath = wallpaperlist[index].get('img');
            return new Material(
              elevation: 8,
              borderRadius: BorderRadius.all(Radius.circular(8.0)),
              child: InkWell(
                onTap: () => Navigator.push(
                  context,
                  MaterialPageRoute(
                  builder: (context) => InstaFull(imgPath: imgPath))),
                  child: Hero(
                    tag: imgPath,
                    child: FadeInImage(
                      image: NetworkImage(imgPath),
                      fit: BoxFit.cover,
                      placeholder: AssetImage('assets/wally2.jpg'),
                    ),
                  ),
                ),
              );
            },
            staggeredTileBuilder: (index) => StaggeredTile.count(2, index.isEven?2:3),
            mainAxisSpacing: 8,
            crossAxisSpacing: 8,
            ): Center(
              child: CircularProgressIndicator(),
              ),
    );
  }
}

Picture Page

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


class InstaFull extends StatelessWidget {
  String imgPath;
  InstaFull({this.imgPath});

  final LinearGradient backgroundGradient = LinearGradient(
    colors: [Color(0x10000000), Color(0x30000000)],
    begin: Alignment.topLeft,end: Alignment.bottomRight);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SizedBox.expand(
        child: Stack(
          children: [
            Align(
              alignment: Alignment.center,
              child: Hero(
                tag: imgPath,
                child: Image.network(imgPath),
              ),
            ),
            Align(
              alignment: Alignment.topCenter,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  AppBar(
                    elevation: 0,
                    backgroundColor: Colors.transparent,
                    leading: IconButton(
                      icon: Icon(Icons.close,
                      color: Colors.black,
                      ),
                      onPressed: () => Navigator.of(context).pop(),
                    ),
                  ),
                ],
              ),
            ),
            Align(
              alignment: Alignment.bottomCenter,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  TextButton(
                    onPressed: () => Navigator.of(context).pop(),
                    child: Text('Download')),
                ],),
            )
          ],
        ),
      ),
    );
  }
}
skrot311
  • 3
  • 2
  • Please take a look at - https://stackoverflow.com/questions/49987707/how-to-save-an-image-to-the-photo-gallery-using-flutter – theiskaa Jun 22 '21 at 19:15

1 Answers1

0

You can use gallery_saver

Install it and enable this permissions:

iOS

Add the following keys to your Info.plist file, located in <project root>/ios/Runner/Info.plist:

NSPhotoLibraryUsageDescription - describe why your app needs permission for the photo library. This is called Privacy - Photo Library Usage Description in the visual editor. Android

Android

android.permission.WRITE_EXTERNAL_STORAGE - Permission for usage of external storage

Official example of gallery_saver:

import 'dart:io';

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

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String firstButtonText = 'Take photo';
  String secondButtonText = 'Record video';
  double textSize = 20;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      body: Container(
        color: Colors.white,
        child: Column(
          children: <Widget>[
            Flexible(
              flex: 1,
              child: Container(
                child: SizedBox.expand(
                  child: RaisedButton(
                    color: Colors.blue,
                    onPressed: _takePhoto,
                    child: Text(firstButtonText,
                        style:
                            TextStyle(fontSize: textSize, color: Colors.white)),
                  ),
                ),
              ),
            ),
            Flexible(
              child: Container(
                  child: SizedBox.expand(
                child: RaisedButton(
                  color: Colors.white,
                  onPressed: _recordVideo,
                  child: Text(secondButtonText,
                      style: TextStyle(
                          fontSize: textSize, color: Colors.blueGrey)),
                ),
              )),
              flex: 1,
            )
          ],
        ),
      ),
    ));
  }

  void _takePhoto() async {
    ImagePicker.pickImage(source: ImageSource.camera)
        .then((File recordedImage) {
      if (recordedImage != null && recordedImage.path != null) {
        setState(() {
          firstButtonText = 'saving in progress...';
        });
        GallerySaver.saveImage(recordedImage.path).then((String path) {
          setState(() {
            firstButtonText = 'image saved!';
          });
        });
      }
    });
  }

  void _recordVideo() async {
    ImagePicker.pickVideo(source: ImageSource.camera)
        .then((File recordedVideo) {
      if (recordedVideo != null && recordedVideo.path != null) {
        setState(() {
          secondButtonText = 'saving in progress...';
        });
        GallerySaver.saveVideo(recordedVideo.path).then((String path) {
          setState(() {
            secondButtonText = 'video saved!';
          });
        });
      }
    });
  }
  void _saveNetworkVideo() async {
    String path =
        'https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4';
    GallerySaver.saveVideo(path).then((bool success) {
      setState(() {
        print('Video is saved');
      });
    });
  }

  void _saveNetworkImage() async {
    String path =
        'https://image.shutterstock.com/image-photo/montreal-canada-july-11-2019-600w-1450023539.jpg';
    GallerySaver.saveImage(path).then((bool success) {
      setState(() {
        print('Image is saved');
      });
    });
  }
}
theiskaa
  • 1,202
  • 5
  • 25