flutterflutter-listviewflutter-flexible

How to place horizontal scrollable Listview.builders inside a scrollable column? Flutter


I would like to have a few horizontal scrollable rows which are going to be filled with data from a DB.

The Items in the row have unequal heights as some have 2 line text and some are only one-liners.

These rows should be displayed inside a scrollable column.

This is how it should look like

I found some related articles (linked below) and tried the solutions.

Please see the source-code below.

The problem is that the different rows are not really places below each other with their desired heights but are shrinked to fit on one screen. I think that this is because of the use of the SliverFillRemaining-Widget. But I don't know how to do it better.

This is what it looks like with four sections

This is what it  looks like with more sections

Here is my current code:

The Code on the page:

Widget build(BuildContext context) {
    return const Scaffold(
      body: SafeArea(
        child: CustomScrollView(
          slivers: [
            SliverFillRemaining(
              child: Column(
                children: [
                  Flexible(
                    flex: 1,
                    child: Scroll-Element(),
                    fit: FlexFit.loose,
                  ),
                  Flexible(
                    flex: 1,
                    child: Scroll-Element(),
                    fit: FlexFit.loose,
                  ),
                  Flexible(
                    flex: 1,
                    child: Scroll-Element(),
                    fit: FlexFit.loose,
                  ),
                  Flexible(
                    flex: 1,
                    child: Scroll-Element(),
                    fit: FlexFit.loose,
                  ),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }

Scroll-Element-Code:

@override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: [
          Container(
            padding: const EdgeInsets.fromLTRB(
                20, 0, 20, 0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  "Section",
                  style: cH2Style.copyWith(color: cTextColor),
                ),
              ],
            ),
          ),
          Flexible(
            fit: FlexFit.tight,
            child: ListView.builder(
              shrinkWrap: true,
              scrollDirection: Axis.horizontal,
              itemCount: elements.length < 3 ? elements.length : 3,
              itemBuilder: (context, index) {
                final element = Element.fromDocument(elements[index]);
                return Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Element(),
                    const Padding(
                      padding: EdgeInsets.only(right: 20),
                    )
                  ],
                );
              },
            ),
          ),
        ],
      ),
    );
  }

Element-Code (the ones displayed in the Scroll-Element:

Widget build(BuildContext context) {
    return SizedBox(
      width: MediaQuery.of(context).size.width / 2,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          ClipRRect(
            borderRadius: BorderRadius.circular(10),
            child: AspectRatio(
              aspectRatio: 1,
              child: Image.asset("assets/images/testbild.jpg"),
            ),
          ),
          Text("..."),
        ],
      ),
    );
  }

Related articled: How to use Expanded in SingleChildScrollView?

Flutter Layout: Listview inside Row flexible height inside SingleChildScrollView

4 Horizontal Listviews in a Scrollable Column in FLutter


Solution

  • Try using ListView in place of CustomScrollView like this,

    Widget build(BuildContext context) {
    return const Scaffold(
      body: SafeArea(
        child: ListView(
                children: [
                  Flexible(
                    flex: 1,
                    child: Scroll-Element(),
                    fit: FlexFit.loose,
                  ),
                  Flexible(
                    flex: 1,
                    child: Scroll-Element(),
                    fit: FlexFit.loose,
                  ),
                  Flexible(
                    flex: 1,
                    child: Scroll-Element(),
                    fit: FlexFit.loose,
                  ),
                  Flexible(
                    flex: 1,
                    child: Scroll-Element(),
                    fit: FlexFit.loose,
                  ),
                ],
              ),   
      ),
    );
    }