skip to Main Content

I’m using the Masonry grid from the flutter_staggered_grid_view package along with cached_network_image to display images fetched from an API. When the grid is initially displayed, the images are still being loaded from the network, and regardless of how fast the images load (even if they are cached), the widget appears to resize itself as each image is fetched and rendered.

Is there a way to prevent the widget from resizing itself during the image loading process or any good idea how to make that transition smooth?

I tried to mask the resizing issue by adding animations, which helped a bit, but it still bothers me. I also considered assigning fixed sizes to the widget, but that somewhat defeats the purpose of using the Masonry grid.

Example of widget:

  CupertinoButton(
      padding: EdgeInsets.zero,
      onPressed: () {},
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: [
          CachedNetworkImage(
            imageUrl: 'url',
          ),
          const Padding(
            padding: EdgeInsets.symmetric(horizontal: 10, vertical: 8),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  'test',
                  style: TextStyle(
                    fontSize: 14,
                    fontWeight: FontWeight.w700,
                  ),
                ),
                SizedBox(height: 5),
                Padding(
                  padding: EdgeInsets.only(top: 10.0),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text(
                        'some text',
                      ),
                      Text(
                        'some text',
                      ),
                    ],
                  ),
                ),
                SizedBox(height: 5),
              ],
            ),
          ),
        ],
      ),
    );

2

Answers


  1. while this is not a perfect solution but it could help a bit to improve

    You can use Predefine Placeholer to handle initial size, and here you also need to add error handling

    AnimatedSize(
      duration: const Duration(milliseconds: 300),
      curve: Curves.easeInOut,
      child: CachedNetworkImage(
        imageUrl: 'url',
        placeholder: (context, url) => Container(
          width: double.infinity,
          height: 200, // Fixed height during loading
          color: Colors.grey[300],
        ),
        errorWidget: (context, url, error) => Container(
          width: double.infinity,
          height: 200, // Fixed height for error
          color: Colors.red,
          child: Icon(Icons.error),
        ),
      ),
    ),
    

    now it’s upto you, show an error image or an unsized SizedBox so if an image get’s crashed while fetching will not consume even an pixle for that you can use SizedBox.shrink()

    Login or Signup to reply.
  2. I may have found a solution via trial and error. Here is the code I used in FlutterFlow under a widget. It works around the image dimensions and resizes with minimal effect. (With some FlutterFlow intervention on the code as it didn’t fit protocols and legislations apparently.)

    class NewCustomWidget extends StatefulWidget {
      const NewCustomWidget({
        super.key,
        this.width,
        this.height,
      });
    
      final double? width;
      final double? height;
    
      @override
      State<NewCustomWidget> createState() => _NewCustomWidgetState();
     }
    
      class _NewCustomWidgetState extends State<NewCustomWidget> {
      @override
      Widget build(BuildContext context) {
        return Container();
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search