Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper method for setting childAspectRatio in flutter

What is the proper way of calculating childAspectRatio of SliverGridDelegateWithFixedCrossAxisCount in flutter. How to manage the the correct height of each view that is compatible with all devices and should work in landscape and portrait

GridView.builder(
    physics: BouncingScrollPhysics(),
    padding: const EdgeInsets.all(4.0),
    itemCount: snapshot.data.results.length,
    gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: itemCount,
      childAspectRatio: 0.501,
      mainAxisSpacing: 4.0,
      crossAxisSpacing: 4.0,
    ),
    itemBuilder: (BuildContext context, int index) {
      return GridTile(
          child: _buildGridItem(context, snapshot.data.results[index]));
    });
like image 978
Ashwin S Ashok Avatar asked May 10 '19 06:05

Ashwin S Ashok


People also ask

How do you calculate Childaspectratio in Flutter?

child aspect ratio is basically width/height of the grid. So let's say you want the width of each grid to be 30 and the height to be 20, you would set the aspect ratio to be 3/2.

What is Childaspectratio in Flutter?

The ratio of the cross-axis to the main-axis extent of each child.

What is crossAxisCount Flutter?

int crossAxisCount. The number of children in the cross axis.

What is SliverGridDelegateWithFixedCrossAxisCount?

SliverGridDelegateWithFixedCrossAxisCount class Null safety. Creates grid layouts with a fixed number of tiles in the cross axis. For example, if the grid is vertical, this delegate will create a layout with a fixed number of columns.


1 Answers

DISCLAIMER: This is theoretical explanation of how GridView works. Proposed solution is not designed for heavy content. Use GridView theory that I describe here to build layout that you desire.

Let me start with crossAxisCount, which is supposed to be interpreted as a number of columns in a table.

e.g. crossAxisCount: 3,

|  cell-1  ||  cell-2  ||  cell-3  |
------------------------------------ // new row after every 3 cells
|  cell-4  ||  cell-5  ||  cell-6  |

What flutter does with crossAxisCount: N, is tries to fit exactly N number of cells in a row. Hence, width of one individual cell will equal grid width divided by N.

e.g. crossAxisCount: 3, -> cellWidth = parentWidth / 3 (pseudocode)


Now, what happens next is calculation of cell's height using childAspectRatio that your initial question is about.

e.g. cellWidth = parentWidth / crossAxisCount & cellHeight = cellWidth / childAspectRatio.

This way, you should interpret childAspectRatio as a ratio of every individual cell's width to its height (and vice versa).


I assume you noticed that GridView is rather limited when it comes to unusually structured layout.

In case you truly think that GridView is not enough for what you are trying to build - I'd recommend using other widgets that support multiple children layout. For instance, I use Wrap widget to display very fluid content, in which every element has its own dynamic width & height.

I am not aware of what type of layout you need, but in case of a very dynamic / fluid yet light concept you can try using Wrap:

@override
Widget build(BuildContext context) {
  final mediaQuery = MediaQuery.of(context);
  return SingleChildScrollView(
    child: Wrap(
      children: List.generate(totalItemsToDisplay, (index) {
        final cellWidth = mediaQuery.size.width / 3; // Every cell's `width` will be set to 1/3 of the screen width.
        return SizedBox(
          width: cellWidth,
          // You can either use some static number for `height`, or set ratio to cellWidth.
          // Setting `height` to `null` should work too, which would make height of a cell auto-resizable according to its content.
          height: 123,
          child: ...,
        );
      })
    )
  );
}

However, I would not recommend using this to display large sets of data.

If your goal is to display a set of posts / articles / pictures etc., something that initially implies structured heavy content - I would recommend going with GridView by standardising cells height through childAspectRatio.

like image 162
George Avatar answered Oct 01 '22 19:10

George