What are BoxConstraints in Flutter

In the previous section we have discussed what constraints are. In Flutter, every widget is rendered by their underlying RenderBox objects. As a result, for each boxes constraints are BoxConstraints.

For a Flutter beginner we need to say one thing at the very beginning. The constraints actually represent sizes of the rendered boxes, which are nothing but widgets.

In that light of the previous discussion, we must try to understand what BoxConstraints are.

We’ve already seen that widgets pass their constraints, which consist of minimum and maximum width and height, to their children. Moreover, each child may vary in size.

As a result we can say that render tree actually passes a concrete geometry, which is size.

Subsequently the widget tree grows in sizes and for each boxes the constraints are BoxConstraints. And, it consists of four numbers – a minimum width minWidth, a maximum width maxWidth, a minimum height minHeight, and a maximum height maxHeight. Therefore we can set a range of width and height.

As we’ve said before, the geometry of boxes consists of a Size. Consequently, the Size satisfies the constraints.

Each child in the rendered widget tree, gets BoxConstraints from its parent. After that, the child picks us the size that satisfies the BoxConstraints adjusting with the parent’s size.

Certainly, with the size, position changes. A child does not know its position.

Why?

Because, if the parent adds some padding the child’s position changes with it.

We’ll see that in a minute.

Consider a Flutter app where Scaffold widget acts as the immediate child of Material App widget.

As a result, the Scaffold takes the entire screen from its immediate parent Material App.

Next, the Scaffold passes its constraints to its immediate child Center widget. And then the Center takes the constraints or size from Scaffold. However, as the Scaffold widget allocates some space for the App Bar widget, therefore, Center doesn’t get the whole screen.

Let us see the code.

import 'package:flutter/material.dart';

class BoxConstraintsSample extends StatelessWidget {
  const BoxConstraintsSample({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'BoxConstraints Sample',
      debugShowCheckedModeBanner: false,
      home: BoxConstraintsSampleHomme(),
    );
  }
}

class BoxConstraintsSampleHomme extends StatelessWidget {
  const BoxConstraintsSampleHomme({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('BoxConstraints Sample'),
      ),
      body: Center(
        child: Container(
          color: Colors.redAccent,
          padding: const EdgeInsets.all(
            20,
          ),
          child: const Text(
            'Box',
            style: TextStyle(
              fontFamily: 'Allison',
              color: Colors.black38,
              fontSize: 60,
              fontWeight: FontWeight.bold,
            ),
          ),
          constraints: const BoxConstraints(
            minHeight: 70,
            minWidth: 70,
            maxHeight: 200,
            maxWidth: 200,
          ),
        ),
      ),//Center
    );
  }
}

If we run the code, we see the following screenshot.

BoxConstraints flutter example one
BoxConstraints flutter example one

The above code tells us about the Container’s constraints that point to BoxConstraints, this way.

constraints: const BoxConstraints(
            minHeight: 70,
            minWidth: 70,
            maxHeight: 200,
            maxWidth: 200,
          ),

The Container widget has a constraints parameter that points to the BoxConstraints widget, which simply defines the minimum and maximum width, height. And the range is between 70px to 200px.

As a result, if we try to make the Text widget bigger, that will not display the whole text, in that case.

Why?

Because, Container passes its constraints to its child Text widget and it gets that exact value. That means, the size of Text widget must remain in between 70px to 200px.

What happens if we try to pass the same constraints to another Container, which will act as the immediate child.

Let’s change our code.

How do you use box constraints in Flutter?

To use box constraints in Flutter, we must understand how BoxConstraints widget acts, maintaining the range of width and height.

Let’s change our above code and it will look like the following, now.

import 'package:flutter/material.dart';

class BoxConstraintsSample extends StatelessWidget {
  const BoxConstraintsSample({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'BoxConstraints Sample',
      debugShowCheckedModeBanner: false,
      home: BoxConstraintsSampleHomme(),
    );
  }
}

class BoxConstraintsSampleHomme extends StatelessWidget {
  const BoxConstraintsSampleHomme({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('BoxConstraints Sample'),
      ),
      body: Center(
        child: Container(
          color: Colors.redAccent,
          padding: const EdgeInsets.all(
            20,
          ),
          constraints: const BoxConstraints(
            minHeight: 170,
            minWidth: 170,
            maxHeight: 400,
            maxWidth: 400,
          ),
          child: Container(
            color: Colors.blueAccent[200],
            padding: const EdgeInsets.all(
              20,
            ),
            child: const Text(
              'Box',
              style: TextStyle(
                fontFamily: 'Allison',
                color: Colors.white,
                fontSize: 60,
                fontWeight: FontWeight.bold,
              ),
            ),
            constraints: const BoxConstraints.expand(
              height: 100,
              width: 100,
            ),
          ),
        ), //container
      ), //Center
    );
  }
}

In the above code, we find two Container widgets. Both have constraints defined. The first Container have constraints like the following:

constraints: const BoxConstraints(
            minHeight: 170,
            minWidth: 170,
            maxHeight: 400,
            maxWidth: 400,
          ),

And its child, the second Container has constraints like the following:

constraints: const BoxConstraints.expand(
              height: 100,
              width: 100,
            ),

The first Container’s constraints define a range of width and height. However, the second Container’s constraints point to BoxConstraints constructor BoxConstraints.expand.

What does this mean, as long as the size of the child Container is concerned?

We can explain it this way.

Since the child Container receives its constraints from its parent Container. Within that range it can expand its width and height up to 100px. Not more than that.

Moreover, this expansion process starts from the Center.

BoxConstraints flutter example two
BoxConstraints flutter example two

Understanding how these widgets or boxes handle the constraints in flutter is very important for the beginners.

In general, there are three kind of boxes that we’ll encounter while we learn Flutter.

Firstly, the widgets like Center and ListView; they always try to be as big as possible.

Secondly, the widgets like Transform and Opacity always try to take the same size as their children.

And, finally, there are widgets like Image and Text that try to fit to a particular size.

As we’ll progress, we’ll find, how these constraints vary from widget to widget.

As example, we can remember the role of Center widget. It always maintains the maximum size. The minimum constraint does not work here.

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

GitHub repository

Technical blog

Twitter

Comments

Leave a Reply