Site icon Flutter Packages | Pub dev Packages – Flutter Mobile App World

align positioned in Flutter App

Flutter Package: When your desired layout or animation is too complex for Columns and Rows, this widget lets you position/size/rotate/transform its child in complex ways.

align_positioned

Widgets in this package:

Why are these widgets an indispensable tool?

When your desired layout feels too complex for Columns and Rows, AlignPositioned is a real life saver. Flutter is very composable, which is good, but sometimes it’s unnecessarily complex to translate some layout requirement into a composition of simpler widgets.

The AlignPositioned aligns, positions, sizes, rotates and transforms its child in relation to both the container and the child itself. In other words, it lets you easily and directly define where and how a widget should appear in relation to another.

For example, you can tell it to position the top-left of its child at 15 pixels to the left of the top-left corner of the container, plus move it two thirds of the child’s height to the bottom plus 10 pixels, and then rotate 15 degrees. Do you even know how to start doing this by composing basic Flutter widgets? Maybe, but with AlignPositioned it’s much easier, and it takes a single widget.

Besides layout, AlignPositioned is specially helpful for explicit animations (those that use a controller), since you can just calculate the final position, size and rotation you want for each frame. Without it you may find yourself having to animate a composition of widgets.

Meanwhile, AnimatedAlignPositioned and AnimChain widgets are helpful for implicit animations, which are very easy to create. If you change their parameters they animate automatically, interpolating between the old and new parameter values.

How it works

Add align_positioned as a dependency in your pubspec.yaml file, then import it:

import 'package:align_positioned/align_positioned.dart';

Pass a child to the AlignPositioned or the AnimatedAlignPositioned, and then one or more of the following parameters:

AlignPositioned(
   child: child,
   alignment: ...,
   dx: ...,
   dy: ...,
   moveByChildWidth: ...,
   moveByChildHeight: ...,
   moveByContainerWidth: ...,
   moveByContainerHeight: ...,
   childWidth: ...,
   childHeight: ...,
   minChildWidth: ...,
   minChildHeight: ...,
   maxChildWidth: ...,
   maxChildHeight: ...,
   childWidthRatio: ...,
   childHeightRatio: ...,
   minChildWidthRatio: ...,
   minChildHeightRatio: ...,
   maxChildWidthRatio: ...,
   maxChildHeightRatio: ...,
   rotateDegrees: ...,
   matrix4Transform: ...,
   wins: ...,
   touch: ...,
   );

Let’s study each parameter in detail:

Align and Position parameters

The alignment parameter works as expected. For example, Alignment.bottomRight represents the bottom right of the container, and Alignment(0.0, 0.0) represents the center of the container. The distance from -1.0 to +1.0 is the distance from one side of the rectangle to the other side of the rectangle.

If touch is Touch.inside, then alignment works just like the alignment for the Align widget, aligning the child inside of the container.

However, if touch is Touch.outside, then the alignment happens outside of the container.

As another example, if touch is Touch.inside, then Alignment(1.0, 0.0) makes the child’s right side touch the right side of the container (it touches the container from the inside).

But if touch is Touch.outside, then Alignment(1.0, 0.0) makes the child’s left side touch the right side of the container (it touches the container from the outside).

Parameters dx and dy can be positive or negative, and move the child horizontally and vertically, in pixels.

Parameters moveByChildWidth and moveByChildHeight can be positive or negative, and move the child horizontally and vertically, but the unit here is not pixels, but child widths and heights.

Parameters moveByContainerWidth and moveByContainerHeight can be positive or negative, and move the child horizontally and vertically, but the unit here is not pixels, but container widths and heights.

Align and Position Examples

The below image shows the center of the child positioned 15 pixels to the right of the top-left corner of the container:

AlignPositioned(
   child: child,
   alignment: Alignment.topLeft,
   touch: Touch.inside,
   dx: 15.0, // Move 4 pixels to the right.
   moveByChildWidth: -0.5, // Move half child width to the left.
   moveByChildHeight: -0.5); // Move half child height to the top.

Then, to move the child one container width to the right, and one container height to the bottom:

AlignPositioned(
   child: child,
   alignment: Alignment.topLeft,
   touch: Touch.inside,
   dx: 15.0, // Move 4 pixels to the right.
   moveByChildWidth: -0.5, // Move half child width to the left.
   moveByChildHeight: -0.5, // Move half child height to the top.
   moveByContainerWidth: 1.0, // Move one container width to the right.
   moveByContainerHeight: 1.0); // Move one container height to the bottom.

Please, check the example tab for the effects seen below:

Size Parameters

Optionally, you can also define the child-size:

Rotate and Transform

Optionally, you can also define rotation and transformation:

One widget relative to another

Use the AlignPositioned.relative() factory if you have a main widget, and you want to position/size/rotate/translate another widget relative to the main one, but the second is not a child of the first.

Example, to center the main widget, and then put the relative widget below it:

Center(
   child: AlignPositioned.relative(
       widgetA(),
       widgetB(),
       moveByContainerHeight: 0.5,
       moveByChildHeight: 0.5));

Using AlignPositioned inside of a Stack

A Stack positions its children relative to the edges of its box. The Stack documentation contains this text:

In particular, when using a Stack you can’t position children relative to their size or the stack’s own size.

However, by using AlignPositioned you can do precisely that: position (and size, rotate and transform) children relative to their size or the Stack’s own size, and consequently in relation to the other widgets inside of the Stack.

If you recall how a Stack works, each of its child widgets is either positioned or non-positioned. The stack sizes itself to contain all the non-positioned children, which are positioned according to the stacks’s alignment parameter. Next, the positioned children are laid out.

If you use the AlignPositioned default constructor and put it inside of a Stack it will be a non-positioned child.

To create a positioned widget, use the AlignPositioned.expand() factory. The AlignPositioned will then expand and fix itself to the corners of the Stack. In other words, the Stack will size itself to their other non-positioned widgets, and then you can use the AlignPositioned to layout its child in relation to the Stack.

Example:

Stack(
  children: [
    Container(...),
    Positioner(child: Container(...)),
    AlignPositioned(...),
    AlignPositioned.expand(...),
    ...
    ]);

Implicit Animation

If you change the AnimatedAlignPositioned parameters it will animate automatically:

return AnimatedAlignPositioned(
    duration: Duration(seconds: 3)
    alignment: Alignment.bottomCenter,
    rotateDegrees: isOk ? 0 : 180,
    child: AnimatedContainer(
        color: isOk ? Colors.yellow : Colors.red,
        duration: Duration(seconds: 2)
        ),
    );

Chained Implicit Animation

Or you can chain widgets together so that even the change of parameters is automatic:

return AnimChain(repeat: true)
   // Show the yellow box and wait 5 seconds.
   .next(
      wait: Duration(seconds: 5),
      widget: AnimatedAlignPositioned(
         alignment: Alignment.bottomCenter,
         rotateDegrees: 0,
         child: Container(color: Colors.yellow),
         ),
      )
   // Rotate to the red box in 3 seconds.
   .next(
      wait: Duration(seconds: 3),
      widget: AnimatedAlignPositioned(
         duration: Duration(seconds: 3),
         rotateDegrees: 180,
         child: Container(color: Colors.red),
         ),
      )
   // Finally, translate the blue in the vertical axis.
   .next(
      widget: AnimatedAlignPositioned(
         duration: Duration(seconds: 15),
         alignment: Alignment.bottomCenter,
         dy: 150,
         rotateDegrees: 180,
         child: Container(color: Colors.blue),
         ),
      ),
    );

Download Flutter Package: align positioned in Flutter App source code on GitHub

https://github.com/marcglasberg/align_positioned

Exit mobile version