Flutter学习笔记09-stack层叠组件

学习视频地址:https://www.bilibili.com/video/BV1S4411E7LY/?p=28&spm_id_from=pageDriver&vd_source=cee744cae4ead27f8193fc7904647073

学习笔记:
1.是用stack构建布局

import 'package:flutter/material.dart';

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

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

  
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primarySwatch: Colors.blue),
      home: Scaffold(
        appBar: AppBar(
          title: const Text("Flutter Demo"),
        ),
        body: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
          width: 400,
          height: 400,
          color: Colors.red,
        ),
        Container(
          width: 200,
          height: 200,
          color: Colors.yellow,
        ),
        Text("hello flutter")
      ],
    );
  }
}

显示效果
在这里插入图片描述
可以看到,这些组件是叠在一起的

2.Stack结合Positioned使用
代码如下

class MyHomePage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Container(
      height: 400,
      width: 300,
      color: Colors.green,
      child: Stack(
        children: [
          Positioned(
            left: 10,
            top: 10,
            child: Container(
              width: 200,
              height: 200,
              color: Colors.yellow,
            ),
          ),
          Positioned(
            right: 10,
            bottom: 10,
            child: Container(
              width: 200,
              height: 200,
              color: Colors.red,
            ),
          ),
          Text("hello flutter")
        ],
      ),
    );
  }
}

可以看到,Positioned是作为Stack的子组件,Positioned内部设置的上下左右边距是相对于Stack的父布局的。显示效果如下:
在这里插入图片描述
3.实现悬浮顶部标题栏效果

class MyHomePage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Stack(
      children: [
        ListView(
          children: [
            ListTile(
              title: Text("我是一个列表1"),
            ),
            ListTile(
              title: Text("我是一个列表2"),
            ),
            ListTile(
              title: Text("我是一个列表3"),
            ),
            ListTile(
              title: Text("我是一个列表4"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
          ],
        ),
        Positioned(
            top: 10,
            left: 0,
            child: Row(
              children: [
                Expanded(
                  flex: 1,
                  child: Container(
                    alignment: Alignment.center,
                    height: 44,
                    color: Colors.red,
                    child: Text(
                      "二级导航",
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                )
              ],
            ))
      ],
    );
  }
}

运行上面代码是会报错的

======== Exception caught by rendering library =====================================================
The following assertion was thrown during performLayout():
RenderFlex children have non-zero flex but incoming width constraints are unbounded.

When a row is in a parent that does not provide a finite width constraint, for example if it is in a horizontal scrollable, it will try to shrink-wrap its children along the horizontal axis. Setting a flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining space in the horizontal direction.
These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child cannot simultaneously expand to fit its parent.

Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible children (using Flexible rather than Expanded). This will allow the flexible children to size themselves to less than the infinite remaining space they would otherwise be forced to take, and then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum constraints provided by the parent.

要给Row的父布局设置宽度才行

class MyHomePage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    //获取屏幕信息
    final size = MediaQuery.of(context).size;
    return Stack(
      children: [
        ListView(
          children: [
            ListTile(
              title: Text("我是一个列表1"),
            ),
            ListTile(
              title: Text("我是一个列表2"),
            ),
            ListTile(
              title: Text("我是一个列表3"),
            ),
            ListTile(
              title: Text("我是一个列表4"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
          ],
        ),
        Positioned(
            top: 10,
            left: 0,
            width: size.width,
            child: Row(
              children: [
                Expanded(
                  flex: 1,
                  child: Container(
                    alignment: Alignment.center,
                    height: 44,
                    color: Colors.red,
                    child: Text(
                      "二级导航",
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                )
              ],
            ))
      ],
    );
  }
}

我这里将Positioned的宽度设置为屏幕的宽度
屏幕的宽度这样获取的:
在MyHomePage的build方法里获取

//获取屏幕信息
final size = MediaQuery.of(context).size;

4.Align组件

class MyHomePage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    //获取屏幕信息
    final size = MediaQuery.of(context).size;
    return Container(
      width: 300,
      height: 300,
      color: Colors.red,
      child: Align(
        alignment: Alignment.center,
        child: Text("hello flutter"),
      ),
    );
  }
}

显示效果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值