ibrokemypie
ibrokemypie

Reputation: 451

Failed assertion width > 0.0': is not true when placing single Image in Container in FittedBox

When I place an Image.network in either a Row or Container which is the child of a FittedBox, viewing it causes errors/crashes.

The FittedBox actually uses a function as its child which returns a widget based on number of images. When there are two images it returns a Row which has each image as its children, which works without error, but when there is only one the error occurs whether I return either a Container with the image as its child or a Row with a Single child being the image.

            Container(
              child: FittedBox(child: status.statusFiles()),
            ),

statusFiles:

    return Container(
        child: 
          Image.network(
            this.files[0].thumbnailUrl,
            fit: BoxFit.contain,
          ),
        );

I expect a FittedBox containing the image in the largest size that fits the, instead I get the following error when the widget is rendered

I/flutter (26617): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (26617): The following assertion was thrown during performLayout():
I/flutter (26617): 'package:flutter/src/rendering/box.dart': Failed assertion: line 307 pos 12: 'width > 0.0': is not
I/flutter (26617): true.
...
I/flutter (26617): When the exception was thrown, this was the stack:
I/flutter (26617): #2      BoxConstraints.constrainSizeAndAttemptToPreserveAspectRatio (package:flutter/src/rendering/box.dart:307:12)
I/flutter (26617): #3      RenderFittedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:2275:26)
I/flutter (26617): #4      RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (26617): #5      RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:738:15)
I/flutter (26617): #6      RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (26617): #7      RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:798:17)
I/flutter (26617): #8      RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (26617): #9      RenderPadding.performLayout (package:flutter/src/rendering/shifted_box.dart:199:11)
...
I/flutter (26617): The following RenderObject was being processed when the exception was fired:
I/flutter (26617):   RenderFittedBox#d752c relayoutBoundary=up8 NEEDS-LAYOUT NEEDS-PAINT
I/flutter (26617):   creator: FittedBox ← Container ← Column ← Expanded ← Row ← Padding ← Container ←
I/flutter (26617):   RepaintBoundary-[<16>] ← IndexedSemantics ← NotificationListener<KeepAliveNotification> ←
I/flutter (26617):   KeepAlive ← AutomaticKeepAlive ← ⋯
I/flutter (26617):   parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size)
I/flutter (26617):   constraints: BoxConstraints(0.0<=w<=339.4, 0.0<=h<=Infinity)
I/flutter (26617):   size: MISSING
I/flutter (26617):   fit: contain
I/flutter (26617):   alignment: center
I/flutter (26617):   textDirection: ltr
I/flutter (26617): This RenderObject had the following descendants (showing up to depth 5):
I/flutter (26617):   RenderSemanticsAnnotations#df6f3 relayoutBoundary=up9 NEEDS-PAINT
I/flutter (26617):     RenderImage#63da1 relayoutBoundary=up10 NEEDS-PAINT
I/flutter (26617): ════════════════════════════════════════════════════════════════════════════════════════════════════

Upvotes: 22

Views: 16229

Answers (8)

Yosvani Quiala
Yosvani Quiala

Reputation: 1

I had similar problem with widget Visibility. Solution:

Visibility(
                   
            maintainSize: true,
            maintainAnimation: true,
            maintainState: true,
            // the free flags true so when visible = false, keeps the widget on the tree

            visible :provider1.visivility[index],
)

Upvotes: 0

Alex Lovsky
Alex Lovsky

Reputation: 50

minWidth hide this error - work good in some cases:

Container(
  child: FittedBox(
  fit:BoxFit.scaleDown,
    Container(
        constraints:const BoxConstraints(minWidth:1), // Set Min Width
        child: status.statusFiles(),
    ),
  ),
),

Upvotes: 1

Ali Ajjoub
Ali Ajjoub

Reputation: 1

i had the same problem when i used video player in FittedBox, i used : ConstrainedBox( constraints: BoxConstraints(minWidth: 1, minHeight: 1), child: Image.asset( 'resources/images/background.png', ), ),

or : SizedBox.expand( child: FittedBox( child: Image.file(File(path)), fit: BoxFit.fill, ), ),

Upvotes: 0

This is my workaround, but I think the Konstantin Kozirev's answer is better

final image = Image.asset("assets/something.png");

...

FutureBuilder(
    future: Future.delayed(Duration(milliseconds: 100)).then((_) => image),
    builder: (context, snapshot) {
        if(snapshot.hasData) {
           return FittedBox(
              fit: BoxFit.scaleDown,
              child: image,
           );
        }
        return image;
    },
)

Upvotes: 0

Konstantin Kozirev
Konstantin Kozirev

Reputation: 1262

It is strongly recommended that either both the width and the height be specified for an Image widget, or that the widget be placed in a context that sets tight layout constraints, so that the image does not change size as it loads.

So if you don't want to specify height/width, you have an option to put the FittedBox into ConstrainedBox that has minWidth of infinity.

Thus we don't need minWidth/minHeight: 1 here.

Upvotes: 1

Bilal Şimşek
Bilal Şimşek

Reputation: 5943

Sizebox.expand solved my problem

Container(
  width: 50,
  height: 50,
  decoration: BoxDecoration(
    border: Border.all(color: Colors.grey),
    borderRadius: BorderRadius.circular(3),
    color: color,
  ),
  child: SizedBox.expand(
    child: FittedBox(
      child: Image.file(File(path)),
      fit: BoxFit.fill,
    ),
  ),
)

Upvotes: 18

Wecherowski
Wecherowski

Reputation: 958

Neither of the previous solutions worked for me because I used fit: Boxfit.fitWidth and I really needed the height of the ancestors to depend on the image width.

My solution was to wrap the image in a ConstrainedBox and manually apply a min. height and width of 1:

ConstrainedBox(
      constraints: BoxConstraints(maxHeight: maxHeight),
      child: Hero(
        tag: 'SettingsPic',
        child: Container(
          width: double.infinity,
          decoration: BoxDecoration(
              borderRadius: BorderRadius.vertical(bottom: Radius.circular(25)),
              boxShadow: [BoxShadow(
                  color: Colors.black.withOpacity(0.2),
                  blurRadius: 10
              )]
          ),
          child: ClipRRect(
            borderRadius: BorderRadius.vertical(bottom: Radius.circular(25)),
            child: FittedBox(
              fit: BoxFit.fitWidth,
              alignment: Alignment.bottomCenter,
              child: ConstrainedBox(
                constraints: BoxConstraints(minWidth: 1, minHeight: 1), // here
                child: Image.asset(
                  'resources/images/background.png',
                ),
              ),
            ),
          ),
        ),
      ),
    )

Upvotes: 25

atreeon
atreeon

Reputation: 24157

The reason why this is not working is because it does not know the width of the image because the image has yet to be loaded at the point of laying out the component. It needs the width of the image to do the calculation. When you do a hot reload the image will have been retrieved by Flutter at that point.

What I did in this situation is go through all my images and find out the dimensions and I hardcoded them into the file. I don't like this solution but it did solve my error.

I assume that the assets are retrieved from the assets directory only when they are required for performance reasons (ie, it would cause a lag at phone startup time if you had many images)

    Expanded(
      child: Column(
        children: [
          FittedBox(
            fit: BoxFit.scaleDown,
            child: Image.asset("assets/foot.png", width: 100, height: 100,),
          ),
        ],
      ),
    ),

Upvotes: 10

Related Questions