7

I am unable to set the dynamic size to my list item of list view builder, every time it shows blank screen and when I specify a constant size it works.

I tried by using column by setting mainAxisSize=minimum and by using container as we know container wraps the child height but nothing works

 listItem (GuideLines news) =>Column(
    mainAxisAlignment: MainAxisAlignment.start,
    mainAxisSize:  MainAxisSize.min,
    children: <Widget>[Container(
      decoration: BoxDecoration(image: new DecorationImage(image: AdvancedNetworkImage(
        "${news.featured_image}",
        useDiskCache: true,
        cacheRule: CacheRule(maxAge: const Duration(days: 7)),
      ),fit: BoxFit.cover)),
      margin: EdgeInsets.only(bottom: 10.0),
      child: ListTile(
        onTap: (){
          print(news.web_link);
          Navigator.push(context, MaterialPageRoute(builder: (context) => NewsDetailsPage(news)));
        },
        title: new Container(
            margin: EdgeInsets.only(left: 30.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.max,
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.only(top: 20.0),
                  child: new Text("${DateFormat("E, d MMM y").format(CommonService.dateFormat(news.publish_date.toString()))}", style: TextStyle(fontFamily: 'SF-Display-Regular' ,fontSize: 13.0 ,color: Colors.white),),
                ),
                SizedBox(height: 13.0),
                new Flexible(
                  child: new Container( width:  MediaQuery.of(context).size.width  *0.45,
                      child: Padding(
                        padding: const EdgeInsets.only(bottom: 20.0),
                        child: new Text("${news.title}" ,maxLines: 3, overflow: TextOverflow.ellipsis, style: TextStyle(fontFamily: 'SF-Display-Semibold' ,fontSize: 22.0 ,color: Colors.white),),
                      )


                  ),
                )
              ],
            )),
        trailing: Padding(
          padding: const EdgeInsets.only(right: 20),
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[Icon(Icons.arrow_forward_ios, color: Colors.white),SizedBox(width: 8,)],
          ),
        ),
      ),


    )],
  );
2
  • What is the outer Column good for? Why is the trailing Icon wrapped in a Row and Padding around it? Why does the Column for the title have the property: mainAxisSize: MainAxisSize.max? Inside the Flexible widget you have a Container and inside it is a Padding widget, you do not need this Padding widget because a Container has a Padding property. All in all, it seems to me that the code contains a lot of unnecessary stuff. I think for what you're doing, you shouldn't use a ListItem and customize it that extreme, but write your own widget instead. Commented May 28, 2019 at 8:46
  • i will update the code inside listTile but still the code inside listtile has nothing to do with my problem.i just want to wrap the list tile to whatever the listtile size is Commented May 28, 2019 at 8:49

2 Answers 2

10

Just add these two properties of shrinkWrap and physics to make the height of list dynamic

ListView.builder(
   shrinkWrap: true,
   physics: NeverScrollableScrollPhysics(), //Optional                               
   itemCount: size,
   itemBuilder: (context, position) {}
),
Sign up to request clarification or add additional context in comments.

4 Comments

If we don't specified a size, Scroll controller will not work. also for huge list this will cause so much lag..
@ÄRÂmmãřŻąîñh listview.builder loads only the items that are fit on the screen and when we scroll the screen. it will load more data. if your list is in thousands or greater you can use pagination for this.
No you tried to load all the list components at whole remaining screen without listview size (height). If you did this default scroll physics will not work because of it didn't have the specified size, that's why you remove the scroll feature from the list view by giving NeverScrollableScrollPhysics(), so parent scroll view will be take the scroll feature from this. and we will loose the many of listview feature like scroll controller, cacheExtent like many of useful feature. If you compare the listview with 1000s records with size and without size you can see huge different in performance.
yes, for dynamic height you can use this argument only "shrinkWrap: true,"
3

The problem with your code is, that you used a Flexible widget in a Column. A Flexible widget expands to the remaining space of the Column or Row. However, this only works if you have restricted the size of the Column or Row widget. Because otherwise, the size of the element in the Column would expand to infinity as the remaining space is not restricted and therefore also infinity.

When using Flexible or Expanded widgets you always need to restrict their parent size, else you get this error:

RenderFlex children have non-zero flex but incoming height constraints are unbounded. When a column is in a parent that does not provide a finite height constraint, for example if it is in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining space in the vertical direction.

The solution and some cleanup of your code:

Widget listItem(GuideLines news) {
  return Container(
    decoration: BoxDecoration(
      image: DecorationImage(
          image: AdvancedNetworkImage(
            "${news.featured_image}",
            useDiskCache: true,
            cacheRule: CacheRule(maxAge: const Duration(days: 7)),
          ),
          fit: BoxFit.cover),
    ),
    margin: EdgeInsets.only(bottom: 10.0),
    child: ListTile(
      onTap: () {
        print(news.web_link);
        Navigator.push(context, MaterialPageRoute(builder: (context) => NewsDetailsPage(news)));
      },
      title: Container(
        margin: EdgeInsets.only(left: 30.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.only(top: 20.0, bottom: 13.0),
              child: Text(
                "${DateFormat("E, d MMM y").format(CommonService.dateFormat(news.publish_date.toString()))}",
                style: TextStyle(fontFamily: 'SF-Display-Regular', fontSize: 13.0, color: Colors.white),
              ),
            ),
            Container(
              width: MediaQuery.of(context).size.width * 0.45,
              padding: const EdgeInsets.only(bottom: 20.0),
              child: new Text(
                "${news.title}",
                maxLines: 3,
                overflow: TextOverflow.ellipsis,
                style: TextStyle(fontFamily: 'SF-Display-Semibold', fontSize: 22.0, color: Colors.white),
              ),
            )
          ],
        ),
      ),
      trailing: Padding(
        padding: const EdgeInsets.only(right: 28),
        child: Icon(Icons.arrow_forward_ios, color: Colors.white),
      ),
    ),
  );
}

In your specific case, this Flexible widget was redundant anyway.

1 Comment

can u explain the fix to me, i didnt understand how its working now, bcz previously i was using container but it was not working

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.