Flutter - Size of Transform.scale widget does not change when its child is scaled
Asked Answered
S

3

18

I have a widget A that I want to scale (pixel perfect). Depending on display width of the device, the size of A should be either increased or decreased. I tried the Transform.scale widget to change the size of the A. This works well but the size of the Transform.scale widget never changes. It always matches the original size of A (without scaling). Is there any way to force Transform.scale that it always adopts the size of its child? Or is there an alternative approach?

You can find an image here that shows the current and the required situation

EDIT: Widget A and its children should shrink/grow uniformly. The ratios between them should not change.

enter image description here

Here is the code I currently tried

_buildWidgetA(scalingFactor) {
  return Transform.scale(
    scale: scalingFactor,
    child: A(),
  );
}
Subtrahend answered 5/5, 2020 at 15:27 Comment(0)
S
24

Thanks to the input from @LOfG I learned that you cannot achieve the desired behavior with Transform.scale widget. Unfortunately, this widget does not change its size to match the dimensions of the scaled child but will always keep the width and height of the original, unscaled child.

I found another widget, FittedBox, with which I got the desired behavior. When using FittedBox, you do not define a scaling factor as you would do with Transform.scale. You rather put FittedBox inside a Container and define its width or height or both. The child of FittedBox is then scaled to match the parent Container.

https://api.flutter.dev/flutter/widgets/FittedBox-class.html

_buildWidgetA(width, height) {
    return Container(
        width: width,
        height: height,
        child: FittedBox(
            child: A(),
        ),
    );
}
Subtrahend answered 7/5, 2020 at 7:53 Comment(1)
I spend a hours on this. Fitted box is what I need :DJailer
T
2

If you really want to change the height from the child, you could do something like:


SizeTransition(
                      sizeFactor: const AlwaysStoppedAnimation<double>(0.8),
                      child: Transform.scale(
                        scale: 0.8,
                        alignment: Alignment.centerLeft,
                        child: yourWidget,
                      ),
                    )
Tribasic answered 13/12, 2023 at 10:54 Comment(0)
T
1

To scale a widget based on the width of the device you can use Media Query to change the scale:

First Approach:

@override
Widget build(BuildContext context) {
  double width = MediaQuery.of(context).size.width; //getting the current width

  return Scaffold(
    body: Transform.scale(
      scale: width <= 420 ? 0.5 : 0.8,
      child: Align(
        child: Container(
          alignment: Alignment.center,
          width: 420,
          height: 420,
          color: Colors.red,
          child: Text('Example', style: TextStyle(fontSize: 50),),
        ),
      ),
    )
  );
}

Second Approach:

Scaffold(
  body: Container(
    alignment: Alignment.center,
    width: width * 0.5,
    height: width * 0.5,
    color: Colors.green,
    child: Text(
      'Example Text',
      textAlign: TextAlign.center,
      style: TextStyle(
        fontSize: width * 0.1,
      ),
    ),
  ),
);
Transcendent answered 5/5, 2020 at 16:18 Comment(4)
Thx for your suggention. However, in this case the content of the container would not scale properly. For example, font-size of any text-widgets would stay the same. I need a way to shrink/grow the widget and all its children uniformly.Subtrahend
Thx for the update. This is the approach that I've already tried. The child widget (in your case the Container) is scaling properly but the Transform.scale widget does not change its size. Width and height always match the dimensions of the orginal, unscaled child. Any ideas to change that?Subtrahend
Now i understand what you want to achieve. In your case i think the second Approach is the best, i can't find a way to make the Transform.scale change it's size.Transcendent
Thx for the feedback. I was thinking about your second approach to manually scale the child widget. Unfortunately, I have tens of nested widgets that have to be rescaled as well which becomes very tedious and hard to maintain. But I found another widget that provides a similar behavior: FittedBox. I posted an answer with the details.Subtrahend

© 2022 - 2024 — McMap. All rights reserved.