UnconstrainedBox is your friend - Tip #5
Tags: flutter, flutterdev, dart, uiweekly
Published: 2021-04-10 17:02:56

[Disponível em Português [aqui](https://dev.to/pedromassango/unconstrainedbox-is-your-friend-tip-5-19cl)]

Hi there.
In this Flutter tip I want to talk a bit about the `UnconstrainedBox` widget, have you ever used it before? Let me know in the comments.

### What is it for?

In short, it is a widget that gives its child the freedom to size itself as needed. `UnconstrainedBox` (as the name suggests), impose no constraints on its child, the child will render as if it were in a infinite canvas. Sometimes it may overflow when used with some widgets like `PageView`, so you must be careful to give its child a proper size constraints as required. 

### Learn by Example

Let's say we need to build a `PageView` where their children have different sizes and it should show one item at time, how would you do that? (let me know in the comments)

Here is our initial code, it is just a `PageView` with three items: a red, green and blue container.

```dart
import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: UnconstrainedBoxSample()));

class UnconstrainedBoxSample extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(title: Text('Unconstrained Box')),
      body: PageView(
        children: [
          Container(color: Colors.red),
          Container(color: Colors.green),
          Container(color: Colors.blue),
        ],
      ),
    );
  }
}
```

Here is the output of the code above.

![GIF #1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yqhuquhvb9ezk9hv6urf.gif)

As you can see all three items are being expanded to fit the entire page, setting a custom size for our children doesn't work because `PageView` forces them to have the same size (in the non-scrolling direction) as itself.

We can work around this by changing the page's viewport but it would have a side effect: other items would be displayed as well and our children would still being forced to have the same height as the `PageView`.

Let's try that, add a controller with a custom view port fraction into your page view:
`controller: PageController(viewportFraction: .8)` and the result is as follow.

![GIF #2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7h1jvv03kl7m13q1bahd.gif)

This happens because `PageView`is imposing constraints for its children. The default (`viewportFraction: 1`) means that each child must have the exact same size as its parent (the `PageView`). Each time you decrease the `viewportFraction` you are just decreasing the size of its children.

## UnconstrainedBox in action!

To solve the issues mentioned above, we should wrap each child into a unconstrained box. 

Notice that even though we are using an unconstrained box, our item still have the constraints of: not being able to be bigger (in height/width depending on the scroll direction) than the PageView. The main advantage is to be able to have smaller (in size) children than the `PageView`.

**Remember:** since we are using a unconstrained box, our child must have size otherwise it will have its width and height set to zero (`0`).

Let's update our code, wrap your second item into a `UnconstrainedBox` and give the container a size, our code now looks like this:

```dart
import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: UnconstrainedBoxSample()));

class UnconstrainedBoxSample extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(title: Text('Unconstrained Box')),
      body: PageView(
        children: [
          Container(color: Colors.red),
          UnconstrainedBox(   // NEW
              child: Container(
                height: 400,  // NEW
                width: 250,   // NEW
                color: Colors.green,
              ),
          ),   // NEW
          Container(color: Colors.blue),
        ],
      ),
    );
  }
}
```

Here is the output:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d685esrwhxhe3slqxkim.gif)

Finally our second child now have the freedom to size itself as needed, as long as it does not oversize the PageView's size. This widget comes with some useful properties like `alignment` and `constrainedAxis`.

- `alignment`: allows you to align the child in its remaining space. Defaults to `Alignment.center`.

- `constrainedAxis`: you can specify an axis to constrain the child, in other words this allows to  define in which direction your widget should still be constrained. Defaults to `null` which means neither axis will be constrained.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wppriztr33up3kpzlt7m.gif)

This widget gives us freedom and the hability to build great animations and UI using in conjuction with `PageView` and other widgets.

That is it for today. Like share and subscribe for more Flutter tips. Comment if you have any question or issue.