Search code examples
flutterimageloadingnetworkimageview

perform action when image is loaded while using CachedNetworkImage in flutter


Here, by action i mean, Loading other widgets aswell

I am using CachedNetworkImage package. And it takes some time for the image to load from the network. I want to exactly know when the image is totally loaded so that i can show my other widgets.

Problem: Image takes time to load but the text already gets displayed which looks unprofessional.

So is there any way to know when the image is completely loaded from network. i.e change from placeholder to image.

child: Stack(
      children: [
        CachedNetworkImage(
          fadeInDuration: const Duration(milliseconds: 300),
          imageUrl: image,
          height: double.infinity,
          fit: BoxFit.cover,
          imageBuilder: (context, imageProvider) => Stack(children: [
            Container(
                decoration: BoxDecoration(
                    image: DecorationImage(
                        image: imageProvider, fit: BoxFit.cover))),
            Container(
              color: Colors.black.withOpacity(0.4),
            )
          ]),
        ),
        Padding(
          padding: const EdgeInsets.only(left: 2.0, bottom: 2),
          child: Align(
              alignment: Alignment.bottomLeft,
              child: Text(title),           <-- This gets displayed before image is loaded
        ),
        Visibility(
          visible: discount != 0,
          child: Align(
            alignment: Alignment.topRight,
            child: Container(
              margin: const EdgeInsets.only(top: 2, right: 2),
              padding: const EdgeInsets.all(2),
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(10),
                gradient: const LinearGradient(
                  begin: Alignment(-1.238, -1.313),
                  end: Alignment(3.464, 3.196),
                  colors: <Color>[
                    Color(0xfff9d423),
                    Color(0xfffc8e3a),
                    Color(0xffff4e50)
                  ],
                  stops: <double>[0.038, 0.5, 0.928],
                ),
              ),
              child: Text("$discount%"), <-- This gets displayed before image is loaded
            ),
          ),
        )
      ],
    ),

Solution

  • You can put the Stack inside the imageBuilder of a CachedNetworkImage, so everything will be displayed only after the image is loaded.

    SizedBox(
      height: 100,
      width: 100,
      child: CachedNetworkImage(
        fadeInDuration: const Duration(milliseconds: 300),
        imageUrl: image,
        height: double.infinity,
        fit: BoxFit.cover,
        imageBuilder: (context, imageProvider) => Stack(
          children: [
            Stack(children: [
              Container(
                  decoration: BoxDecoration(
                      image: DecorationImage(image: imageProvider, fit: BoxFit.cover))),
              Container(
                color: Colors.black.withOpacity(0.4),
              )
            ]),
            Padding(
              padding: const EdgeInsets.only(left: 2.0, bottom: 2),
              child: Align(
                alignment: Alignment.bottomLeft,
                child: Text(title),
              ),
            ),
            Visibility(
              visible: discount != 0,
              child: Align(
                alignment: Alignment.topRight,
                child: Container(
                  margin: const EdgeInsets.only(top: 2, right: 2),
                  padding: const EdgeInsets.all(2),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(10),
                    gradient: const LinearGradient(
                      begin: Alignment(-1.238, -1.313),
                      end: Alignment(3.464, 3.196),
                      colors: <Color>[Color(0xfff9d423), Color(0xfffc8e3a), Color(0xffff4e50)],
                      stops: <double>[0.038, 0.5, 0.928],
                    ),
                  ),
                  child: Text("$discount%"),
                ),
              ),
            )
          ],
        ),
      ),
    ),