Vinh Truong
Vinh Truong

Reputation: 431

Flutter Card child content height is larger than its parent

I'm trying to use a GridView to handle displays for multiple Card, each Card contains of an Image. Unfortunately it turns out that the Image is taking a larger height than its parent (see attached picture for the details).

I'm pretty new to Flutter layout so any ideas why this is happening and how I can resolve this? I want the layout to be something like this:

enter image description here

class SquadSelectionScreen extends StatelessWidget {
  final List<Team> teams;

  const SquadSelectionScreen({super.key, required this.teams});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Squads'),
      ),
      body: GridView.count(
        crossAxisSpacing: 10,
        crossAxisCount: 2,
        padding: const EdgeInsets.all(16),
        children: teams
            .map(
              (team) => SquadView(team: team),
            )
            .toList(),
      ),
    );
  }
}

class SquadView extends StatelessWidget {
  final Team team;

  const SquadView({super.key, required this.team});

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        context.push('/squads/${team.code}');
      },
      child: Card(
        elevation: 1,
        child: Column(
          children: [
            Image(
              image: NetworkImage(team.imageUrl),
            ),
            const SizedBox(
              height: 8,
            ),
            Center(
              child: Text(team.name),
            ),
          ],
        ),
      ),
    );
  }
}

Upvotes: 1

Views: 527

Answers (1)

Septian Dika
Septian Dika

Reputation: 596

Using GridView.count has a very visible drawback, namely the size of the aspect ratio of the grid will always be one (1:1 or Square) and can't be changed.

So if you look at the code above, you can't set an image with the same aspect ratio because the text will sink.

The first suggestion for me if you still want to use GridView.count is

  1. Wrapping your Image with AspectRatio that has value higher than one (example set Ratio to 4/3, 5/3, 16/9, or landscape looks). Note: 4/3 = is higher than 1, 16/9 = is higher than 1, etc..

  2. Then wrap the Text Widget with Expanded()

Example code:

class SquadView extends StatelessWidget {
  final Team team;

  const SquadView({super.key, required this.team});

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {},
      child: Card(
        elevation: 1,
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: [
              AspectRatio(
                aspectRatio: 4/3, // you can set the value to 16/9 or anything that result is higher than one
                child: Image(
                  image: NetworkImage(team.imageUrl),
                  fit: BoxFit.cover, // set How the image looks to Fit
                ),
              ),
              const SizedBox(
                height: 8,
              ),
              Expanded(
                child: Center(
                  child: Text(team.name, overflow: TextOverflow.ellipsis),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

I suggest you try GridView.builder or another GridView. You can look at the documentation here

or this third package this will be good for to try flutter_staggered_grid_view. The flutter_staggered_grid_view is more flexible to create GridView with various size.

Upvotes: 1

Related Questions