How to add borders to a widget in Flutter

Share this post

Adding a border to a widget is very easy in Flutter. We just need to wrap the widget in a Container and add BoxDecoration to it.

Let’s say we want to make a square with blue borders all we need to do is:

Container(
  height: 100,
  width: 100,
  decoration: BoxDecoration(
    border: Border.all(
      color: Colors.blue,
    ),
    borderRadius: BorderRadius.circular(10.0),
  ),
  child: Center(
    child: Text('mrflutter.com'),
  ),
),

Which will look like this:

Border.all constructor

What if the border is too “pointy” and we want a nice border-radius? No problem, we just add borderRadius to our BoxDecoration constructor:

decoration: BoxDecoration(
  border: Border.all(
    color: Colors.blue,
  ),
  borderRadius: BorderRadius.circular(10.0),
),

We then get the following:

BorderRadius.circular constructor

You can also choose on what sides of the container you want a border using the BorderSide constructor.

decoration: BoxDecoration(
  border: Border(
    top: BorderSide(
      color: Colors.blue,
      // width: 3.0 --> you can set a custom width too!
    ),
    bottom: BorderSide(
      color: Colors.blue,
    ),
  ),
),

Which looks like this:

BorderSide top and bottom

I hope this post helps you utilize the widgets that Flutter offers to create a custom border to your own widgets.

How to create rounded buttons in Flutter

Share this post

There are many ways to create and use rounded buttons in Flutter, but I’m going to show you some ways that work great in my opinion.

Rounded button using RoundedRectangleBorder

This method is very easy, we just need to use a RaisedButton and give it a shape with RoundedRectangleBorder.

Widget _withRoundedRectangleBorder() {
    return RaisedButton(
      child: Text("RaisedButton with RoundedRectangleBorder"),
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(20),
      ),
      onPressed: () {},
    );
  }

The button above already has all the characteristics of a Material button, thus not really customizable (except obvious things like color, etc.)

Rounded button using StadiumBorder

This method basically does the same thing to the button as a RoundedRectangleBorder with a circular radius of 20 but is much shorter. Obviously even less customizable than the above method.

Widget _withStadiumBorder() {
    return RaisedButton(
      shape: StadiumBorder(),
      onPressed: () {},
      child: Text("RaisedButton with StadiumBorder"),
    );
  }

Custom rounded button using InkWell

This method uses InkWell and is the most customizable one, but of course, is the most verbose and is only recommended for people who want things like double-tap support, custom splashColor and highlightColor, and many more customizable properties. You can read all about it in the link above and try it out yourself.

Widget _customButton() {
    return Material(
      child: InkWell(
        borderRadius: BorderRadius.circular(20),
        onTap: () {},
        splashColor: Colors.blue,
        highlightColor: Colors.blue,
        child: Container(
          height: 36,
          width: 240,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(20),
            border: Border.all(color: Colors.grey),
          ),
          child: Center(
            child: Text("Custom Button with InkWell"),
          ),
        ),
      ),
    );
  }

I hope this post makes it easy for you to use rounded buttons in Flutter.

Sizing widgets relative to parent/screen size in Flutter

Share this post

Oftentimes we don’t want our widgets to have a specific width or height, but rather have a width or height that is relative to the parent. For instance, we want a container to take 65% of the screen width or two containers that each taking respectively 70% and 30% of parent width. These are just 2 examples off the top of my head, but once you learn the basics, you can apply it to every case.

Sizing a widget relative to screen size

To be able to do this, we need to know the size of the device screen. No worries, Flutter has just the widget for that. To get the screen size just do the following:

MediaQuery.of(context).size // contains width and height

And use it anywhere in your app. Let’s say we want to have a container with width and height that are half as large as the screen. We would end up with the following code.

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("MediaQuery"),
      ),
      body: Container(
        width: MediaQuery.of(context).size.width * 0.5,
        height: MediaQuery.of(context).size.height * 0.5,
      ),
    );
  }

But what if we want to have a container that takes half of the available space (means half of the parent widget)? Enter FractionallySizedBox!

Sizing a widget relative to its parent

FractionallySizedBox is a widget (a container) that lets its child have a widthFactor and a heightFactor. You can see this as a kind of scale value. So if we want to have a container that takes half of the available space horizontally and vertically, we would do the following:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FractionallySizedBox"),
      ),
      body: FractionallySizedBox(
        widthFactor: 0.5,
        heightFactor: 0.5,
        child: Container(
          // this container won't be larger than
          // half of its parent size
        ),
      ),
    );
  }

What if we have a list of widgets that we want to place next to each other horizontally or vertically and we want them to take a certain percentage of the list. We can do just that using Expanded.

Sizing a list of widgets relative to each other

By using expanded and setting the flex property, we can give each widget in a Row or Column its own weight (I explained Row and Column in one of my earlier posts). That means how much of the available space of that widget it is allowed to fill. So we can have the following code for a horizontal alignment:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Expanded"),
      ),
      body: Container(
        child: Row(
          children: <Widget>[
            Expanded(
              flex: 6, // 60% of space => (6/(6 + 4))
              child: Container(
                color: Colors.red,
              ),
            ),
            Expanded(
              flex: 4, // 40% of space
              child: Container(
                color: Colors.purple,
              ),
            ),
          ],
        ),
      ),
    );
  }

By default, Expanded takes the whole available space, so if we want 2 widgets to take 50% of the space, we can remove the flex property altogether.

There are more ways to size widgets relative to a parent widget, I just described the most common ways. If you know more ways to do this, let me know in the comment section.