Griffin Fisch
Griffin Fisch

Reputation: 107

How do I display images from a JSON file in a carousel(slider) in Flutter

I have a local json file assets/properties.json in which key "image" has [5 different images] stored with other keys as well like name, place, etc. I want this images be displayed in a carouselSlider.

I have searched but cant find something specific to what i am trying to do.

import 'package:flutter/material.dart';
import 'package:carousel_pro/carousel_pro.dart';
import 'package:flutter_test_app/test_page.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'dart:convert';
import 'dart:async';
import 'package:flutter_test_app/propery_details_widget.dart';

class PropertyDetails extends StatefulWidget {
  @override
  _PropertyDetailsState createState() => _PropertyDetailsState();
}

class _PropertyDetailsState extends State<PropertyDetails> {
  List properties;
  Future<String> loadJsonData() async {
    var jsonText = await rootBundle.loadString("assets/properties.json");
    setState(() {
      properties = json.decode(jsonText);
    });
    return 'success';
  }
  int index = 1;

  List<String> listaTela = new List();

  CarouselSlider instance;

  @override
  void initState() {
    super.initState();
    this.loadJsonData();

    listaTela.add("assets/images/houses/house.jpg");
    listaTela.add('assets/images/houses/house1.jpg');
    listaTela.add('assets/images/houses/house2.jpg');
    listaTela.add('assets/images/houses/house3.jpg');
    listaTela.add('assets/images/houses/house4.jpg');
  }

  @override
  Widget build(BuildContext context) {
    instance = new CarouselSlider(
      autoPlay: true,
      autoPlayDuration: new Duration(seconds: 2),
      items: listaTela.map((it) {
        return new Container(
          width: MediaQuery.of(context).size.width,
//          margin: new EdgeInsets.symmetric(horizontal: 5.0),
          decoration: new BoxDecoration(

//            color: Colors.amber,
          ),
          child: new Image.asset(it),
        );
      }).toList(),
      height: 200,
    );

    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text("Test App"),
      ),
      body: Container(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        child: Column(
          children: <Widget>[
            instance,
            Flexible(
              fit: FlexFit.tight,
              child: Container(
                child: Details(),
              ),
            )
          ],
        ),
      ),
    );
  }
}

Instead of calling images from assests listaTela.add("assets/images/houses/house.jpg"); like this i want to call them from my "image" key in JSON file. outside my Carousel i can call my images by properties[index]["image"][0],

Upvotes: 1

Views: 7623

Answers (2)

Richard Heap
Richard Heap

Reputation: 51682

Try this. (There's a chance that the map won't work because it will have the wrong type. I don't think you included the whole json, as you are indexing it by index, yet you don't show a [] surrounding the json indicating a json array.)

class _PropertyDetailsState extends State<PropertyDetails> {
  List properties;
  int index = 1;

  Future<void> loadJsonData() async {
    var jsonText = await rootBundle.loadString("assets/properties.json");
    setState(() {
      properties = json.decode(jsonText);
    });
  }

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

  @override
  Widget build(BuildContext context) {
    Widget carousel = properties == null
        ? CircularProgressIndicator()
        : CarouselSlider(
            items: properties[index]["image"].map((it) {
              return new Container(
                width: MediaQuery.of(context).size.width,
                decoration: new BoxDecoration(),
                child: new Image.asset(it),
              );
            }).toList(),
            autoPlay: true,
            autoPlayDuration: new Duration(seconds: 2),
            height: 200,
          );

    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text("Test App"),
      ),
      body: Container(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        child: Column(
          children: <Widget>[
            carousel,
            Flexible(
              fit: FlexFit.tight,
              child: Container(
                child: Details(),
              ),
            )
          ],
        ),
      ),
    );
  }
}

Upvotes: 3

Daniel V.
Daniel V.

Reputation: 1188

As far as I can understand you problem, there are a couple of challenges.

  1. you probably want to map the JSON to Dart objects
  2. you want to display a set of images in the Slider starting from index
  3. mechanics to update you widget tree when you want to update the slider

JSON and Dart

Takes some getting used to built package:built_value is a nice way to go. It will allow you to have Dart object or list of objects mapped from a JSON file. Or, if you want to go simpler, you could do what's described here: https://flutter.dev/docs/development/data-and-backend/json#serializing-json-manually-using-dartconvert

Images from index & update

Basically, what you want to do in your initState is:

load image data from json -> set start index -> somehow get Flutter to map N image paths to Image widgets and update tree

A pseudo-code like initState could look like so:

void initState() {
  super.initState();

  // step 1: load json and map it to Dart objects
  this.loadFromJson().then(() {
    // loadFromJson returns with a Future, `then` allows you to do computation after it returns
    setState(() {
      // setting property in setState tells Flutter: hey buddy, stuff happened, rebuild!
      this.startIndex = 0;
    });
  });
}

inside your build:

// [...]
CarouselSlider(
  items: listaTela.skip(this.startIndex).take(5).map((imgObj) => Image.asset(imgObj.assetPath))
);

Hope I understood your problem and gave you relevant answer.

Upvotes: 0

Related Questions