'Using a ListViewBuilder with a row in flutter

I'm receiving data from a database that works but I have an issue where the data is not being displayed in a CustomWidget card I've created. I've tried using shrinkwrap, expanded, and flexible but none work. I'm assuming it might be my placement but I'm not so sure. I'm getting these errors:

*'package:flutter/src/rendering/viewport.dart': Failed assertion: line 1869 pos 16: 'constraints.hasBoundedWidth': is not true.

RenderBox was not laid out: RenderShrinkWrappingViewport#39186 relayoutBoundary=up36 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE

'package:flutter/src/rendering/box.dart':

Failed assertion: line 1982 pos 12: 'hasSize'*

  Widget build(BuildContext context) {
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: SizedBox(
        height: 200,
        child: FutureBuilder(
          future: _getListing(),
          builder: (context,AsyncSnapshot snapshot) {
            if(snapshot.hasData) {
              print(snapshot.data.length);
              return ListView.builder(
                  shrinkWrap: true,
                  itemCount:snapshot.data.length,
                  itemBuilder: (context,index) {
                  return Row(children:  <Widget>[
                  Flexible(
                    child: ItemsCard(
                      image: defaulturl+"${snapshot.data[index].image}", // var defaulturl = "https://sam-thige.000webhostapp.com/productimages/";
                      title: "${snapshot.data[index].description}",
                      location: "${snapshot.data[index].location}",
                    ),
                  ),
            ]);
                }
              );
            }
            else{
              return Center(child: CircularProgressIndicator(),);
            }
          }
        ),
      ),
    );
  }

This is the ItemsCard widget

class ItemsCard extends StatelessWidget {
  const ItemsCard({
    Key? key,
    required this.location,
    required this.image,
    required this.title,
  }) : super(key: key);

  final String image, title, location;

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Container(
        margin: EdgeInsets.only(left: 20.0, top: 10.0, bottom: 50.0),
        width: size.width * 0.4,
        child: Column(
          children: <Widget>[
            Image.network(image),
            GestureDetector(
              child: Container(
                padding: EdgeInsets.all(10.0),
                decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.only(
                        bottomLeft: Radius.circular(10),
                        bottomRight: Radius.circular(10)),
                    boxShadow: [
                      BoxShadow(
                          color: Color.fromARGB(251, 105, 111, 216),
                          blurRadius: 20.0,
                          offset: Offset(0, 10))
                    ]),
                child: Row(
                  children: <Widget>[
                    RichText(
                        text: TextSpan(children: [
                          TextSpan(
                              text: "$title \n",
                              style: Theme.of(context).textTheme.button),
                          TextSpan(
                              text: "$location",
                              style: TextStyle(color: Colors.blue.withOpacity(0.5)))
                        ]))
                  ],
                ),
              ),
            )
          ],
        ));
  }
}


Solution 1:[1]

Since you are not giving us the full code of your custom widget named ItemsCard, it's kinda hard to tell if the Row -> Flexible widget parents are necessary. Skipping that, your ListView.builder it's not horizontal, but vertical, so it doesn't have any space to render horizontally. The solution for this is to add width to your SizedBox like this:

Widget build(BuildContext context) {
  return SingleChildScrollView(
    scrollDirection: Axis.horizontal,
    child: SizedBox(
      height: 200,
      width: MediaQuery.of(context).size.width //adding the whole screen's width,
      child: FutureBuilder(
        future: _getListing(),
        builder: (context,AsyncSnapshot snapshot) {
          if(snapshot.hasData) {
            print(snapshot.data.length);
            return ListView.builder(
                shrinkWrap: true,
                itemCount:snapshot.data.length,
                itemBuilder: (context,index) {
                return Row(children:  <Widget>[
                Flexible(
                  child: ItemsCard(
                    image: defaulturl+"${snapshot.data[index].image}", // var defaulturl = "https://sam-thige.000webhostapp.com/productimages/";
                    title: "${snapshot.data[index].description}",
                    location: "${snapshot.data[index].location}",
                  ),
                ),
                ]);
              }
            );
          }
          else{
            return Center(child: CircularProgressIndicator(),);
          }
        }
      ),
    ),
  );
}

Solution 2:[2]

You need to provide a fixed height and width for your listView.Builder. You can use it as a parent of FutureBulder or as a parent of listView.builder. You can change the height or width as your requirement. It is just the solution.

Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: FutureBuilder(
          future: _getListing(),
          builder: (context, AsyncSnapshot snapshot) {
        if (snapshot.hasData) {
          return SizedBox(
              height: size.height,
              width: size.width,
              child: ListView.builder(
                  shrinkWrap: true,
                  itemCount: snapshot.data.length,
                  itemBuilder: (context, index) {
                    return Row(children: const <Widget>[
                      Flexible(
                        child: ItemsCard(
                          image: defaulturl +
                              "${snapshot.data[index].image}", // var
                          // defaulturl = "https://sam-thige.000webhostapp.com/productimages/";
                          title: "${snapshot.data[index].description}",
                          location: "${snapshot.data[index].location}",
                        ),
                      ),
                    ]);
                  }));
        } else {
          return Center(
            child: CircularProgressIndicator(),
           );
         }
       }
     ),
  );
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Rodrigo Molero
Solution 2 Salim Murshed