Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter scrollable body with horizontal list and grid as children

Tags:

flutter

dart

I'm having a hard time understanding how to best create a scrollable container for the body that holds inside children that by default are scrollable as well.

In this case the grid shouldn't scroll but it's the entire page that should scroll so you are able to see more of the elements inside the grid. So basically the whole content should move vertically with the addition of the ListView moving horizontally (but that works fine already)

I had it working but it was using a bunch of "silver" widget, and I'm hoping there's a better solution that works without using all those extra widgets.

Thanks

Here's my code so far:

class GenresAndMoodsPage extends AbstractPage {
  @override
  String getTitle() => 'Genres & Moods';

  @override
  int getPageBottomBarIndex() => BottomBarItems.Browse.index;

  static const kListHeight = 150.0;

  Widget _buildHorizontalList() => SizedBox(
        height: kListHeight,
        child: ListView.builder(
          scrollDirection: Axis.horizontal,
          itemCount: 20,
          itemBuilder: (_, index) =>
              CTile(heading: 'Hip Hop', subheading: '623 Beats'),
        ),
      );

  Widget _buildGrid() => GridView.count(
        crossAxisCount: 2,
        crossAxisSpacing: LayoutSpacing.sm,
        mainAxisSpacing: LayoutSpacing.sm,
        children: List.generate(10, (index) {
          return CTile(
            padding: false,
            heading: 'Kevin Gates Type Beat',
            subheading: '623 FOLLOWERS',
            width: double.infinity,
          );
        }),
      );

  @override
  Widget buildBody(_) {
    return ListView(children: [
      CSectionHeading('Popular Genres & Moods'),
      _buildHorizontalList(),
      CSectionHeading('All Genres & Moods'),
      _buildGrid(),
    ]);
  }
}

The result should be something like this

enter image description here

like image 559
Giacomo Avatar asked Aug 29 '18 13:08

Giacomo


2 Answers

Create List with Horizontal Scroll direction and called it as a child for Vertical Scroll direction.

body: new ListView.builder(itemBuilder: (context, index){
            return new HorizList();
          })

class HorizList extends StatelessWidget{
 @override
 Widget build(BuildContext context) {
 return new Container(
  height: 100.0,

  child: new ListView.builder(itemBuilder: (context, index){
    return new Card(child: new Container(width: 80.0,
    child: new Text('Hello'),alignment: Alignment.center,));
  }, scrollDirection: Axis.horizontal,),
);
}
}
like image 138
Zulfiqar Avatar answered Sep 24 '22 11:09

Zulfiqar


As we want Popular Genres & Moods section also to scroll, we should not using nestedScroll. In above example GridView is nested inside `ListView. Because of which when we scroll, only the GridView will scroll.

I used Only one ListView to achieve the similar screen.

  • Number of children = (AllGenresAndMoodsCount/2) + 1

    • divide by 2 as we are having 2 elements per row
    • +1 for the first element which is horizontal scroll view.

Please refer the code:

import 'package:flutter/material.dart';

void main() {
  runApp(new Home());
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var image = new Image.network("http://www.gstatic.com/webp/gallery/1.jpg");
    var container = new Container(
      child: image,
      padding: EdgeInsets.only(left: 5.0, right: 5.0, top: 5.0, bottom: 5.0),
      width: 200.0,
      height: 200.0,
    );

    return MaterialApp(
      title: "Scroller",
      home: Scaffold(
        body: Center(
            child: new ListView.builder(
          itemBuilder: (context, index) {
            if (index == 0) { //first row is horizontal scroll
              var singleChildScrollView = SingleChildScrollView(
                  child: Row(
                    children: <Widget>[
                      container,
                      container,
                      container,
                    ],
                  ),
                  scrollDirection: Axis.horizontal);
              return singleChildScrollView;
            } else {
              return new Row(
                children: <Widget>[container, container],
              );
            }
          },
          itemCount: 10, // 9 rows of AllGenresAndMoods + 1 row of PopularGenresAndMoods
        )),
      ),
    );
  }
}
like image 28
Dinesh Balasubramanian Avatar answered Sep 24 '22 11:09

Dinesh Balasubramanian