0

I can't scroll to see my lower grid view. Why is that? What should I change to make this work? Please help!!! Thank you in advance.

Scaffold(
            body: SingleChildScrollView(
              child: Container(
                child: Column(
                  children: <Widget>[
                    Text('GridView 1'),
                    GridView.count(
                      crossAxisCount: 3,
                      shrinkWrap: true,
                      children: List.generate(
                        9,
                        (index) {
                          return TouchableImageCard(
                            imagePath: 'assets/images/view_${index + 1}.jpg',
                          );
                        },
                      ),
                    ),
                    Text('GridView 2'),
                    GridView.builder(
                      itemCount: list_item.length,
                      shrinkWrap: true,
                      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                          crossAxisCount: 3),
                      itemBuilder: (BuildContext context, int index) {
                        return TouchableImageCard(
                          imagePath: 'assets/images/view_${index + 1}.jpg',
                          // width: 150,
                          // height: 150,
                        );
                      },
                    ),
                  ],
                ),
              ),
            ),
          );

Thank you for helping me in flutter.

4 Answers4

1

It actually does work, just not the way you need it.
The problem is that GridView itself is a scrollable widget too. So when you try to scroll the page, it actually tries to scroll those GridViews and not the SingleChildScrollView.
To disable GridView scrolling ability - you need to add one more parameter.

GridView.count(
                physics: NeverScrollableScrollPhysics(),
                ...
              ),
Thepeanut
  • 3,074
  • 1
  • 17
  • 23
0

Try this:

 Center(
    child: SingleChildScrollView(
      padding: const EdgeInsets.all(8.0),
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[]
0

multiple gridview scrollable

Scaffold(
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            Text('GridView 1'),
            Container(
              height: 400,
              child: GridView.count(
                crossAxisCount: 3,
                shrinkWrap: true,
                primary: false,
                children: List.generate(
                  20,
                  (index) {
                    return TouchableImageCard(
                      imagePath: 'assets/images/view_${index + 1}.jpg',
                    );
                  },
                ),
              ),
            ),
            Text('GridView 2'),
            Container(
              height: 400,
              child: GridView.builder(
                itemCount: 20,
                shrinkWrap: true,
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 3),
                itemBuilder: (BuildContext context, int index) {
                  return TouchableImageCard(
                    imagePath: 'assets/images/view_${index + 1}.jpg',
                    // width: 150,
                    // height: 150,
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
Shahoriar Nahid
  • 164
  • 6
  • 11
0

This happens because you have to specify the height to GridView.

I've answered one similar questions here: https://stackoverflow.com/a/76192690/11976596

You can find the same below-

I had a similar issue, where I had a GridView.builder inside a SingleChildScrollView. Now the problem is you can't create a GridView inside SingleChildScrollView because both will try to take as much space available which here makes height unbounded/infinte.

So the solution is to wrap the GridView with a SizedBox and I always prefer to use GridView.Builder.

Now the actual question, "How do I know the size of SizedBox when the list is dynamic ?"

So I wrote this code with a logic to calculate the height of SizedBox dynamically based on the childAspectRatio attribute of GridView

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(title: 'Dynamic GridView', home: Home());
  }
}

class Home extends StatelessWidget {
  const Home({super.key});

  @override
  Widget build(BuildContext context) {
    final double width = MediaQuery.of(context).size.width;
    final double height = MediaQuery.of(context).size.height;
    return Scaffold(
      body: SingleChildScrollView(
        child: Column(
          children: [
            itemGrid(width),
          ],
        ),
      ),
    );
  }

  Widget itemGrid(double width) {
    const int count = 16;
    const int itemsPerRow = 2;
    const double ratio = 1 / 1;
    const double horizontalPadding = 0;
    final double calcHeight = ((width / itemsPerRow) - (horizontalPadding)) *
        (count / itemsPerRow).ceil() *
        (1 / ratio);
    return SizedBox(
      width: width,
      height: calcHeight,
      child: GridView.builder(
        padding: const EdgeInsets.symmetric(horizontal: horizontalPadding),
        itemCount: count,
        physics: const NeverScrollableScrollPhysics(),
        shrinkWrap: true,
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            mainAxisSpacing: 0,
            crossAxisSpacing: 0,
            crossAxisCount: itemsPerRow,
            childAspectRatio: ratio),
        itemBuilder: (context, index) {
          return SizedBox(
            child: Card(
              clipBehavior: Clip.hardEdge,
              child: Column(
                children: [
                  Expanded(
                      child: Image.network(
                          "https://picsum.photos/200?${DateTime.now().millisecondsSinceEpoch.toString()}")),
                  const Padding(
                    padding: EdgeInsets.symmetric(horizontal: 4.0),
                    child: Text(
                      "Lorem Ipsum is a dummy text, lorem ipsum",
                      maxLines: 3,
                      overflow: TextOverflow.ellipsis,
                      style:
                          TextStyle(fontSize: 10, fontWeight: FontWeight.bold),
                      textAlign: TextAlign.start,
                    ),
                  ),
                ],
              ),
            ),
          );
        },
      ),
    );
  }
}

Link to working Dart gist - https://dartpad.dev/?id=05ba8804b19a2978a087c68622000a01

Explanation

  • count is the total number of items or itemCount.
  • itemsPerRow is the number of items in a row or crossAxisCount.
  • ratio is the childAspectRatio attribute of GridView that usually is used to set size of an item inside grid. ratio is calculated as width/height.
  • horizontalPadding is the horizontal padding given to GridView(in case of vertical list)
  • calcHeight is the calculated height of the SizedBox just so you don't need to give a fixed height in case of dynamic lists.
Rishabh Sehgal
  • 45
  • 2
  • 11