Flutter Transform.scale 的子部件没有按比例缩放,为什么?

Flutter Transform.scale for child widgets not scaling proportionately, why?

我有一个基本的旗帜小部件,代码在这里:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        body: Flag(),
      ),
    );
  }
}

class Flag extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var scaleFactor = 1.0;

    final flag = Transform.scale(
      scale: scaleFactor,
      child: AspectRatio(
        aspectRatio: 5 / 3,
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(width: 2, color: Colors.black),
          ),
          child: Center(
            child: Container(
              height: 400,
              width: 150,
              color: Colors.purple,
            ),
          ),
        ),
      ),
    );

    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) => flag,
    );
  }
}

看起来像这样:

如果我将 scaleFactor 更改为 0.5,它会按预期缩放:

但是如果我将我的模拟器旋转到横向,比例就会关闭:

如果我使条纹与横向视图成比例(例如,将条纹宽度更改为 250),它在纵向模式下会变得太大:

无论设备大小如何,如何确保紫色条纹在 space 中占据相同的比例?

标志会变得更复杂,所以我不想使用 MediaQuery.of(context).size 来获取设备宽度并计算每个子部件的百分比。 .

我需要告诉我的小部件它的 "canonical" 大小吗?我需要将 scaleFactor 传递给每个子部件吗?

非常感谢任何想法:)

因此,我看到了两种解决方法,具体取决于您的最终目标。我想第一个可能是你真正想要的。

1) 为旗帜的每个部分使用一个 Row 和一个 Expanded 小部件,其中 flex 为 1。 AspectRatio 将保持纵横比固定,因此容器的比例应保持不变。由于默认的 flex 因子无论如何都是 1,因此您也可以将其忽略。如果需要白色部分透明,颜色为Colors.transparent即可。

class Flag extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var scaleFactor = 1.0;

    final flag = Transform.scale(
      scale: scaleFactor,
      child: AspectRatio(
        aspectRatio: 5 / 3,
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(width: 2, color: Colors.black),
          ),
          child: Row(
            children: <Widget>[
              Expanded(
                flex:1,
                child: Container(
                  color: Colors.white,
                ),
              ),
              Expanded(
                flex:1,
                child: Container(
                  color: Colors.purple,
                ),
              ),
              Expanded(
                flex:1,
                child: Container(
                  color: Colors.white,
                ),
              ),
            ],
          ),
        ),
      ),
    );

    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) => flag,
    );
  }
}

2) 您可以使用 Transform 小部件缩放中心的内容,但这会挤压您放入其中的所有内容,因此这可能不是您想要的。

class Flag extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var scaleFactor = 1.0;

    final flag = Transform.scale(
      scale: scaleFactor,
      child: AspectRatio(
        aspectRatio: 5 / 3,
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(width: 2, color: Colors.black),
          ),
          child: Center(
            child: Transform(
              transform: Matrix4.diagonal3Values(0.33, 1.0, 1.0),
              alignment: Alignment.bottomCenter,
              child: Container(
                color: Colors.purple,
              ),
            ),
          ),
        ),
      ),
    );

    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) => flag,
    );
  }
}