1

I want to achieve a screen that is scrollable(vertically) with the elements inside it. So I placed it on a listview.builder. The thing is, one of the elements is another listview.builder that scrolls horizontally. When I implemented it, element inside the horizontal.builder doesn't show up. Here is what I have so far:

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: 3,
      itemBuilder: (context, position) {
        if (position == 0) {
          return Card(
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(15.0),
            ),
            elevation: 1.5,
            margin: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 0.0),
            child: Padding(
              padding: EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 0.0),
              child: Column(
                children: <Widget>[
                  //PICTURE
                  Padding(
                    padding: const EdgeInsets.only(bottom: 8.0),
                    child: Center(
                      child: Image.asset(
                        "assets/snek.gif",
                        fit: BoxFit.scaleDown,
                      ),
                    ),
                  ),

                  Padding(
                    padding: const EdgeInsets.only(bottom: 16.0),
                    child: Text(
                      HOME_GIF_TEXT_STR,
                      textAlign: TextAlign.center,
                      style: TextStyle(fontSize: 18.0),
                    ),
                  ),
                ],
              ),
            ),
          );
        } 
        else if (position == 1) //Videos Title
        {
          return Padding(
            padding: EdgeInsets.all(16.0),
            child: Text(
              "Videos",
              style: TextStyle(
                  fontSize: 36.0,
                  fontWeight: FontWeight.bold,
                  color: Colors.black),
            ),
          );
        }
        else if (position == 2) //Videos
        {
          Container(
            height: 350.0,
            child: ListView.builder(
              physics: NeverScrollableScrollPhysics(),
              itemCount: 3,
              controller: scrollController,
              scrollDirection: Axis.horizontal,
              itemBuilder: (context, position) {
                return GestureDetector(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Card(
                        child: Container(
                          width: 280.0,
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.center,
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: <Widget>[
                              Column(
                                children: <Widget>[
                                  Container(
                                    height: 230.0,
                                    decoration: new BoxDecoration(
                                      image: new DecorationImage(
                                        fit: BoxFit.cover,
                                        image: new AssetImage(
                                            "${videoList[position].imgPath}"),
                                      ),
                                    ),
                                  ),
                                  Padding(
                                    padding: EdgeInsets.only(top: 8.0),
                                    child: Text(
                                      "${videoList[position].name}",
                                      style: TextStyle(fontSize: 28.0),
                                    ),
                                  ),
                                ],
                              ),
                            ],
                          ),
                        ),
                        shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(10.0)),
                      ),
                    ),
                    onHorizontalDragEnd: (details) {
                      if (details.velocity.pixelsPerSecond.dx > 0) {
                        if (cardIndex > 0) cardIndex--;
                      } else {
                        if (cardIndex < 2) cardIndex++;
                      }
                      setState(() {
                        scrollController.animateTo((cardIndex) * 256.0,
                            duration: Duration(milliseconds: 500),
                            curve: Curves.fastOutSlowIn);
                      });
                    },
                    onTap: () {
                      _launchURL("${videoList[position].url}");
                    });
              },
            ),
          );
        } 
        else if (position == 3)
        {
          return Padding(
            padding: EdgeInsets.all(16.0),
            child: Text(
              "Useful Links",
              style: TextStyle(
                  fontSize: 36.0,
                  fontWeight: FontWeight.bold,
                  color: Colors.black),
            ),
          );
        }
        else if (position == 4) //Links
        {
          //TODO PUT LINKS
        } 
      },
    );
  }
}

First two elements shows up correctly. I also tried the element in position == 2 in other environment but outside a listview.builder and is perfectly working. Any thoughts on why it doesn't show up? Thanks.

1
  • Try to set the parameter shrinkWrap to true in your ListView. Also you could put your ListView inside an Èxpanded()` Widget Commented Jan 30, 2019 at 6:20

1 Answer 1

3

You are not returning Widget if(position == 2)

if (position == 2) {
  //Add Return Statement HERE:
  return Container(
    height: 350.0,
    child: ListView.builder(
      physics: NeverScrollableScrollPhysics(),
      itemCount: 3,
      controller: scrollController,
      scrollDirection: Axis.horizontal,
      itemBuilder: (context, position) {
        return GestureDetector(
          // All other stuff
        );

      },
    ),
  );
 } 
Sign up to request clarification or add additional context in comments.

2 Comments

Nice catch haha. For the OP - if you're only building a few items in the list, using builder and positions has much less of an advantage, so you could probably use the construct that just accepts a list instead. The builder becomes more useful when you have many more items than fit on the screen - that way flutter doesn't have to actually instantiate them all at once.
Waah. Wasted hours just for this simple mistake. Thank you Tornike!

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.