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:
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:
- You want a fixed number of cells => use
StaggeredTile.count
. - You want a fixed extent => use
StaggeredTile.extent
. - 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,
),
],
),
),
],
),
)
])