skip to Main Content

I have created a list view with images in flutter. it works but the images is wrong size. It looks like this:

enter image description here

But what I want is this:

enter image description here

This is the code I am using:

SizedBox(
                      height: 300,
                      child: ListView.builder(
                        shrinkWrap: true,
                        scrollDirection: Axis.horizontal,
                        itemBuilder: (BuildContext ctx, int index) {
                          return SizedBox(
                              width: MediaQuery.of(context).size.width * 0.5,
                              child: Card(
                                child: ClipRRect(
                                  borderRadius: BorderRadius.circular(10),
                                  child: Image.file(
                                    File(_imageFileListM[index].path),
                                    fit: BoxFit.fitWidth,
                                  ),
                                ),
                                margin: const EdgeInsets.all(10),
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(20.0),
                                ),
                              ));
                        },
                        itemCount: _imageFileListM.length,
                      ))

What am I doing wrong?

4

Answers


  1. use container widget Box decoration property
    like this may help you

    Container(
    height: 200.h,
    width: double.infinity,
    decoration: BoxDecoration(
    image: DecorationImage(
    image: AssetImage("Enter your path")
    ),
    color: baseColor2,
    borderRadius: BorderRadius.only(
    bottomLeft:Radius.circular(20.r),
    bottomRight:Radius.circular(20.r))),

    ),

    Login or Signup to reply.
  2. try this:

    SizedBox(
              height: 300,
              child: ListView.builder(
                shrinkWrap: true,
                scrollDirection: Axis.horizontal,
                itemBuilder: (BuildContext ctx, int index) {
                  return SizedBox(
                      width: MediaQuery.of(context).size.width * 0.5,
                      child: Card(
                        elevation: 0,
                        color: Colors.transparent,
                        surfaceTintColor: Colors.transparent,
                        child: Align(
                          alignment: Alignment.center,
                          child: Container(
                            clipBehavior: Clip.antiAlias,
                            decoration: BoxDecoration(
                              color: Colors.transparent,
                              borderRadius: BorderRadius.circular(10),
                            ),
                            child: Image.file(
                              File(_imageFileListM[index].path),
                              fit: BoxFit.contain,
                            ),
                          ),
                        ),
                        margin: const EdgeInsets.all(10),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(20.0),
                        ),
                      ));
                },
                itemCount: _imageFileListM.length,
              )),
    

    enter image description here

    Login or Signup to reply.
  3. Just wrap your list element with FittedBox like this:

    SizedBox(
      height: 300,
      child: ListView.builder(
        shrinkWrap: true,
        scrollDirection: Axis.horizontal,
        itemBuilder: (BuildContext ctx, int index) {
          return SizedBox(
              width: MediaQuery.of(context).size.width * 0.5,
              child: FittedBox(
                child: Card(
                  child: ClipRRect(
                    borderRadius: BorderRadius.circular(20),
                    child: Image.file(
                      File(_imageFileListM[index].path),
                      fit: BoxFit.fitWidth,
                    ),
                  ),
                  margin: const EdgeInsets.all(10),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(20.0),
                  ),
                ),
              ));
        },
        itemCount: _imageFileListM.length,
      )))
    
    Login or Signup to reply.
  4. A simple way to achieve this is to use Stack and position.

    Stack allows widgets to overlap each other.
    Positioned allows you to render its child at a specific location within the stack.

    The stack is pretty much like a column but the widgets are rendered on top of each other therefore you need to specify how they should render.

    This would be your main Image Widget:

    1. The image is wrapped in an expanded-sized box to cover the whole space.

    2. positioned is set to bottom 0 will stick the widget to the bottom.
      left and right are specified to be 0 so the widget also expands horizontally.

    class ImageWidget extends StatelessWidget {
      final String url;
      const ImageWidget({super.key, required this.url});
    
      @override
      Widget build(BuildContext context) {
        return ClipRRect(
          borderRadius: BorderRadius.circular(16),
          child: Stack(
            children: [
              SizedBox.expand(
                child: Image.network(
                  url,
                  fit: BoxFit.contain,
                ),
              ),
              const Positioned(
                left: 0,
                right: 0,
                bottom: 0,
                child: ImageChildWidget(),
              ),
            ],
          ),
        );
      }
    }
    

    This would be the bottom part. you can replace this with anything you’d like.

    class ImageChildWidget extends StatelessWidget {
      const ImageChildWidget({super.key});
    
      @override
      Widget build(BuildContext context) {
        return const ColoredBox(
          color: Color.fromARGB(155, 0, 0, 0),
          child: Padding(
            padding: EdgeInsets.all(8),
            child: Text(
              'Some Long Text',
              style: TextStyle(
                color: Colors.white,
                fontSize: 16,
              ),
            ),
          ),
        );
      }
    }
    

    You also have a grid view, it’s easy with gridDelegate

    • crossAxisCount: 2, says that you want 2 elements per row
    • mainAxisSpacing: 16, says that you want a padding of 16 vertically
    • crossAxisSpacing: 16, says that you want a padding of 16 horizontally
    class GridExample extends StatefulWidget {
      const GridExample({super.key});
    
      @override
      State<GridExample> createState() => GridExampleState();
    }
    
    class GridExampleState extends State<GridExample> {
      // Generate a random list of images
      List<String> urls = List.generate(
        10,
        (_) {
          int random = Random().nextInt(500) + 250; // 250-500
          return 'https://picsum.photos/$random/$random';
        },
      );
    
      @override
      Widget build(BuildContext context) {
        return GridView.builder(
          key: widget.key,
          itemCount: urls.length,
          padding: const EdgeInsets.all(16),
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
            mainAxisSpacing: 16,
            crossAxisSpacing: 16,
          ),
          itemBuilder: (context, index) {
            return ImageWidget(
              key: ValueKey(urls[index]),
              url: urls[index],
            );
          },
        );
      }
    }
    

    Full code sample.

    import 'dart:math';
    
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            body: Center(
              child: GridExample(
                key: ValueKey('grid'),
              ),
            ),
          ),
        );
      }
    }
    
    class GridExample extends StatefulWidget {
      const GridExample({super.key});
    
      @override
      State<GridExample> createState() => GridExampleState();
    }
    
    class GridExampleState extends State<GridExample> {
      // Generate a random list of images
      List<String> urls = List.generate(
        10,
        (_) {
          int random = Random().nextInt(500) + 250; // 250-500
          return 'https://picsum.photos/$random/$random';
        },
      );
    
      @override
      Widget build(BuildContext context) {
        return GridView.builder(
          key: widget.key,
          itemCount: urls.length,
          padding: const EdgeInsets.all(16),
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
            mainAxisSpacing: 16,
            crossAxisSpacing: 16,
          ),
          itemBuilder: (context, index) {
            return ImageWidget(
              key: ValueKey(urls[index]),
              url: urls[index],
            );
          },
        );
      }
    }
    
    class ImageWidget extends StatelessWidget {
      final String url;
      const ImageWidget({super.key, required this.url});
    
      @override
      Widget build(BuildContext context) {
        return ClipRRect(
          borderRadius: BorderRadius.circular(16),
          child: Stack(
            children: [
              SizedBox.expand(
                child: Image.network(
                  url,
                  fit: BoxFit.contain,
                ),
              ),
              const Positioned(
                left: 0,
                right: 0,
                bottom: 0,
                child: ImageChildWidget(),
              ),
            ],
          ),
        );
      }
    }
    
    class ImageChildWidget extends StatelessWidget {
      const ImageChildWidget({super.key});
    
      @override
      Widget build(BuildContext context) {
        return const ColoredBox(
          color: Color.fromARGB(155, 0, 0, 0),
          child: Padding(
            padding: EdgeInsets.all(8),
            child: Text(
              'Some Long Text',
              style: TextStyle(
                color: Colors.white,
                fontSize: 16,
              ),
            ),
          ),
        );
      }
    }
    
    

    End result:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search