preload assets images before build

Viewed 6411

am trying to set background image of my container to image from assets like this:

return new Container(
            decoration: new BoxDecoration(
              image: new DecorationImage(
                image: new AssetImage(images[index]),
                fit: BoxFit.cover,
              ),
            ),

but this will take some time to load and return blank whilte screen till image load ..

so i tried to preload images before build like this:

@override
void initState() {
precacheImage(new AssetImage(images[1]), context);
precacheImage(new AssetImage(images[2]), context);
precacheImage(new AssetImage(images[3]), context);
super.initState();
}

and this returned this error:

flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ flutter: The following assertion was thrown building Builder: flutter: inheritFromWidgetOfExactType(MediaQuery) or inheritFromElement() was called before flutter: _WalkthroughPageState.initState() completed. flutter: When an inherited widget changes, for example if the value of Theme.of() changes, its dependent flutter: widgets are rebuilt. If the dependent widget's reference to the inherited widget is in a constructor flutter: or an initState() method, then the rebuilt dependent widget will not reflect the changes in the flutter: inherited widget. flutter: Typically references to to inherited widgets should occur in widget build() methods. Alternatively, flutter: initialization based on inherited widgets can be placed in the didChangeDependencies method, which flutter: is called after initState and whenever the dependencies change thereafter. flutter: flutter: When the exception was thrown, this was the stack: flutter: #0 StatefulElement.inheritFromElement. (package:flutter/src/widgets/framework.dart:3898:9) flutter: #1 StatefulElement.inheritFromElement (package:flutter/src/widgets/framework.dart:3931:6) flutter: #2 Element.inheritFromWidgetOfExactType (package:flutter/src/widgets/framework.dart:3274:14) flutter: #3 MediaQuery.of (package:flutter/src/widgets/media_query.dart:476:38) flutter: #4 createLocalImageConfiguration (package:flutter/src/widgets/image.dart:49:34) flutter: #5 precacheImage (package:flutter/src/widgets/image.dart:81:37) flutter: #6 _WalkthroughPageState.initState (package:spl/Pages/walkthrough.page.dart:65:5) flutter: #7 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3808:58) flutter: #8 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3674:5) flutter: #9 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #10 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #11 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3710:16) flutter: #12 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5) flutter: #13 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3679:5) flutter: #14 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3674:5) flutter: #15 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #16 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #17 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4838:14) flutter: #18 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #19 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #20 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4838:14) flutter: #21 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #22 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #23 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4838:14) flutter: #24 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #25 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #26 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3710:16) flutter: #27 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5) flutter: #28 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3679:5) flutter: #29 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3826:11) flutter: #30 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3674:5) flutter: #31 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #32 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #33 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4838:14) flutter: #34 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #35 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #36 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3710:16) flutter: #37 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5) flutter: #38 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3679:5) flutter: #39 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3674:5) flutter: #40 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #41 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #42 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4838:14) flutter: #43 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #44 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #45 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3710:16) flutter: #46 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5) flutter: #47 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3679:5) flutter: #48 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3826:11) flutter: #49 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3674:5) flutter: #50 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #51 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #52 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3710:16) flutter: #53 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5) flutter: #54 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3679:5) flutter: #55 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3674:5) flutter: #56 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #57 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #58 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4838:14) flutter: #59 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #60 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #61 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3710:16) flutter: #62 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5) flutter: #63 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3679:5) flutter: #64 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3674:5) flutter: #65 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #66 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #67 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3710:16) flutter: #68 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5) flutter: #69 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3679:5) flutter: #70 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3826:11) flutter: #71 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3674:5) flutter: #72 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #73 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #74 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3710:16) flutter: #75 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5) flutter: #76 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3679:5) flutter: #77 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3826:11) flutter: #78 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3674:5) flutter: #79 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2950:14) flutter: #80 Element.updateChild (package:flutter/src/widgets/framework.dart:2753:12) flutter: #81 RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:4621:32) flutter: #82 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4953:17) flutter: #83 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15) flutter: #84 _TheatreElement.update (package:flutter/src/widgets/overlay.dart:507:16) flutter: #85 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15) flutter: #86 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3710:16) flutter: #87 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5) flutter: #88 StatefulElement.update (package:flutter/src/widgets/framework.dart:3856:5) flutter: #89 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15) flutter: #90 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3710:16) flutter: #91 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5) flutter: #92 ProxyElement.update (package:flutter/src/widgets/framework.dart:3968:5) flutter: #93 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15) flutter: #94 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4845:14) flutter: #95 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15) flutter: #96 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3710:16) flutter: #97 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5) flutter: #98 StatefulElement.update (package:flutter/src/widgets/framework.dart:3856:5) flutter: #99 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15) flutter: #100 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4845:14) flutter: #101 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15) flutter: #102 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4845:14) flutter: #103 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15) flutter: #104 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3710:16) flutter: #105 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5) flutter: #106 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2286:33) flutter: #107 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:676:20) flutter: #108 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:219:5) flutter: #109 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15) flutter: #110 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9) flutter: #111 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5) flutter: #112 _invoke (dart:ui/hooks.dart:151:13) flutter: #113 _drawFrame (dart:ui/hooks.dart:140:3) flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════

3 Answers

I had the same problem, the solution was in the error description itself:

initialization based on inherited widgets can be placed in the didChangeDependencies method, which is called after initState and whenever the dependencies change thereafter.

Here's a simplified version of my code, preloading images in method didChangeDependencies:

class _SampleWidgetState extends State<SamleWidget> {
  Image image1;
  Image image2;
  Image image3;
  Image image4;

  Image currentImage;

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

    image1 = Image.asset("assets/image1.png");
    image2 = Image.asset("assets/image2.png");
    image3 = Image.asset("assets/image3.png");
    image4 = Image.asset("assets/image4.png");

    currentImage = image1;
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();

    precacheImage(image1.image, context);
    precacheImage(image2.image, context);
    precacheImage(image3.image, context);
    precacheImage(image4.image, context);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: currentImage,
    );
  }

  void setImage(int index) {
      switch (index) {
        case 1: currentImage = image1; break;
        case 2: currentImage = image2; break;
        case 3: currentImage = image3; break;
        case 4: currentImage = image4; break;
      }
  }
}

Hope this helps :)

I'm not sure, but I think, you can try FutureBuilder

import 'dart:ui' as ui;

class MyImage extends StatelessWidget {
  MyImage(this._imgSrc);
  final String _imgSrc;

  @override
  Widget build(BuildContext context) {
    Image image = Image.asset(_imgSrc);
    Completer<ui.Image> completer = new Completer<ui.Image>();
    image.image.resolve(ImageConfiguration()).addListener((ImageInfo info, bool _) {
      completer.complete(info.image);
    });
    return FutureBuilder(
        future: completer.future,
        builder: (context, AsyncSnapshot<ui.Image> snapshot) {
          return snapshot.hasData ? image : Container();
        });
  }

This is happening because precacheImage is creating an ImageConfiguration object with the function createLocalImageConfiguration. And this function accesses some InheritedWidget.

And accessing InheritedWidget in constructor or in the initState method can be tricky.

Here is the createLocalImageConfiguration function, the one that access InheritedWidget

ImageConfiguration createLocalImageConfiguration(BuildContext context, { Size? size }) {
  return ImageConfiguration(
    bundle: DefaultAssetBundle.of(context),
    devicePixelRatio: MediaQuery.maybeOf(context)?.devicePixelRatio ?? 1.0,
    locale: Localizations.maybeLocaleOf(context),
    textDirection: Directionality.maybeOf(context),
    size: size,
    platform: defaultTargetPlatform,
  );
}

To avoid this, as the error message advise you and as Alex Domenici answered, you can move this code inside the didUpdateWidget method.

Related