FractionallySizedBox para alinear elementos de manera proporcional y con porcentajes sin MediaQueries en Flutter

- Andrés Cruz

In english

Vamos a conocer un widgets muy especial que nos sacará de un apuro en muchos casos, seguramente te a pasado que quieres colocar un elemento que ocupe un 40%, 60% 10% etc; y no sabes como hacerlo, podrías emplear MediaQueries pero estos deben ser empleados para algo mucho más específico y además, te mostraremos una forma más fácil de hacerlo.

El Widget FractionallySizedBox nos permite indicar crear un contenedor que ocupe solo una fracción (según lo establecido entre un valor entre 0 y 1) del espacio del total del contenedor; puede que suene algo confuso esta descripción así que vamos a verlo en la práctica; vamos a especificar una sola pantalla, es decir, tendremos todo el espacio disponible mediante un sencillo 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(),
      )
    );
  }
}
Estructura básica proyecto Flutter

Simplemente tenemos la estructura básica, un AppBar, con un texto y en el cuerpo del mismo un Center completamente vacío.

Definiendo la mitad del ancho/width en porcentajes

Ahora, que tenemos todo el espacio disponible de ese Scaffold, vamos a colocar como elemento contenedor nuestro FractionallySizedBox para que ocupe una fracción del contenedor según el valor que le especifiquemos; por ejemplo queremos que ocupe la mitad del ancho:

  @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,
                ),
              ))),
    );
  }
FractionallySizedBox con la mitad del ancho o width

Como puedes ver en el ejemplo anterior, colocamos un factor de 0,5 para lo que sería el ancho y esto se traduce en la práctica como un elemento que ocupa la mitad del ancho de toda la pantalla, ya que recuerda que nuestro FractionallySizedBox tiene disponible todo el espacio de su contenedor padre ya que el mismo se encuentra como elemento raíz del Scaffold.

Definiendo la mitad del alto/height en porcentajes

Vamos a definir ahora el factor para el alto o lo que es lo mismo, el height de nuestro contenedor de tipo fraccional:

  @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,
                ),
              ))),
    );
  }
FractionallySizedBox con la mitad del largo o height

Es exactamente el mismo código, solo que variamos en el factor de ancho/width a alto/height y por tal motivo ahora ocupa la mitad de lo alto, como puedes suponer el factor va de cero, para totalmente invisible hasta 1 que significa un valor ocupa todo el espacio, todo lo que está en el medio (valor double entre 0 y 1 sin incluir estos) significa que ocupamos una fracción del contenedor en proporción igual al valor que especifiques.

Alinear en el medio de la pantalla un widget

También podemos alinear el elemento que esté contenido dentro de nuestro FractionallySizedBox que en este caso sería nuestro botón RaisedButton; para eso empleamos el Aligment, pero en estos ejemplos como nuestro FractionallySizedBox hace que nuestro botón ocupe todo lo ancho, pero si empleamos otro tipo de contenedor que no sea un Container por ejemplo, un 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,
                  ),
                )),
          )),
    );
  }
FractionallySizedBox con el center

Emplear el FractionallySizedBox con columnas y/o filas

Si quieres emplear un Column dentro de un Row o FractionallySizedBox debes de especificar un Flexible

Column(
            children: <Widget>[
              Flexible(
                child: FractionallySizedBox(
                    //alignment: Alignment.center,
                    //widthFactor: 0.5,
                    heightFactor: 0.5,
                    child: Center(
                      child: RaisedButton(
                        child: Text("Hola"),
                        onPressed: NULL,
                      ),
                    )),
              ),
            ],
          ))
FractionallySizedBox con las columnas y filas
Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy