alecsam
alecsam

Reputation: 591

Flutter: multiple lists with multiple scroll controllers

I want to create a scrollable page with multiple widgets, each representing a ListView. Some of these lists have a scrolling controller for loading multiple items. I want to be able to controll scrolling in each widget, but I also want to scroll on page.

Something like this:
MainPage (I tried Column):
- Widget1 > a ListView.separated with scrollDirection: Axis.horizontal
- Widget2 > a ListView.separated with scrollDirection: Axis.horizontal
- Widget3 > a ListView.builder with scrollDirection: Axis.vertical; each item on the list contains a GridView.builder; this list has a scrolling controller for loading multiple items
- Widget4 > idem Widget3 (a ListView.builder with scrollDirection: Axis.vertical; this list has also a scrolling controller for loading more elements)

MainPage:

  Column(
   children: <Widget>[
    DocumentsFiltersWidget() //Widget1,
    ReportsListWidget() //Widget2,
    Expanded(child: DocumentsListWidget()) //Widget3,
    Expanded(child: DocumentsListWidget()) //also Widget3
   ]
 )

Widget3

  ScrollController _scrollController = new ScrollController();

  @override
  void initState() {
    _scrollController.addListener(() async {
      double maxScroll = _scrollController.position.maxScrollExtent;
      double currentScroll = _scrollController.position.pixels;

      if (currentScroll == maxScroll) { 
        print("loadMore");
      }
    });

    super.initState();
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return 
    ListView.builder(
      controller: _scrollController,
      shrinkWrap: true,
      itemCount: 2,
      itemBuilder: (BuildContext context, int index) {
        return Padding(
          padding: EdgeInsets.fromLTRB(12.0, 0.0, 12.0, 0.0),
          child: Column(
            children: <Widget>[
              SizedBox(height: 10.0),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Text("List ${index.toString()}"),
              ]),
              Container(
                margin: EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
                decoration: new BoxDecoration(
                  border: new Border.all(color: Colors.grey, width: 0.3)
                )
              ),
              GridView.builder(
                physics: NeverScrollableScrollPhysics(),
                shrinkWrap: true,
                itemCount: 10,
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, mainAxisSpacing: 5.0, childAspectRatio: 0.75),
                itemBuilder: (BuildContext context, int index) {
                  return Card(
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0)),
                    child: Padding(
                      padding: EdgeInsets.all(5.0),
                      child: Text("DocumentCard ${index.toString()}")
                    )
                  );
                }
              )
            ],
        ),
      );
    });
  }

Everything works fine, except I can't scroll through the entire page, Widget1 and Widget2 are stuck. Like this. I think it's because of the Column and Extended widget but if I replace Column with ListView, Widget3 _scrollController.addListener no longer triggers.

Upvotes: 0

Views: 4046

Answers (1)

Steve Cahn
Steve Cahn

Reputation: 13

There are two ways to go about it. Either use ListView or SingleChildScrollView.

Another way to achieve the same thing is to use a SingleChildScrollView:

return new Container(
  child: new ListView(
    children: <Widget>[
      Column(
      children: <Widget>[
        Child1(),
        Child2(),
        ...
        ChildN()
      ]
    ),
  ],
  )
);

Or:

return new Container(
  child: new SingleChildScrollView(
    child: new Column(
      children: <Widget>[
        _showChild1(),
        _showChild2(),
        ...
        _showChildN()
      ]
    )
  )
);

Let me know if this works and if you have any questions.

Upvotes: 0

Related Questions