Loading Images from a Remote URL in Flutter

In this tutorial, you will learn how to load a list of images from a remote URL in Flutter. The remote URL that we are going to use will return a list of images in JSON format. We will create a Flutter mobile application that will display this list of images in a GridView.

For us to reach our main goal we will follow these steps:

  1. Create a new Flutter App,
  2. Download dependencies,
  3. Create a function to get JSON from a remote API,
  4. Calling the function in the “initState“,
  5. Display the images in a GridView.

1. Create a new Flutter App

To start off we will need to create a new Flutter project in Android Studio(or any IDE that you might be using), if you don’t know how to create a project you can refer to the “Hello World App in Flutter” tutorial.

2. Download dependencies

For this tutorial, we will use a dependency called HTTP. The HTTP dependency is a composable, multi-platform, future-based API for HTTP requests. This package contains a set of functions and classes that make it easy to consume HTTP resources.

Open your pubspec.yaml file:

and add “http: ^0.12.2” under dependencies:

Please note that the latest version at the time of writing this tutorial is 0.12.2. You might want to check what is the latest version when you use it. After that, open the terminal windows, change the current directory to where your Flutter project is and run the “pub getcommand to fetch dependencies listed in the pubspec.yaml file. Then you should be able to import the HTTP package into your code as it is illustrated in the image below.

3. Create a Function to Fetch JSON

To fetch JSON with a list of images from a remote URL using HTTP package, we will need the following function.

List data;
List imagesUrl = [];

Future<String> fetchDataFromApi() async {
  var jsonData = await http.get(
      "https://s3-us-west-2.amazonaws.com/appsdeveloperblog.com/tutorials/files/cats.json");
  var fetchData = jsonDecode(jsonData.body);

  setState(() {
    data = fetchData;
    data.forEach((element) {
      imagesUrl.add(element['url']);
    });
  });

  return "Success";
}`

Let us break down the above function to better understand it. First, we declare a variable “jsonData” which will be set to the JSON object which we will GET using the HTTP package.

Once we have the JSON data fetched, we will need to decode it using the default  ‘dart:convert‘ package. Then, once the JSON data is decoded, we can use it to store the result in a list. As you can see we have declared two Lists. The first list which is called “data” will store the JSON objects after decoding. The second list called which is called “imagesUrl” is where we will add all the image URLs read from JSON objects. We will use these image URLs to display images. Next, we will use the “forEach()” function to loop through a collection of JSON objects stored in the “data” list, and for each element, we will read its “URL” property and add its value to a “imagesUrl” list. In the end, we simply return “Success” to close the function.

4. Calling the fetchDataFromApi()

In the previous step, we have prepared the fetchDataFromApi() function. Now when we have this function ready, we can call it inside of “initState()” function. This means that the fetchDataFromApi() function will be called at the time when the widget has been initialized and inserted into the tree. Please see the code example below:

@override
void initState() {
  super.initState();
  fetchDataFromApi();
}

5. Display the Images in a GridView

Now that we have a list of image URLs fetched from a remote JSON, we are ready to display these images in our Flutter mobile app. As it was mentioned earlier, the best way to display images is either using a ListView or a GridView. In the code example below, we will use GridView.builder.

GridView.builder(
  gridDelegate:
      SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
  itemCount: imagesUrl.length,
  itemBuilder: (BuildContext context, int index) {
    return Image.network(
      imagesUrl[index],
      fit: BoxFit.cover,
    );
  },
),

Inside the GridView.builder we pass the required gridDelegate property and then we give it a SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2) which basically means that we want to display our images in 2 columns. Next, the itemCount property is set the length of the imagesUrl list. Finally, in the itemBuilder we return a network image that has a URL path set to imagesUrl[index]. This means we will get one image for every URL stored in the imagesUrl list.

Here is the output of our code:

Complete Code Example

Below is a complete code example that you can copy and run in your IDE.

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List data;
  List imagesUrl = [];

  @override
  void initState() {
    super.initState();
    fetchDataFromApi();
  }

  Future<String> fetchDataFromApi() async {
    var jsonData = await http.get(
        "https://s3-us-west-2.amazonaws.com/appsdeveloperblog.com/tutorials/files/cats.json");
    var fetchData = jsonDecode(jsonData.body);

    setState(() {
      data = fetchData;
      data.forEach((element) {
        imagesUrl.add(element['url']);
      });
    });

    return "Success";
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: false,
        title: Text('List Of Images'),
        centerTitle: true,
      ),
      body:
      GridView.builder(
        gridDelegate:
            SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
        itemCount: imagesUrl.length,
        itemBuilder: (BuildContext context, int index) {
          return Image.network(
            imagesUrl[index],
            fit: BoxFit.cover,
          );
        },
      ),
    );
  }
}

I hope this Flutter tutorial was helpful for you. If you are interested in learning Flutter, please check other Flutter tutorials on this site. Some of them have video tutorials included.


Leave a Reply

Your email address will not be published. Required fields are marked *