Search code examples
fluttersharedpreferences

How to save multiple images to Shared_Preferences in Flutter?


I want to save multiple images to SharedPreferences. I already got image from my Gallery and save it but i don't want to save not 1 image i want to save multi image. Here is my code:

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';
import 'Utility.dart';

class SaveImageDemo extends StatefulWidget {
  SaveImageDemo() : super();

  final String title = "Flutter Save Image in Preferences";

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

class _SaveImageDemoState extends State<SaveImageDemo> {
  //
  Future<File> imageFile;
  Future<List<Image>> myImageList;
  List<Image> imageHolderList = List<Image>();
  Image imageFromPreferences;

  pickImageFromGallery(ImageSource source) {
    setState(() {
      imageFile = ImagePicker.pickImage(source: source);
    });
  }

  loadImageFromPreferences() {
    Utility.getImageFromPreferences().then((img) {
      if (null == img) {
        return;
      }
      setState(() {
        imageFromPreferences = Utility.imageFromBase64String(img);
      });
    });
  }

  Widget imageFromGallery() {
    return FutureBuilder<File>(
      future: imageFile,
      builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
        if (snapshot.connectionState == ConnectionState.done &&
            null != snapshot.data) {
          print(snapshot.data.path);
          Utility.saveImageToPreferences(
              Utility.base64String(snapshot.data.readAsBytesSync()));
          imageHolderList.add(Image.file(snapshot.data));
          print(imageHolderList.length);
          return Image.file(
            snapshot.data,
          );
        } else if (null != snapshot.error) {
          return const Text(
            'Error Picking Image',
            textAlign: TextAlign.center,
          );
        } else {
          return const Text(
            'No Image Selected',
            textAlign: TextAlign.center,
          );
        }
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.add),
            onPressed: () {
              pickImageFromGallery(ImageSource.gallery);
              setState(() {
                imageFromPreferences = null;
              });
            },
          ),
          IconButton(
            icon: Icon(Icons.refresh),
            onPressed: () {
              loadImageFromPreferences();
            },
          ),
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            SizedBox(
              height: 20.0,
            ),
            Container(width: 100, height: 250, child: imageFromGallery()),
            Expanded(
              child: ListView.builder(
                shrinkWrap: true,
                scrollDirection: Axis.horizontal,
                itemCount: imageHolderList.length ?? 0,
                itemBuilder: (BuildContext context, int index) => Card(
                  child: Container(
                      width: 100, height: 100, child: imageHolderList[index]),
                ),
              ),
            ),
            SizedBox(
              height: 400.0,
            ),
            null == imageFromPreferences ? Container() : imageFromPreferences,
          ],
        ),
      ),
    );
  }
}

This code saving 1 image. I have Utility.dart file and that file codes:

import 'dart:typed_data';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';

class Utility {
  //
  static const String KEY = "IMAGE_KEY";

  static Future<String> getImageFromPreferences() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    return prefs.getString(KEY) ?? null;
  }

  static Future<bool> saveImageToPreferences(String value) async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    return prefs.setString(KEY, value);
  }

  static Image imageFromBase64String(String base64String) {
    return Image.memory(
      base64Decode(base64String),
      fit: BoxFit.fill,
    );
  }

  static Uint8List dataFromBase64String(String base64String) {
    return base64Decode(base64String);
  }

  static String base64String(Uint8List data) {
    return base64Encode(data);
  }
}

The only thing I want is to save for more than one image, just like I did for one image.


Solution

  • You can use the setStringList method of SharedPreferences:

    import 'dart:typed_data';
    import 'package:shared_preferences/shared_preferences.dart';
    import 'package:flutter/material.dart';
    import 'dart:async';
    import 'dart:convert';
    
    class Utility {
      //
      static const String KEY = "IMAGES_KEY";
    
      static Future<List<String>> getImagesFromPreferences() async {
        final SharedPreferences prefs = await SharedPreferences.getInstance();
        return prefs.getStringList(KEY) ?? null;
      }
    
      static Future<bool> saveImageToPreferences(String value) async {
        final SharedPreferences prefs = await SharedPreferences.getInstance();
        List<String> currentImages = await prefs.getStringList(KEY); // getting current loaded images
        currentImages.add(value);  // adding the new image    
        return prefs.setStringList(KEY, currentImages); // saving the array of images
      }
    
      static Future<bool> resetImages() async {
        final SharedPreferences prefs = await SharedPreferences.getInstance();
        return prefs.setStringList(KEY, []); // deleting all saved images
      }
    
      static Image imageFromBase64String(String base64String) {
        return Image.memory(
          base64Decode(base64String),
          fit: BoxFit.fill,
        );
      }
    
      static Uint8List dataFromBase64String(String base64String) {
        return base64Decode(base64String);
      }
    
      static String base64String(Uint8List data) {
        return base64Encode(data);
      }
    }
    

    Important note: saving base64 encoded images in SharedPreferences is not generally recommended. SharedPreferences should be used to save small chunks of data. You might want to consider a local database solution, such as SQLite, for your specific scenario.