Muneeb Ahmad
Muneeb Ahmad

Reputation: 109

Column is taking more space than required in Flutter

I am trying to build a page view which is in a column. The page view will hold cards. i want the size of the page view to be dynamic to it's content i.e the card, but i am unable to achieve that. Apparently the column in the card is taking up more space than required. I have checked it with flutter inspector and i can't understand why. Any help would be appreciated. Here is the code.

import 'package:cricket_app/util/colors.dart';
import 'package:flutter/material.dart';
import 'package:page_view_indicators/circle_page_indicator.dart';

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  PageController _controller = PageController(
    initialPage: 0,
  );
  final _currentPageNotifier = ValueNotifier<int>(0);
  final double _cardHeight = 200.0;
  final double _teamIconSize = 50.0;

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: primaryColor,
        elevation: 0,
        // flexibleSpace: Container(
        //   decoration: BoxDecoration(
        //       gradient: LinearGradient(
        //           begin: Alignment.topLeft,
        //           end: Alignment.bottomRight,
        //           colors: <Color>[Colors.red, Colors.blue])),
        // ),
        centerTitle: true,
        title: Text(
          "CRICKET APP",
        ),
      ),
      body: Column(
        children: <Widget>[
          Flexible(
            child: Column(
              children: <Widget>[
                Flexible(
                  child: PageView(
                    controller: _controller,
                    children: <Widget>[
                      _buildMatchCard(context, _teamIconSize),
                      _buildMatchCard(context, _teamIconSize),
                      _buildMatchCard(context, _teamIconSize),
                    ],
                    onPageChanged: (int index) {
                      _currentPageNotifier.value = index;
                    },
                  ),
                ),
                CirclePageIndicator(
                  dotColor: primaryColor,
                  selectedDotColor: accentColor,
                  itemCount: 3,
                  selectedSize: 10.0,
                  currentPageNotifier: _currentPageNotifier,
                )
              ],
            ),
          ),
          Expanded(
            child: Container(
              child: Center(
                  child: Text(
                "News Section",
                style: TextStyle(fontSize: 20.0),
              )),
            ),
          )
        ],
      ),
    );
  }

  Widget _buildMatchCard(BuildContext context, double _teamIconSize) {
    return Card(
      margin: EdgeInsets.all(10.0),
      elevation: 2.0,
      color: darkGreyColor,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(10.0),
      ),
      child: Container(
        child: Column(
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.fromLTRB(5.0, 10.0, 5.0, 0),
              child: Text(
                "European Cricket Series, Stockholm, 11th Match",
                style: TextStyle(
                    fontSize: 18.0,
                    color: Colors.black,
                    fontWeight: FontWeight.w500),
                textAlign: TextAlign.center,
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(5.0),
              child: Text(
                "04:00 PM 22-Oct at Rajiv Ghandhi Stadium, Hyderabad",
                style: TextStyle(fontSize: 14.0),
                textAlign: TextAlign.center,
              ),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Container(
                          child: Image.asset(
                            'assets/icons/appIcon.jpg',
                            height: _teamIconSize,
                            width: _teamIconSize,
                          ),
                        ),
                        SizedBox(
                          height: 10.0,
                        ),
                        Text(
                          "WI",
                          style: TextStyle(
                              color: Colors.black,
                              fontSize: 18.0,
                              fontWeight: FontWeight.w500),
                        )
                      ],
                    ),
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Expanded(
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            Text(
                              "250/8",
                              style: TextStyle(
                                  fontSize: 24.0, color: Colors.black),
                            ),
                            Text("50 Over")
                          ],
                        ),
                      ),
                    )
                  ],
                ),
                Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text(
                      "Live",
                      style: TextStyle(
                          fontSize: 16.0,
                          color: Colors.red,
                          fontWeight: FontWeight.w500),
                    ),
                    Container(
                      width: 20.0,
                      height: 20.0,
                      margin: EdgeInsets.only(top: 5.0, bottom: 5.0),
                      decoration: new BoxDecoration(
                        color: accentColor,
                        shape: BoxShape.circle,
                      ),
                      child: Center(
                          child: Text(
                        "VS",
                        style: TextStyle(
                            fontSize: 12.0, fontWeight: FontWeight.w500),
                      )),
                    ),
                    Row(
                      children: <Widget>[
                        Container(
                          padding: EdgeInsets.fromLTRB(10.0, 3.0, 10.0, 3.0),
                          color: Colors.red,
                          child: Text("56"),
                        ),
                        SizedBox(
                          width: 5.0,
                        ),
                        Container(
                          padding: EdgeInsets.fromLTRB(10.0, 3.0, 10.0, 3.0),
                          color: Colors.red,
                          child: Text("56"),
                        )
                      ],
                    ),
                    Container(
                      margin: EdgeInsets.all(5.0),
                      child: Text("Fav - IND"),
                    )
                  ],
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Expanded(
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            Text(
                              "250/8",
                              style: TextStyle(
                                  fontSize: 24.0, color: Colors.black),
                            ),
                            Text("50 Over")
                          ],
                        ),
                      ),
                    ),
                    Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Image.asset(
                          'assets/icons/appIcon.jpg',
                          height: _teamIconSize,
                          width: _teamIconSize,
                        ),
                        SizedBox(
                          height: 10.0,
                        ),
                        Text(
                          "WI",
                          style: TextStyle(
                              color: Colors.black,
                              fontSize: 18.0,
                              fontWeight: FontWeight.w500),
                        )
                      ],
                    ),
                  ],
                ),
              ],
            ),
            Padding(
              padding: const EdgeInsets.all(4.0),
              child: Text(
                "INDIA needs 126 runs in 155 balls to win",
                style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w500),
                textAlign: TextAlign.center,
              ),
            )
          ],
        ),
      ),
    );
  }
}

Upvotes: 4

Views: 4079

Answers (2)

ANUP SAJJAN
ANUP SAJJAN

Reputation: 1968

The problem here is PageView. PageView will try to get all height as much as possible. So you can't use it without specifying a predefined height. Either you can determine the height of your card well before building pageView or give a hardcoded height, which can be bad considering the responsive nature of the app.

If you use pageview without mentioning any constraint to its height, it will try to grab the whole screen height if possible. So here is a workaround to your problem. You can modify it as per your requirements.

Solution

Wrap your pageview inside IndexedStack and container widget and give a height, which determines the size of your Pageview.

IndexedStack(
            children: [
              Container(
                height: 280,
                child: PageView( . . . ) ) ] )

So its not the problem of your buildCard method, its pageview which is taking height irrespective of the size of your card.

import 'package:cricket_app/util/colors.dart';
import 'package:flutter/material.dart';
import 'package:page_view_indicators/circle_page_indicator.dart';

class App extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<App> {
  PageController _controller = PageController(
    initialPage: 0,
  );
  final _currentPageNotifier = ValueNotifier<int>(0);
  final double _cardHeight = 200.0;
  final double _teamIconSize = 50.0;

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white70,
        elevation: 0,
        // flexibleSpace: Container(
        //   decoration: BoxDecoration(
        //       gradient: LinearGradient(
        //           begin: Alignment.topLeft,
        //           end: Alignment.bottomRight,
        //           colors: <Color>[Colors.red, Colors.blue])),
        // ),
        centerTitle: true,
        title: Text(
          "CRICKET APP",
        ),
      ),
      body: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          IndexedStack(
            children: [
              Container(
                height: 280,
                child: PageView(
                  controller: _controller,
                  children: <Widget>[
                    _buildMatchCard(context, _teamIconSize),
                    _buildMatchCard(context, _teamIconSize),
                    _buildMatchCard(context, _teamIconSize),
                  ],
                  onPageChanged: (int index) {
                    _currentPageNotifier.value = index;
                  },
                ),
              )
            ],
          ),
          Expanded(
            child: Container(
              child: Center(
                  child: Text(
                "News Section",
                style: TextStyle(fontSize: 20.0),
              )),
            ),
          )
        ],
      ),
    );
  }

  Widget _buildMatchCard(BuildContext context, double _teamIconSize) {
    return Card(
      margin: EdgeInsets.all(10.0),
      elevation: 2.0,
      color: Colors.cyan,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(10.0),
      ),
//        child: Text("das"),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.fromLTRB(5.0, 10.0, 5.0, 0),
            child: Text(
              "European Cricket Series, Stockholm, 11th Match",
              style: TextStyle(
                  fontSize: 18.0,
                  color: Colors.black,
                  fontWeight: FontWeight.w500),
              textAlign: TextAlign.center,
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(5.0),
            child: Text(
              "04:00 PM 22-Oct at Rajiv Ghandhi Stadium, Hyderabad",
              style: TextStyle(fontSize: 14.0),
              textAlign: TextAlign.center,
            ),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Container(
                        child: Image.asset(
                          'assets/images/img my hello bye.png',
                          height: _teamIconSize,
                          width: _teamIconSize,
                        ),
                      ),
                      SizedBox(
                        height: 10.0,
                      ),
                      Text(
                        "WI",
                        style: TextStyle(
                            color: Colors.black,
                            fontSize: 18.0,
                            fontWeight: FontWeight.w500),
                      )
                    ],
                  ),
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Text(
                          "250/8",
                          style: TextStyle(fontSize: 24.0, color: Colors.black),
                        ),
                        Text("50 Over")
                      ],
                    ),
                  )
                ],
              ),
              Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(
                    "Live",
                    style: TextStyle(
                        fontSize: 16.0,
                        color: Colors.red,
                        fontWeight: FontWeight.w500),
                  ),
                  Container(
                    width: 20.0,
                    height: 20.0,
                    margin: EdgeInsets.only(top: 5.0, bottom: 5.0),
                    decoration: new BoxDecoration(
                      color: Colors.red,
                      shape: BoxShape.circle,
                    ),
                    child: Center(
                        child: Text(
                      "VS",
                      style: TextStyle(
                          fontSize: 12.0, fontWeight: FontWeight.w500),
                    )),
                  ),
                  Row(
                    children: <Widget>[
                      Container(
                        padding: EdgeInsets.fromLTRB(10.0, 3.0, 10.0, 3.0),
                        color: Colors.red,
                        child: Text("56"),
                      ),
                      SizedBox(
                        width: 5.0,
                      ),
                      Container(
                        padding: EdgeInsets.fromLTRB(10.0, 3.0, 10.0, 3.0),
                        color: Colors.red,
                        child: Text("56"),
                      )
                    ],
                  ),
                  Container(
                    margin: EdgeInsets.all(5.0),
                    child: Text("Fav - IND"),
                  )
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Text(
                          "250/8",
                          style: TextStyle(fontSize: 24.0, color: Colors.black),
                        ),
                        Text("50 Over")
                      ],
                    ),
                  ),
                  Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      Image.asset(
                        'assets/images/img my hello bye.png',
                        height: _teamIconSize,
                        width: _teamIconSize,
                      ),
                      SizedBox(
                        height: 10.0,
                      ),
                      Text(
                        "WI",
                        style: TextStyle(
                            color: Colors.black,
                            fontSize: 18.0,
                            fontWeight: FontWeight.w500),
                      )
                    ],
                  ),
                ],
              ),
            ],
          ),
          Padding(
            padding: const EdgeInsets.all(4.0),
            child: Text(
              "INDIA needs 126 runs in 155 balls to win",
              style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w500),
              textAlign: TextAlign.center,
            ),
          )
        ],
      ),
    );
  }
}

I hope it helps!

Upvotes: 0

vinipx
vinipx

Reputation: 445

You should set appropriate mainAxisSize according to oficial docs

The height of the Column is determined by the mainAxisSize property. If the mainAxisSize property is MainAxisSize.max, then the height of the Column is the max height of the incoming constraints. If the mainAxisSize property is MainAxisSize.min, then the height of the Column is the sum of heights of the children (subject to the incoming constraints

...
child: Column(
          mainAxisSize: MainAxisSize.  //MIN or MAX
          children: <Widget>[
            Padding(
...

Upvotes: 11

Related Questions