美文网首页
Flutter - 布局:正方形

Flutter - 布局:正方形

作者: 开心人开发世界 | 来源:发表于2019-08-18 00:28 被阅读0次

    今天我们将使用Flutter创建以下布局。我们为什么要那样做?答案很简单:“练习变得完美”。

    但是我们怎么能这样做呢?真的有可能像这样在彼此之上和之下扭曲方块吗?


    我想到的第一种方法是使用九个方块,并相应地着色它们,如下所示:

    但是可以使用更少的方块吗?也许是这样的:

    上面的布局包含一个包装其他所有内容的列。在该列中,有两行。第一行有两个子项(红色和橙色),第二行有两列。第一列是绿色,第二列有两行,依此类推......

    据我所知,橙色块不可能使用一个小部件,除非......我们使用stack,并将橙色块排列在其他块之上。

    首先让我们创建上面的布局,之后,我们将看到如何使用橙色的stack。


    在第一个中Row,我们将创建两个“ Container”并将它们中的每一个包装在一个Expanded小部件中,将flex因子设置为2表示红色Container,1表示黄色表示。我也将他们的身高设定为100。

    使用“ 扩展”窗口小部件可以使“ 行”或“ 列”的子项展开以填充主轴中的可用空间(例如,水平方向为行,或垂直方向为)。如果扩展了多个子节点,则根据弹性因子将可用空间划分为多个子节点

    main_page.dart

      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Squares'),
          ),
          body: Column(
            children: <Widget>[
              Row(
                children: <Widget>[
                  Expanded(
                    flex: 2,
                    child: Container(
                      height: 100,
                      color: Colors.red,
                    ),
                  ),
                  Expanded(
                    flex: 1,
                    child: Container(
                      height: 100,
                      color: Colors.orange,
                    ),
                  ),
                ],
              ),
            ],
          ),
        );
      }
    

    现在让我们创建第二行。

    对于第二行,我们将使用另外两个Expanded小部件,第一个使用flex因子1,第二个使用flex因子将是2。

    在这一行中,我们将紫色和橙色块放在两个Expanded小部件中。但我们不会为它们指定弹性因子。因此,他们将平等占用可用空间:

    main_page.dart

    Row(
      children: <Widget>[
        Expanded(
          flex: 1,
          child: Container(
            height: 200,
            color: Colors.green,
          ),
        ),
        Expanded(
          flex: 2,
          child: Column(
            children: <Widget>[
              Row(children: <Widget>[
                Expanded(
                  child: Container(
                    height: 100,
                    color: Colors.purple,
                  ),
                ),
                Expanded(
                  child: Container(
                    height: 100,
                    color: Colors.orange,
                  ),
                ),
              ],),
              Container(
                height: 100,
                color: Colors.blue,
              ),
            ],
          ),
        )
      ],
    ),
    

    结果是:

    要在每个块上显示白色数字,只需将Text小部件作为每个Container的子级,例如我们将拥有的红色Container:

    main_page.dart

    Expanded(
      flex: 2,
      child: Container(
        height: 100,
        color: Colors.red,
        child: Center(
          child: Text(
            "1",
            style: TextStyle(fontSize: 50, color: Colors.white),
          ),
        ),
      ),
    ),
    

    请注意,我已将Text小部件包装在Center小部件中,以便文本显示在容器的中心:

    我们差不多完成了,除了“2”号,它是居中的,但它没有居中!橙色块由两个不同的容器组成,数字“2”在下部容器中居中!

    我们如何对齐此数字以使其居中?

    我正在关注由Flutter的创作者创建的youtube上的一个频道,名为“ 本周的颤动小部件 ”。如果你还没有我完全建议你关注它!在上一集中,他们介绍了“Align”小部件,这对我们来说非常有用。

    如下图所示,如果我们将对齐设置为(0,-1),对象将被放置在其容器内的顶部中心位置:

    我用它来对齐下面橙色块内的文本。

    我还尝试将对齐值设置为(0,-2.5)以将对象移动到其容器的上方(实际上是外部),并且它也起作用:

    Expanded(
      child: Container(
        alignment: Alignment(0, -2.5),
        height: 100,
        color: Colors.orange,
        child: Text(
          "2",
          style: TextStyle(fontSize: 50, color: Colors.white),
        ),
      ),
    ),
    

    结果:

    现在让我们使用“Stack”小部件从头开始创建所有内容。


    Stack的孩子从下往上定位。因此第一个应该在其他人之下的孩子是紫色的,第5个:

    stack_page.dart

    body: Stack(
      children: <Widget>[
        Container(
          color: Colors.purple,
          height: 300,
          child: Center(
            child: Text(
              "5",
              style: TextStyle(fontSize: 50, color: Colors.white),
            ),
          ),
        ),
      ],
    ),
    

    现在让我们添加堆栈的第二个子块,块号为1:
    stack_page.dart

    Container(
      color: Colors.red,
      height: 100,
      width: MediaQuery.of(context).size.width * 2 / 3,
      child: Center(
        child: Text(
          "1",
          style: TextStyle(fontSize: 50, color: Colors.white),
        ),
      ),
    ),
    

    请注意,我已使用MediaQuery该类获取屏幕的宽度,然后将其乘以2/3。或者,我可以将容器包装在0.66(2/3)的FractionallySizedBox类中,widthFactor以实现红色块的相同宽度。另请注意,堆栈的子项默认位于堆栈的左上角。因此,我们不需要对齐红色块:

    现在我们将橙色块放在stack上:

    Align(
      alignment: AlignmentDirectional.topEnd,
      child: Container(
        color: Colors.orange,
        width: MediaQuery.of(context).size.width * 1 / 3,
        height: 200,
        child: Center(
          child: Text(
            "2",
            style: TextStyle(fontSize: 50, color: Colors.white),
          ),
        ),
      ),
    ),
    

    请注意,这一次,我将整个包装Container在一个Align小部件中,将小部件移动到堆栈的右上角。而这一次,橙色块的宽度是整个屏幕宽度的1/3:

    添加和定位蓝色块有点棘手。因为如果你将它与“bottomRight”对齐,它最终会像这样:

    这是因为我们没有为堆栈指定任何大小。因此它已经扩展到整个屏幕的大小。现在我们有两个选项来对齐蓝色块:

    1. 限制Stack高度。通过将其包装在SizedBox窗口小部件中,并将height属性设置为300。
    2. 手动对齐蓝色块。即使用alignment: Alignment(1, -0.22)而不是alignment: AlignmentDirectional.*bottomEnd*

    我选择实施第一个:

    body: SizedBox(
      height: 300,
      child: Stack(
        children: <Widget>[
    

    结果:

    将最后一个子项放在Stack上几乎与前一个相同,唯一的区别是它的宽度设置为屏幕宽度的1/3,它的位置是左下角,或者是BottmStart:

    Align(
      alignment: AlignmentDirectional.bottomStart,
      child: Container(
        color: Colors.green,
        height: 200,
        width: MediaQuery.of(context).size.width * 1 / 3,
        child: Center(
          child: Text("4",
              style: TextStyle(fontSize: 50, color: Colors.white)),
        ),
      ),
    ),
    

    结果:

    最后的说明:

    1. MediaQuery课程对响应式设计非常有用。您可以使用它来查找屏幕的总大小,然后相应地设置小部件的大小。
    2. Expanded插件也是响应式设计非常方便,让你的部件由填充剩余的空间flex你指定的因素。
    3. 如果要将窗口小部件放置在其父窗口中,请将窗口小部件包装在窗口Align小部件中,并alignment相应地设置该属性。
    4. 如果没有为任何Stack的子项指定宽度和高度,默认情况下它们会将自身扩展到Stack的宽度和高度。
    5. 您还可以将Stack的每个子项包装在Positioned小部件中以对齐它们。

    整个源代码可以在github上找到。

    谢谢阅读!

    翻译自:https://medium.com/@meysam.mahfouzi/flutter-layout-challenge-squares-3d0bc4c78793

    相关文章

      网友评论

          本文标题:Flutter - 布局:正方形

          本文链接:https://www.haomeiwen.com/subject/smzadctx.html