Flutter: Is there a good tutorial on Offset?

I want to learn more about offset, I googled and found very few tutorials.
I found this tutorial https://blog.logrocket.com/understanding-offsets-flutter/ but is a bit complex.
I learned somewhere that it was expressed from the center of the screen Offset(0,0) (with Offset(dx,dy) and for instance:

  • Offset(1,0) was the center right
  • Offset(-1,0) was the center left
  • Offset(0,1) was the bottom center
  • Offset(0,-1) was the top center
    but I have other examples with Offset(30,20) …
    I am lost, in which unit is it expressed?
    Does in depend on the type of widget?
    Is there a simple tutorial out there?
    Thank you!

  • “in which unit is it expressed?” – Offset’s dx and dy are expressed as “logical” pixels, the same values you use in Container’s width and height properties

    – 




Offset, Alignment, Rect, and Size are all very important to understand. I spend a bit of time reviewing their protocols from time to time, and it pays off when I must deal with Positioned widgets inside a Stack, or painting on the canvas with CustomPainter.

It scares me to see all these painting apps that deal with x and y as pairs of variables, instead of using the self-paired offsets and math on those. Especially cool is Offset.fromDirection which does a polar-to-rect calculation, meaning you don’t have to remember your trig very much to lay out that clock-face.

What an Offset does depends entirely on the Widget it’s used in. See this full example:

import 'package:flutter/material.dart';

void main() => runApp(const MaterialApp(
      home: OffSetTest(),
    ));

class OffSetTest extends StatelessWidget {
  const OffSetTest({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Stack(
          alignment: Alignment.center,
          children: [
            OffSetBox(dx: 0, dy: 0, color: Colors.red),
            OffSetBox(dx: 1, dy: 1, color: Colors.green),
            OffSetBox(dx: 2, dy: 2, color: Colors.blue),
            OffSetBox(dx: 3, dy: 3, color: Colors.yellow),
            OffSetBox(dx: 4, dy: 4, color: Colors.purple),
          ],
        ),
      ),
    );
  }
}

class OffSetBox extends StatelessWidget {
  final double dx;
  final double dy;
  final Color color;

  const OffSetBox(
      {super.key, required this.dx, required this.dy, required this.color});

  @override
  Widget build(BuildContext context) {
    return Transform.translate(
      offset: Offset(dx, dy),
      child: Container(
        width: 100,
        height: 100,
        color: color,
        child: Text('$dx, $dy'),
      ),
    );
  }
}

Here we use it in an Transform.translate and there the values used in the Offset equal the number of pixels it will be shifted, so you get this output:

enter image description here

If we replace it with an FractionalTranslation instead like this:

class OffSetBox extends StatelessWidget {
  final double dx;
  final double dy;
  final Color color;

  const OffSetBox(
      {super.key, required this.dx, required this.dy, required this.color});

  @override
  Widget build(BuildContext context) {
    return FractionalTranslation(
      translation: Offset(dx, dy),
      child: Container(
        width: 100,
        height: 100,
        color: color,
        child: Text('$dx, $dy'),
      ),
    );
  }
}

we get this instead while using the same offsets:

enter image description here

Here it shifts according to its own size.

And there’s also FractionalOffsets for example. For example:

class OffSetBox extends StatelessWidget {
  final double dx;
  final double dy;
  final Color color;

  const OffSetBox(
      {super.key, required this.dx, required this.dy, required this.color});

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: FractionalOffset(dx, dy),
      child: Container(
        width: 500,
        height: 500,
        color: color,
        child: Text('$dx, $dy'),
      ),
    );
  }
}

enter image description here
or
enter image description here

Here 0,0 corresponds to the topleft of the parent. 1,1 to bottomleft. And 2,2 will then mean the position so 1,1 is exactly in between etc. So behavior also depends on the the window size.

There’s many more possibilities where in each it could mean something else

Leave a Comment