Mike N
Mike N

Reputation: 508

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

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(),
  );
}

Upvotes: 18

Views: 9282

Answers (3)

Mike N
Mike N

Reputation: 508

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 SizedBox and define its width or height or both. The child of FittedBox is then scaled to match the parent SizedBox.

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

_buildWidgetA(width, height) {
    return SizedBox(
        width: width,
        height: height,
        child: FittedBox(
            child: A(),
        ),
    );
}

Upvotes: 26

Stefan Schaller
Stefan Schaller

Reputation: 123

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,
                      ),
                    )

Upvotes: 2

Try
Try

Reputation: 3469

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,
      ),
    ),
  ),
);

Upvotes: 1

Related Questions