How to make flutter card auto adjust its height depend on content

Try flutter_staggered_grid_view package.

In the pubspec.yaml , add the following dependency:

dependencies:
  flutter_staggered_grid_view: any

In your library , add the following import:

import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';

Example:

  StaggeredGridView.countBuilder(
  crossAxisCount: 4,
  itemCount: 8,
  itemBuilder: (BuildContext context, int index) => new Container(
      color: Colors.green,
      child: new Center(
        child: new CircleAvatar(
          backgroundColor: Colors.white,
          child: new Text('$index'),
        ),
      )),
  staggeredTileBuilder: (int index) =>
      new StaggeredTile.count(2, index.isEven ? 2 : 1),
  mainAxisSpacing: 4.0,
  crossAxisSpacing: 4.0,
),

Use it like GridView

Output:

enter image description here


Constructors :

The StaggeredGridView follow the same constructors convention than the GridView. There are two more constructors: countBuilder and extentBuilder. These constructors allow you to define a builder for the layout and a builder for the children.

Tiles :

A StaggeredGridView needs to know how to display each tile, and what widget is associated with a tile.

A tile needs to have a fixed number of cell to occupy in the cross axis. For the extent in the main axis you have 03 options:

  1. You want a fixed number of cells => use StaggeredTile.count.
  2. You want a fixed extent => use StaggeredTile.extent.
  3. You want a variable extent, defined by the content of the tile itself => use StaggeredTile.fit.

The problem comes from SliverGridDelegateWithFixedCrossAxisCount:

Creates grid layouts with a fixed number of tiles in the cross axis
This delegate creates grids with equally sized and spaced tiles.

I recommend you to use flutter_staggered_grid_view: and to give up to AspectRatio widget. More about tiles here.

body: StaggeredGridView.countBuilder(
   crossAxisCount: 2,
   itemCount: 6,
   itemBuilder: (BuildContext context, int index) => 
     Card(
       margin: const EdgeInsets.all(10.0),
       child: Container(
         child: Column(
           crossAxisAlignment: CrossAxisAlignment.start,
           children: [
            Image.network('https://upload.wikimedia.org/wikipedia/commons/6/66/An_up-close_picture_of_a_curious_male_domestic_shorthair_tabby_cat.jpg',
              fit: BoxFit.fill,
            ),
            Padding(
              padding: EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 8.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text("Cat",textAlign: TextAlign.center),
                ],
            ),
         )],
       ),
     )
   ),
   staggeredTileBuilder: (int index) =>
     StaggeredTile.fit(1),
)

You want to wrap your card in a Column because the inner Column take full height

 Column(children: <Widget>[
      Card(
        margin: const EdgeInsets.all(10.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            AspectRatio(
              aspectRatio: 18.0 / 13.0,
              child: Image.network(
               "https://picsum.photos/200",
                fit: BoxFit.fill,
              ),
            ),
            Padding(
              padding: EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 8.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    "Just add your desired image size (width & height) after our URL, and you'll get a random image.",
                    textAlign: TextAlign.center,
                  ),
                ],
              ),
            ),
          ],
        ),
      )
])

enter image description here