AboutContact

Flutter grid view image gallery: how to download and display images

In this new flutter tutorial, you will learn how to download json data in flutter in an asynchronous way using the future builder, how to parse a simple list of string defined in a json data structure, how to create a simple grid view in flutter, how to download and display the images in the grid view gallery.

Let's create the flutter project

Open Android studio and create a new flutter application project. Open now the pubspec.yaml file and add the http library.

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^0.1.2
  http: ^0.12.0+2

Get the http package. Now open the main.dart file. Here, we will define the view that will use the future builder flutter functionality to download the json image data gallery in an async way, the json parsing in the background on an external thread using the compute functionality. Then, we will define the grid view image gallery view that will display the grid cells. Finally you will learn how to download an external image from the internet in a flutter Container and crop it to fill the cell size.

Download the JSON gallery data asynchronously

To download the data asynchronously we'll use the future builder flutter functionality. It requires as an input the async task. The snapshot will show the current status and will update itself as soon as the data is ready or as soon as an error occured.

FutureBuilder<List<String>>(
            future: fetchGalleryData(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                
              }
             
            }
          )

Here the data we'll use: json image data

It is a simple list of strings. Each row contains the image url to be displayed in the app.

Let's define now the async function that will be called by the future builder. This function will download the data using the http library, will then create a background thread using the compute flutter functionality to parse the json data in a list of string dart object.

Future<List<String>> fetchGalleryData() async {
  try {
    final response = await http
        .get(
            'https://kaleidosblog.s3-eu-west-1.amazonaws.com/flutter_gallery/data.json')
        .timeout(Duration(seconds: 5));

    if (response.statusCode == 200) {
      return compute(parseGalleryData, response.body);
    } else {
      throw Exception('Failed to load');
    }
  } on SocketException catch (e) {
    throw Exception('Failed to load');
  }
}

List<String> parseGalleryData(String responseBody) {
  final parsed = List<String>.from(json.decode(responseBody));
  return parsed;
}

Once the data is ready, the future builder will update the snapshot with the parsed list of strings object and we can use these data to display the images.

Define the grid view for the images gallery

To define the flutter grid view, we'll use the grid builder functionality.

GridView.builder(
                    itemCount: ITEM-COUNT,
                    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: COUNT),
                    itemBuilder: (context, index) {
                      return CELL-DEFINITION
                    });

We'll define the total cells count, how many cells to show for every row, and the single cell design.

Here the single cell design template. We'll use a container and we'll use the decoration to display the cropped image download from the url.

Container(
	decoration: new BoxDecoration(
		image: new DecorationImage(
		image: new NetworkImage(
		IMAGE-URL
	),
	fit: BoxFit.cover))
)

Here's how the full app gallery widget looks like.

class GalleryDemo extends StatelessWidget {
  GalleryDemo({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Image Gallery Example"),
        ),
        body: Center(
          child: FutureBuilder<List<String>>(
            future: fetchGalleryData(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return GridView.builder(
                    itemCount: snapshot.data.length,
                    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: 2),
                    itemBuilder: (context, index) {
                      return Padding(
                          padding: EdgeInsets.all(5),
                          child: Container(
                              decoration: new BoxDecoration(
                                  image: new DecorationImage(
                                      image: new NetworkImage(
                                          snapshot.data[index]),
                                      fit: BoxFit.cover))));
                    });
              }
              return Center(child: CircularProgressIndicator());
            },
          ),
        ));
  }
}

Here you can download the project example:

Download

Leave a comment








Comments


- 28 February 2020 at 12:44
I'm so grateful that this project with fulling working code is up here and available to be worked into other projects. I did however have issues with this code, and am going to share those challenges and my workarounds incase anyone else finds this wonderful example, but can't implement it based on their frameworks. My database where the images are stored is MongoDB, I use the Mongo Dart package within my Flutter project and created a collection called "images" where the URL that is uploaded to Cloudinary is inserted as the "_id" value. Pulling the list of images from the "images" collection is rather easy although my JSON will look similar to this [_id: {www......]; and this didn't really work for me. What I did was to convert the JSON to a String, and then run three ReplaceAll's for the terms "_id:", "{ " and "}" and it cleaned up the JSON quite nicely. I got stuck now with a String that did not want to to become a List. My URLS also did not have " " around them so I navigated this by adding the quotations to the upload of the URL to the database. This bit of code was invaluable to get the data to be used as you intended in your original post: //"imageurls" is the result of a sortBy query from MongoDB for "_id"// var convert1 = imageurls.toString(); var convert2 = convert1.replaceAll(new RegExp(r'_id:'),''); var convert3 = convert2.replaceAll(new RegExp(r'{ '), ''); var convert4 = convert3.replaceAll(new RegExp(r'}'), ''); //For some reason I had to create a List as dynamic, and then to String for it to work// List parse = (jsonDecode(convert4) as List).cast(); I hope this helps anyone that uses a database where you can't get the JSON image urls only Thank you so much for a very functional and great project!





AboutContactPrivacy