1

I have a page with container + listView. Now the listView is scrollable, but I would like the whole page to be scrollable. (so if the user scrolls, the container goes 'away')

Column(
        children: <Widget>[
          Container(
              color: Colors.white.withOpacity(0.95),
              width: 400,
              height: 400,
              child: Text("")),
          ListView(
              children: posts,
            ),
        ],
      ),

Is this possible, and how can it be achieved?

Thanks!

Karel Debedts
  • 5,226
  • 9
  • 30
  • 70

5 Answers5

13

You can wrap the whole page with a SingleChildScrollView

here is an example:

SingleChildScrollView( // <- added
    child: Column(
        children: <Widget>[
          Container(
              color: Colors.white.withOpacity(0.95),
              width: 400,
              height: 400,
              child: Text("")),
          ListView(
              shrinkWrap: true, // <- added
              primary: false, // <- added
              children: posts,
            ),
        ],
      ),
);

for more info about see this question

Zvi Karp
  • 3,621
  • 3
  • 25
  • 40
7
  1. What if you don't use Column and use ListView.builder and according to indexes you show the widget.
  2. For example on 0 index you show the Container.
  3. This way you don't have to use any different widget for scrolling and as per your requirement the container will scroll with the list.
  4. This way there is no chance that you will get any overflow error like you were getting while using Column.
  5. Plus point of ListView.builder is that your posts will be created lazily and that is efficient way of creating ListView in Flutter. No matter how many posts you have your UI will not lag.
  6. This at first may look like a hack but according to your requirement that the container must also be able to get scrolled, this solution makes sense to me because Container can be considered as a first element of the list.

Let me know if it works for you or not.

Following is the working code for your reference:

@override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: posts.length + 1, // +1 because you are showing one extra widget.
      itemBuilder: (BuildContext context, int index) {
        if (index == 0) {
          return Container(
              color: Colors.white.withOpacity(0.95),
              width: 400,
              height: 400,
              child: Text(""));
        }
        int numberOfExtraWidget = 1; // here we have 1 ExtraWidget i.e Container.
        index = index - numberOfExtraWidget; // index of actual post.
        return posts[index]; 
      },
    );
  }

I hope this works for you, in case of any doubt please comment.

Kalpesh Kundanani
  • 5,413
  • 4
  • 22
  • 32
3

There are multiple ways you can achieve what you want. The only problem is that if you have large number of posts, listview with children posts, as shrinkWrap is set to true, will take time to calculate its required height, for that it will have to populate all of its children.

First

ListView(
    children: <Widget>[
      Container(
          color: Colors.white.withOpacity(0.95),
          width: 400,
          height: 400,
          child: Text("")),
      ListView(
        physics: NeverScrollableScrollPhysics(),
        primary: false, 
        shrinkWrap: true,
        children: posts,
        ),
      ),
    ],
  ),

Second

SingleChildScrollView(
    child: Column(
      children: <Widget>[
        Container(
            color: Colors.white.withOpacity(0.95),
            width: 400,
            height: 400,
            child: Text("")),
        ListView(
          physics: NeverScrollableScrollPhysics(),
          shrinkWrap: true,
          primary: false,
          children: posts,
        ),
      ],
    ),
  ),
dlohani
  • 2,511
  • 16
  • 21
  • Thanks, with solution one I have this error: Vertical viewport was given unbounded height. With solution 2 I have this error: A RenderFlex overflowed by 1232 pixels on the bottom. – Karel Debedts Dec 28 '19 at 08:39
2

use SingleChildScrollView then Container with hard coded container height, then list view builder, that should fix your issue.

kapil
  • 91
  • 1
  • 3
  • 15
  • Thanks, it works indeed, but is there an option to get a flexible container? – Karel Debedts Dec 27 '19 at 12:05
  • 1
    @KarelDebedts u can use mediaquery to set dimensions of container. That will give it some flexibility. But other than that, i don't think thete is a good approach. – kapil Dec 28 '19 at 12:04
2

I tried the following:

SingleChildScrollView(
      child: Container(
        height: 1000,
        width: 400,
        child: ListView(
          children: <Widget>[
          Container(
              color: Colors.white.withOpacity(0.95),
              width: 400,
              height: 400,
              child: Text("")),
          ListView(
              children: posts,
            ),
        ],
      ),
     ),
    ),

This works, but I would like that the container has a dynamic height and width? Is that possible? Thanks!

Karel Debedts
  • 5,226
  • 9
  • 30
  • 70