Flutter布局(4):层叠布局(Stack、Positioned)

 


层叠布局和 Web 中的绝对定位、Android 中的 Frame 布局是相似的,子组件可以根据距父容器四个角的位置来确定自身的位置。层叠布局允许子组件按照代码中声明的顺序堆叠起来。Flutter中使用StackPositioned这两个组件来配合实现绝对定位。Stack允许子组件堆叠,而Positioned用于根据Stack的四个角来确定子组件的位置。

在 Flutter 中,层叠布局是一种常用的布局方式,用于实现多个组件的重叠排列。

Flutter 提供了两个用于层叠布局的组件:StackPositioned

  • Stack: Stack 组件用于将子组件按照层叠顺序进行排列,可以实现多个组件的重叠布局。
  • Positioned: Positioned 组件用于在 Stack 中定位子组件的位置。Positioned 组件必须作为 Stack 的直接子组件使用

Positioned 是只能,必须跟着 Stack 玩的,别人,不要它!也要不起!

一、Stack组件

Stack 组件用于将子组件按照层叠顺序进行排列,可以实现多个组件的重叠布局。Stack 组件定义如下:

Stack({
  this.alignment = AlignmentDirectional.topStart,
  this.textDirection,
  this.fit = StackFit.loose,
  this.clipBehavior = Clip.hardEdge,	
  List<Widget> children = const <Widget>[],
})

参数解析:

  • alignment(对齐方式):指定子组件在 Stack 内的对齐方式,默认为左上角对齐。

    fit(未定位子组件的布局方式):指定未定位子组件如何布局,可以是填充父容器(StackFit.expand)或根据子组件大小自适应(StackFit.loose)。

    overflow(溢出处理):指定当子组件超出 Stack 范围时的处理方式,默认为裁剪溢出部分。

Stack 常用场景

Stack 组件在开发中常用于以下场景:

  • 叠加效果:当需要将多个组件叠加在一起时,使用 Stack 组件可以方便地实现叠加效果。
    1. 背景图与内容叠加:在设计中,有时候需要将背景图与内容进行叠加显示。使用 Stack 组件可以将背景图和内容组合在一起,并按照指定的层叠顺序进行排列。

下面是一个可直接运行的示例代码,展示了 Stack 组件的基本用法:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Stack布局示例'),
        ),
        body: Stack(
          alignment: Alignment.center,
          children: <Widget>[
            Container(
              width: 200,
              height: 200,
              color: Colors.blue,
            ),
            const Text(
              '叠加文本',
              style: TextStyle(
                fontSize: 24,
                color: Colors.white,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

在这个例子中,我们创建了一个 Stack 布局,其中包含一个蓝色的正方形容器和一个居中显示的文本组件。Stack的alignment 属性设置为 Alignment.center,使得子组件在 Stack 中居中对齐。效果图如下所示:

Flutter_layoutWidget_P.png


二、Positioned组件

Positioned组件用于在Stack中定位子组件的位置。Positioned组件必须作为Stack的直接子组件使用。

Positioned 的默认构造函数如下:

const Positioned({
  Key? key,
  this.left, 
  this.top,
  this.right,
  this.bottom,
  this.width,
  this.height,
  required Widget child,
})
  • lefttoprightbottom分别代表离Stack左、上、右、底四边的距离。
  • widthheight用于指定需要定位元素的宽度和高度。
  • 注意,Positionedwidthheight 和其他地方的意义稍微有点区别,此处用于配合lefttoprightbottom来定位组件,举个例子,在水平方向时,你只能指定leftrightwidth三个属性中的两个,如指定leftwidth后,right会自动算出(left+width),如果同时指定三个属性则会报错,垂直方向同理。

Positioned 使用场景

Positioned 组件在开发中常用于以下场景:

  1. 精确定位:当需要将子组件精确定位在 Stack 中的特定位置时,使用 Positioned 组件可以方便地控制子组件的偏移量。
  2. 图层叠加:与 Stack 组件结合使用,可以在叠加的组件中精确定位子组件,实现复杂的图层叠加效果。

下面是一个可直接运行的示例代码,展示了 Positioned 组件的基本用法:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Positioned布局示例'),
        ),
        body: Stack(
          alignment: Alignment.center,
          children: <Widget>[
            Container(
              width: 300,
              height: 300,
              color: Colors.blue,
            ),
            const Positioned(
              top: 50,
              left: 50,
              child: Text(
                '定位文本',
                style: TextStyle(
                  fontSize: 24,
                  color: Colors.white,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

在这个例子中,我们使用 Positioned 组件将文本组件定位在蓝色容器的左上角,实现了精确的定位效果。效果图如下所示:

Flutter_layoutWidget_Q.png


三、演示stack的不同属性的不同作用

show time,演示不同的属性:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Stack布局示例'),
        ),
        body: Stack(
          alignment: Alignment.center,
          fit: StackFit.expand, // 将未定位的子组件填充满整个Stack的空间
          children: <Widget>[
            Container(
              width: 200,
              height: 200,
              color: Colors.blue,
            ),
            const Positioned(
              top: 50,
              left: 50,
              child: Text(
                'Positioned文本', // Positioned定位的子组件
                style: TextStyle(
                  fontSize: 24,
                  color: Colors.white,
                ),
              ),
            ),
            const Positioned(
              bottom: 50,
              right: 50,
              child: Text(
                '底部右侧', // Positioned定位的子组件
                style: TextStyle(
                  fontSize: 20,
                  color: Colors.yellow,
                ),
              ),
            ),
            const Text(
              '居中文本', // Stack的子组件,在Stack中居中对齐
              style: TextStyle(
                fontSize: 30,
                color: Colors.red,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

效果图如下所示:

Flutter_layoutWidget_X.png


四、注意事项和常见问题

在使用 Stack 和 Positioned 进行层叠布局时,需要注意以下几点:

  • 层叠顺序:组件在Stack中的层叠顺序由其在children列表中的顺序决定。后面的子组件将覆盖前面的子组件。
  • 定位偏移量:在使用Positioned组件时,需要注意指定子组件的边距(left、top、right、bottom属性),以确保子组件在Stack中定位正确。
  • 溢出处理:如果子组件超出Stack的范围,可以通过设置Stack的overflow属性来控制溢出的处理方式。

层叠布局适用于许多场景,如实现复杂的图层叠加效果、创建自定义的悬浮按钮、实现覆盖式的弹出框等。

五、Align和Stack的对比

Align 和 Stack 都是在 Flutter 中用于布局的组件,它们有一些相似之处,也有一些不同之处。下面是 Align 和 Stack 之间的异同点:

相同点:

  • 层叠布局:Align 和 Stack 都支持层叠布局,可以将多个子组件进行叠加排列。
  • 对齐功能:Align 和 Stack 都提供了对子组件的对齐功能,可以通过设置对齐参数来控制子组件在父组件中的位置。

不同点:

  • 层级管理:Stack 是一个可以管理多个子组件的容器,可以通过 Stack 的层叠顺序来控制子组件的显示顺序。而 Align 只能包含一个子组件,并且不涉及层叠顺序。
  • 子组件尺寸:在 Stack 中,子组件可以具有不同的尺寸,并且可以通过 Positioned 组件来精确控制子组件的位置。而在 Align 中,子组件的尺寸会受到 Align 组件的约束,并且无法通过属性直接控制子组件的位置。
  • 父组件尺寸:在 Stack 中,父组件的尺寸默认由子组件的尺寸决定,可以通过设置 fit 属性来调整子组件对父组件的适应方式。而 Align 会根据子组件的尺寸来调整自身的尺寸,并将子组件放置在中心或指定的位置。

适用场景:

  • 使用 Stack:当需要对多个子组件进行层叠布局,并且对层叠顺序和尺寸有精确控制的场景下,使用 Stack 是较为合适的选择。
  • 使用 Align:当需要将单个子组件放置在特定位置,并对其进行对齐的场景下,使用 Align 是较为合适的选择。

posted @   fengMisaka  阅读(664)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示