FractionallySizedBox to align items proportionally and with percentages without MediaQueries in Flutter
- Andrés Cruz
We are going to know a very special widget that will get us out of trouble in many cases, surely it happened to you that you want to place an element that occupies 40%, 60%, 10% etc; and you don't know how to do it, you could use MediaQueries but these must be used for something much more specific and also, we will show you an easier way to do it.
The FractionallySizedBox Widget allows us to instruct to create a container that occupies only a fraction (as set between a value between 0 and 1) of the space of the total container; this description may sound somewhat confusing so let's see it in practice; We are going to specify a single screen, that is, we will have all the available space through a simple Scaffold:
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'FractionallySizedBox',
home: Scaffold(
appBar: AppBar(
title: Text("FractionallySizedBox"),
),
body: Center(),
)
);
}
}
We simply have the basic structure, an AppBar, with a text and in its body a completely empty Center.
Defining half width in percentages
Now, that we have all the available space of that Scaffold, we are going to place our FractionallySizedBox as a container element so that it occupies a fraction of the container according to the value that we specify; For example, we want it to occupy half the width:
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'FractionallySizedBox',
home: Scaffold(
appBar: AppBar(
title: Text("FractionallySizedBox"),
),
body: FractionallySizedBox(
//alignment: Alignment.center,
widthFactor: 0.5,
//heightFactor: 0.5,
child: Container(
child: RaisedButton(
child: Text("Hola"),
onPressed: NULL,
),
))),
);
}
As you can see in the example above, we put a factor of 0.5 for what the width would be and this translates in practice to an element taking up half the width of the entire screen, as remember that our FractionallySizedBox has available all the space of its parent container since it is found as the root element of the Scaffold.
Defining half height in percentages
Now we are going to define the factor for the height or what is the same, the height of our container of fractional type:
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'FractionallySizedBox',
home: Scaffold(
appBar: AppBar(
title: Text("FractionallySizedBox"),
),
body: FractionallySizedBox(
//alignment: Alignment.center,
//widthFactor: 0.5,
heightFactor: 0.5,
child: Container(
child: RaisedButton(
child: Text("Hola"),
onPressed: NULL,
),
))),
);
}
It is exactly the same code, only we vary the factor from width/width to height/height and for this reason now it occupies half the height, as you can suppose the factor goes from zero, to totally invisible up to 1, which means a value occupies all the space, everything in between (double value between 0 and 1 not including these) means that we occupy a fraction of the container in proportion equal to the value you specify.
Align a widget in the middle of the screen
We can also align the element that is contained within our FractionallySizedBox, which in this case would be our RaisedButton; for that we use the Alignment, but in these examples, such as our FractionallySizedBox, it makes our button occupy the entire width, but if we use another type of container that is not a Container, for example, a Center:
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'FractionallySizedBox',
home: Scaffold(
appBar: AppBar(
title: Text("FractionallySizedBox"),
),
body: Center(
child: FractionallySizedBox(
alignment: Alignment.center,
//widthFactor: 0.5,
heightFactor: 0.5,
child: Container(
child: RaisedButton(
child: Text("Hola"),
onPressed: NULL,
),
)),
)),
);
}
Using the FractionallySizedBox with columns and/or rows
Using the FractionallySizedBox with columns and/or rows
Column(
children: <Widget>[
Flexible(
child: FractionallySizedBox(
//alignment: Alignment.center,
//widthFactor: 0.5,
heightFactor: 0.5,
child: Center(
child: RaisedButton(
child: Text("Hola"),
onPressed: NULL,
),
)),
),
],
))
Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter