Rémi Rousselet
Rémi Rousselet

Reputation: 277007

Position widget in stack with percent

Let's say I want to position a widget inside a Stack but with a percent of the Stack position instead of a fixed size. How to do that in flutter ?

I'd expect that the Positionned.fromRelativeRect constructor would be the thing, using floats between 0 and 1. But seems like no.

Align allows to position the widget in percent. But heightFactor and widthFactor changes the Align size instead of the child size. Which is not what I want.

Upvotes: 20

Views: 11826

Answers (4)

use FractionalOffset & FractionallySizedBox it's very simple in contrast

  • around no unnecessary code like Positioned.fill
  • no no extra calculations like Alignment
...
 Container(
   color: Colors.blue[200],
   alignment: FractionalOffset(0.7, 0.6),
   child: FractionallySizedBox(
     widthFactor: 0.1,
     heightFactor: 1/3,
     child: Container(color: Colors.red[900])
   ),
 ),
...

enter image description here

Upvotes: 18

If you want to use LayoutBuilder then do without Positioned.fill, like this: you need one LayoutBuilder, no need to turn around every elements and use Transform.translate instead of Padding.

  new LayoutBuilder(
    builder: (context, constraints) {
      return Stack(
        children: <Widget>[
          Transform.translate(
            offset: Offset(
              constraints.biggest.width * left,
              constraints.biggest.height * top),         
            child: new Text("toto", textAlign: TextAlign.center,),
          ),
          ...
        ],
      );
    }
  )

Upvotes: 1

Bar Tzadok
Bar Tzadok

Reputation: 516

one thing that i figured out not long ago is that you can position a widget on the screen using a container its alignment parameter with the help of the Alignment.lerp(x,y,z) function

//the widget will be placed in the center of the container
alignment: Alignment.lerp(Alignment.topCenter, Alignment.bottomCenter, 0), 

//the widget will be placed in the bottom of the container
alignment: Alignment.lerp(Alignment.topCenter, Alignment.bottomCenter, 1), 

//the widget will be placed in the bottom quarter of the container
alignment: Alignment.lerp(Alignment.topCenter, Alignment.bottomCenter, 0.5), 

//the widget will be placed in the top quarter of the container
alignment: Alignment.lerp(Alignment.topCenter, Alignment.bottomCenter, -0.5), 

Upvotes: 13

R&#233;mi Rousselet
R&#233;mi Rousselet

Reputation: 277007

You can combine a Positioned.fill and LayoutBuilder to achieve such result.

    new Stack(
    children: <Widget>[
      new Positioned.fill(
        child: new LayoutBuilder(
          builder: (context, constraints) {
            return new Padding(
              padding: new EdgeInsets.only(top: constraints.biggest.height * .59, bottom: constraints.biggest.height * .31),
              child: new Text("toto", textAlign: TextAlign.center,),
            );
          },
        ),
      )
    ],
  ),

Upvotes: 20

Related Questions