Flutter学习之旅 - 页面布局Stack层叠组件

Stack

Stack意思是堆的意思,我们可以用Stack结合Align或者Stack结合Positioned来实现页面的定位布局

属性说明
alignment配置所有元素显示位置
children子组件
class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
          height: 400,
          width: 300,
          color: Colors.red,
        ),
        Container(
          height: 200,
          width: 200,
          color: Colors.yellow,
        ),
        const Text("你好")
      ],
    );
  }
}

在这里插入图片描述

Positioned定位布局

/*
格式:
Positioned(component())
*/
class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return Container(
        child: Stack(
        //相对与外部的容器进行定位
      children: [
        Container(
          width: 300,
          height: 400,
          color: Colors.red,
        ),
        Positioned(//注意: 相对于外部容器进行定位,如果没有外部容器对于整个屏幕进行定位
          //在Container外面包裹一个Positioned
          //主要代码
          left: 0,
          bottom: 0,
          child: Container(
            width: 200,
            height: 200,
            color: Colors.yellow,
          ),
        ),
        const Text("你好")
      ],
    ));
  }
}

在这里插入图片描述

浮动导航(Stack+Positioned)

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return Stack(//重点
      children: [
        ListView(
          children: const [
            ListTile(
              title: Text("我是一个列表1"),
            ),
            ListTile(
              title: Text("我是一个列表2"),
            ),
            ListTile(
              title: Text("我是一个列表3"),
            ),
            ListTile(
              title: Text("我是一个列表4"),
            ),
            ListTile(
              title: Text("我是一个列表5"),
            ),
            ListTile(
              title: Text("我是一个列表6"),
            ),
            ListTile(
              title: Text("我是一个列表7"),
            ),
            ListTile(
              title: Text("我是一个列表8"),
            ),
            ListTile(
              title: Text("我是一个列表8"),
            ),
            ListTile(
              title: Text("我是一个列表9"),
            ),
            ListTile(
              title: Text("我是一个列表10"),
            ),
            ListTile(
              title: Text("我是一个列表11"),
            ),
            ListTile(
              title: Text("我是一个列表12"),
            ),
            ListTile(
              title: Text("我是一个列表13"),
            ),
            ListTile(
              title: Text("我是一个列表14"),
            ),
            ListTile(
              title: Text("我是一个列表15"),
            ),
          ],
        ),
        Positioned(
            left: 0,
            top: 0,
            width: 300,
            height: 44,
            child: Row( //重点
              children: [
                Expanded(
                  flex: 1,
                  child: Container(
                    height: 44,
                    color: Colors.black,
                    alignment: Alignment.center,
                    child: const Text(
                      "二级导航",
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                )
              ],
            ))
      ],
    );
  }
}

在这里插入图片描述

FlutterMediaQuery获取屏幕宽度和高度

因为double.infinity只能用在Container组件中再加上Positioned在没有之前的容器中的长宽,所以要自己定义

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    //获取设备的宽度和高度
    final size = MediaQuery.of(context).size;
    return Stack(
      children: [
        ListView(
          children: const [
            ListTile(
              title: Text("我是一个列表1"),
            ),
            ListTile(
              title: Text("我是一个列表2"),
            ),
            ListTile(
              title: Text("我是一个列表3"),
            ),
            ListTile(
              title: Text("我是一个列表4"),
            ),
            ListTile(
              title: Text("我是一个列表5"),
            ),
            ListTile(
              title: Text("我是一个列表6"),
            ),
            ListTile(
              title: Text("我是一个列表7"),
            ),
            ListTile(
              title: Text("我是一个列表8"),
            ),
            ListTile(
              title: Text("我是一个列表8"),
            ),
            ListTile(
              title: Text("我是一个列表9"),
            ),
            ListTile(
              title: Text("我是一个列表10"),
            ),
            ListTile(
              title: Text("我是一个列表11"),
            ),
            ListTile(
              title: Text("我是一个列表12"),
            ),
            ListTile(
              title: Text("我是一个列表13"),
            ),
            ListTile(
              title: Text("我是一个列表14"),
            ),
            ListTile(
              title: Text("我是一个列表15"),
            ),
          ],
        ),
        Positioned(
            left: 0,
            top: 0,
            width: size.width,
            height: 44,
            child: Row(
              children: [
                Expanded(
                  flex: 1,
                  child: Container(
                    height: 44,
                    color: Colors.black,
                    alignment: Alignment.center,
                    child: const Text(
                      "二级导航",
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                )
              ],
            ))
      ],
    );
  }
}

就实现了我们所需要的等宽的功能

Stack+Align

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    //获取设备的宽度和高度

    return Container(
      // alignment: Alignment.center,
      width: 300,
      height: 200,
      color: Colors.red,
      child: const Align(
        //alignment: Alignment.center,
        //alignment: Alignment(1, 1),//Alignment.x*childWidth/2+childWidth/2,childWidth.y*childHeight/2+childHeight/2来实现的
        alignment: Alignment(-1, 1),
        child: Text("你好"),
      ),
    );
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

结城明日奈是我老婆

支持一下一直热爱程序的菜鸟吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值