【Flutter】线性布局弹性布局层叠布局

🔥 本文由 程序喵正在路上 原创,CSDN首发!
💖 系列专栏:Flutter学习
🌠 首发时间:2024年5月25日
🦋 欢迎关注🖱点赞👍收藏🌟留言🐾

目录

  • 线性布局
    • Row水平布局组件
    • Column垂直布局组件
    • double.infinity和double.maxFinite
  • 弹性布局
    • 水平弹性布局
    • 垂直弹性布局
    • 使用Row或Column结合Expanded实现案例
  • 层叠布局
    • Stack组件
    • Align组件
    • Positioned组件
    • MediaQuery获取屏幕宽度和高度
    • Stack结合Positioned固定导航案例

线性布局

Row水平布局组件

在这里插入图片描述

实现如下效果:

在这里插入图片描述

因为图中有3个差不多的盒子,都是一个盒子里面放一个图标,所以我们将其写成了一个类 IconContainer,以减少代码量

class MyHomePage extends StatelessWidget {const MyHomePage({super.key});Widget build(BuildContext context) {return Container(height: double.infinity, //无穷大width: double.infinity,color: Colors.white,child: Row(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [IconContainer(Icons.home, color: Colors.red),IconContainer(Icons.search),IconContainer(Icons.send, color: Colors.orange),],),);}
}class IconContainer extends StatelessWidget {Color color; //盒子颜色double iconSize; //图标大小IconData icon; //图标//盒子默认为蓝色,图标大小默认32IconContainer(this.icon,{super.key, this.color = Colors.blue, this.iconSize = 32});Widget build(BuildContext context) {return Container(height: 100,width: 100,color: color,//图标颜色默认为白色child: Center(child: Icon(icon, size: iconSize, color: Colors.white)),);}
}

Column垂直布局组件

在这里插入图片描述

实现如下效果:

在这里插入图片描述

将前面代码中的 Row 改成 Column 即可:

在这里插入图片描述

double.infinity和double.maxFinite

double.infinitydouble.maxFinite 可以让当前元素的 width 或者 height 达到父元素的尺寸

如下可以让Container铺满整个屏幕

class MyHomePage extends StatelessWidget {const MyHomePage({super.key});Widget build(BuildContext context) {return Container(height: double.infinity,width: double.infinity,color: Colors.white,child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [IconContainer(Icons.home, color: Colors.red),IconContainer(Icons.search),IconContainer(Icons.send, color: Colors.orange),],),);}
}

如下可以让Container的宽度和高度等于父元素的宽度高度

class MyHomePage extends StatelessWidget {const MyHomePage({super.key});Widget build(BuildContext context) {return Container(height: 500,width: 300,color: Colors.red,child: Container(height: double.maxFinite,width: double.infinity,color: Colors.yellow,child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [IconContainer(Icons.home, color: Colors.red),IconContainer(Icons.search),IconContainer(Icons.send, color: Colors.orange),],),),);}
}

在这里插入图片描述

弹性布局

水平弹性布局

Flex 组件可以沿着水平或垂直方向排列子组件,如果你知道主轴方向,使用 RowColumn 会方便一些,因为 RowColumn 都继承自 Flex ,参数基本相同,所以能使用 Flex 的地方基本上都可以使用 RowColumnFlex 本身功能是很强大的,它也可以和 Expanded 组件配合实现弹性布局 。

实现如下效果:

在这里插入图片描述

class MyHomePage extends StatelessWidget {const MyHomePage({super.key});Widget build(BuildContext context) {return Flex(direction: Axis.horizontal, //水平方向children: [//flex: 占用多少位置Expanded(flex: 2, child: IconContainer(Icons.home, color: Colors.red)),Expanded(flex: 1, child: IconContainer(Icons.search))],);}
}class IconContainer extends StatelessWidget {Color color; //盒子颜色double iconSize; //图标大小IconData icon; //图标//盒子默认为蓝色,图标大小默认32IconContainer(this.icon,{super.key, this.color = Colors.blue, this.iconSize = 32});Widget build(BuildContext context) {return Container(height: 100,width: 100,color: color,//图标颜色默认为白色child: Center(child: Icon(icon, size: iconSize, color: Colors.white)),);}
}

因为 Row 继承自 Flex ,所以我们将代码中的 Flex 换成 Row,同样是可以的,而且我们还不用设置方向。当我们能确定主轴的方向时,推荐使用 RowColumn

class MyHomePage extends StatelessWidget {const MyHomePage({super.key});Widget build(BuildContext context) {return Row(children: [//flex: 占用多少位置Expanded(flex: 2, child: IconContainer(Icons.home, color: Colors.red)),Expanded(flex: 1, child: IconContainer(Icons.search))],);}
}

垂直弹性布局

class MyHomePage extends StatelessWidget {const MyHomePage({super.key});Widget build(BuildContext context) {return Column(children: [//flex: 占用多少位置Expanded(flex: 2, child: IconContainer(Icons.home, color: Colors.red)),Expanded(flex: 1, child: IconContainer(Icons.search))],);}
}

在这里插入图片描述

使用Row或Column结合Expanded实现案例

实现如下效果:

在这里插入图片描述

class MyHomePage extends StatelessWidget {const MyHomePage({super.key});Widget build(BuildContext context) {return ListView(children: [Container(width: double.infinity,height: 200,color: Colors.blue,child: Image.network("https://xixi-web-tlias.oss-cn-guangzhou.aliyuncs.com/1.jpg",fit: BoxFit.cover)),const SizedBox(height: 10),Row(children: [Expanded(flex: 2,child: SizedBox(height: 200,child: Image.network("https://xixi-web-tlias.oss-cn-guangzhou.aliyuncs.com/2.jpg",fit: BoxFit.cover),)),const SizedBox(width: 10),Expanded(flex: 1,child: SizedBox(height: 200,child: Column(children: [Expanded(flex: 1,child: SizedBox(width: double.infinity,child: Image.network("https://xixi-web-tlias.oss-cn-guangzhou.aliyuncs.com/3.jpg",fit: BoxFit.cover),),),const SizedBox(height: 10),Expanded(flex: 1,child: SizedBox(width: double.infinity,child: Image.network("https://xixi-web-tlias.oss-cn-guangzhou.aliyuncs.com/4.jpg",fit: BoxFit.cover),),),],),),),],),const SizedBox(height: 10),Row(children: [Expanded(flex: 1,child: SizedBox(height: 200,child: Column(children: [Expanded(flex: 1,child: SizedBox(width: double.infinity,child: Image.network("https://xixi-web-tlias.oss-cn-guangzhou.aliyuncs.com/5.jpg",fit: BoxFit.cover),),),const SizedBox(height: 10),Expanded(flex: 1,child: SizedBox(width: double.infinity,child: Image.network("https://xixi-web-tlias.oss-cn-guangzhou.aliyuncs.com/6.jpg",fit: BoxFit.cover),),),]),),),const SizedBox(width: 10),Expanded(flex: 1,child: SizedBox(height: 200,child: Column(children: [Expanded(flex: 1,child: SizedBox(width: double.infinity,child: Image.network("https://xixi-web-tlias.oss-cn-guangzhou.aliyuncs.com/7.jpg",fit: BoxFit.cover),),),const SizedBox(height: 10),Expanded(flex: 1,child: SizedBox(width: double.infinity,child: Image.network("https://xixi-web-tlias.oss-cn-guangzhou.aliyuncs.com/8.jpg",fit: BoxFit.cover),),),]),),),],),],);}
}

层叠布局

Stack组件

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

属性说明
alignment配置所有子元素的显示位置
children子组件
class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return Center(child: Stack(alignment: Alignment.topLeft,children: [Container(height: 400,width: 300,color: Colors.blue,),const Text("我是一个文本",style: TextStyle(fontSize: 40, color: Colors.white),)],),);}
}

在这里插入图片描述

Align组件

Align 组件可以调整子组件的位置 , Stack 组件中结合 Align 组件也可以控制每个子元素的显示位置

属性说明
alignment配置所有子元素的显示位置
child子组件

Align结合Container的使用

我们先来看一个简单的例子:

FlutterLogoFlutter SDK 提供的一个组件,内容就是 Flutterlog

class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return Container(height: 300,width: 300,color: Colors.blue.shade50,child: const Align(alignment: Alignment.topRight,child: FlutterLogo(size: 100,),),);}
}

在这里插入图片描述

Align结合Container的使用

class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return Container(height: 300,width: 300,color: Colors.blue.shade50,child: const Align(alignment: Alignment(2, 0),child: FlutterLogo(size: 100,),),);}
}

在这里插入图片描述

Alignment Widget 会以矩形的中心点作为坐标原点,即 Alignment(0, 0) 。 x 、y 的值从 -1 到 1 分别代表矩形左边到右边的距离和顶部到底边的距离,因此 2 个水平(或垂直)单位则等于矩形的宽(或高),如 Alignment(-1, -1) 代表矩形的左侧顶点,而 Alignment(1, 1) 代表右侧底
部终点,而 Alignment(1, -1) 则正是右侧顶点,即 Alignment.topRight。为了使用方便,矩形的原点、四个顶点,以及四条边的终点在 Alignment 类中都已经定义为了静态常量。

Alignment 可以通过其坐标转换公式将其坐标转为子元素的具体偏移坐标:

(Alignment.x*childWidth/2+childWidth/2, Alignment.y*childHeight/2+childHeight/2)

其中 childWidth 为子元素的宽度, childHeight 为子元素高度。

现在我们再看看上面的示例,我们将 Alignment(2, 0) 带入上面公式, ( 2 × 300 / 2 + 300 / 2 , 0 × 300 / 2 + 300 / 2 ) (2 \times 300 / 2 + 300 / 2, 0 \times 300 / 2 + 300 / 2) (2×300/2+300/2,0×300/2+300/2) ,可得 FlutterLogo 的实际偏移坐标正是 (450,150)

Align结合Stack的使用

class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return Center(child: Container(height: 400,width: 300,color: Colors.blue,child: const Stack(children: [Align(alignment: Alignment(1, -0.2),child: Icon(Icons.home, size: 40, color: Colors.white),),Align(alignment: Alignment.center,child: Icon(Icons.search, size: 30, color: Colors.white),),Align(alignment: Alignment.bottomRight,child: Icon(Icons.settings_applications,size: 30, color: Colors.white),),],),),);}
}

在这里插入图片描述

Positioned组件

Stack 组件中结合 Positioned 组件也可以控制每个子元素的显示位置

属性说明
top子元素距离顶部的距离
bottom子元素距离底部的距离
left子元素距离左侧距离
right子元素距离右侧距离
child子组件
width组件的高度(注意:宽度和高度必须是固定值,不能使用 double.infinity
height子组件的高度
class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return Center(child: Container(height: 400,width: 300,color: Colors.blue,child: const Stack(children: [Positioned(left: 10,child: Icon(Icons.home, size: 40, color: Colors.white),),Positioned(bottom: 0,left: 100,child: Icon(Icons.search, size: 30, color: Colors.white),),Positioned(right: 0,child: Icon(Icons.settings_applications,size: 30, color: Colors.white),),],),),);}
}

在这里插入图片描述

MediaQuery获取屏幕宽度和高度

前面说到 Positioned 组件的高度和宽度不能使用 double.infinity,在这种情况下,如果我们可以在组件的 build 方法中可以通过 MediaQuery.of(context).size; 来设置

final size = MediaQuery.of(context).size;
final width = size.width;
final height = size.height;

Stack结合Positioned固定导航案例

实现如下效果:

在这里插入图片描述

class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {final size = MediaQuery.of(context).size;return Stack(children: [ListView(padding: const EdgeInsets.only(top: 45),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("我是标题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(top: 0,left: 0,height: 40,width: size.width,child: Container(alignment: Alignment.center,color: Colors.blue,child: const Text("二级导航",style: TextStyle(color: Colors.white),),),),]);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/14911.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

4、PHP的xml注入漏洞(xxe)

青少年ctf&#xff1a;PHP的XXE 1、打开网页是一个PHP版本页面 2、CTRLf搜索xml&#xff0c;发现2.8.0版本&#xff0c;含有xml漏洞 3、bp抓包 4、使用代码出发bug GET /simplexml_load_string.php HTTP/1.1 补充&#xff1a; <?xml version"1.0" encoding&quo…

内网穿透--Nps-自定义-上线

免责声明:本文仅做技术交流与学习... 目录 Nps项目: 一图通解: 1-下载nps/npc 2-服务端启动 访问web网页: 添加客户端&#xff0c;生成密匙. 3-kali客户端连接服务端 4-添加协议隧道. 5-kali生成后门&#xff1a; 6-kali创建监听: Nps项目: https://github.com/ehang…

蓝桥杯Web开发【模拟题一】15届

1.动态的Tab栏 日常在使用移动端 APP 或访问 PC 端网站的时候&#xff0c;常常发现在一些有工具栏或者 Tab 栏的页面会有顶栏固定的效果。简单来说&#xff0c;在页面未开始滚动时顶栏处在其原有的位置上&#xff0c;当页面向下滚动一定区域后&#xff0c;顶栏会跟随滚动固定在…

HTTPS证书——网站如何实现HTTPS访问?

实现网站HTTPS访问可以简化为以下四个基本步骤&#xff0c;确保过程既通俗易懂又条理清晰&#xff1a; 1. 申请SSL证书 - 目的&#xff1a;SSL证书是实现HTTPS加密的关键&#xff0c;它验证了网站的身份&#xff0c;并提供了加密数据所需的密钥。 - 操作&#xff1a;首先&…

TypeScript(持续更新中...)

1.TypeScript是什么&#xff1f; TypeScript是javaScript的超集。 2.使用TypeScript 1&#xff09;全局安装nodejs 2&#xff09;安装TypeScript编译器 npm i -g typescript 3.编译ts文件 //注意&#xff1a;需要在ts文件同级目录执行此命令&#xff0c;否则会报找不到…

遥感、GIS和GPS技术在水文、气象、灾害、生态、环境及卫生等领域中的应用

【科研必备】遥感、GIS和GPS技术在水文、气象、灾害、生态、环境及卫生等领域中的应用 (qq.com)https://mp.weixin.qq.com/s?__bizMzg2NDYxNjMyNA&mid2247565057&idx4&snecec1f5396132122acf02b188f7b74ac&chksmce6515eaf9129cfc9a6c4a16413c0d746003cc192132…

C++ Primer Plus第十七章复习题

1、iostream文件在CI/O中扮演这种角色&#xff1f; 答&#xff1a; iostream文件定义了用于管理输入和输出的类、常量和操纵符,这些对象管理用于处理I/O的流和缓冲区。该文件还创建了一些标准对象(cin、cout、cerr和 clog以及对应的宽字符对象)&#xff0c;用于处理与每个程序…

【论文笔记】| 微调LLM晶体生成

【论文笔记】| 微调LLM晶体生成 Fine-Tuned Language Models Generate Stable Inorganic Materials as Text NYU, ICLR 2024 Theme&#xff1a;Material Generation Main work&#xff1a; 微调大型语言模型以生成稳定的材料 可靠性&#xff1a;在样本结构中&#xff0c;90% …

如何修改WordPress网站的域名

我的网站用的是Hostease的虚拟主机&#xff0c;但是域名是之前在其他平台买的&#xff0c;而且已经快到期了&#xff0c;因为主机和域名在不同的平台上&#xff0c;管理不太方便&#xff0c;所以我又在Hostease重新注册了一个域名&#xff0c;然后把网站换成了新的域名&#xf…

(Java企业 / 公司项目)配置Linux网络-导入虚拟机

公司给了我一个IP地址 &#xff0c;提供了一个虚拟机或者自己搭建虚拟机&#xff0c;还有提供登录的账号密码 可以查看我之前的文章 VMware Workstation Pro 17虚拟机超级详细搭建&#xff08;含redis&#xff0c;nacos&#xff0c;docker, rabbitmq&#xff0c;sentinel&…

3D透视图模型转模型变形?---模大狮模型网

3D建模是数字艺术和设计领域中的重要技术&#xff0c;它可以为我们带来丰富多彩的视觉体验和创意表达。在本文中&#xff0c;我们将探讨一个引人注目的话题&#xff1a;3D透视图中模型转换是否会导致变形?通过深入探讨这个问题&#xff0c;我们希望能够帮助您更好地理解在3D建…

如何通过软件SPI读写W25Q64

STM32F1之SPI通信软件SPI代码编写-CSDN博客 目录 1. W25Qxx系列简介 2. W25Q64硬件电路 3. W25Q64框图 4. Flash操作注意事项 5. 代码编写 5.1 初始化 5.2 W25Q64读取ID号 5.3 W25Q64写使能 5.4 W25Q64等待忙 5.5 W25Q64页编程 5.6 W25Q64扇区擦除&#x…

WebRTC | 网络传输协议 RTP 和 RTCP

WebRTC | 网络传输协议 RTP 和 RTCP WebRTC | 网络传输协议 RTP 和 RTCP如何选择 TCP 与 UDPRTP概述工作机制报文结构RTP 的使用RTP 拓展头RTP 中的填充数据翻译器和混合器同步控制报文大小wireshark 抓取 RTP 报文 RTCP概述工作机制分组类型报文结构WebRTC 的反馈报文RTPFBPSF…

深入浅出递归算法

文章目录 递归思想递归的题目1.汉诺塔问题问题分析代码展示 2.合并两个有序链表问题分析代码展示 3.反转链表问题分析代码展示 4.两两交换 链表中的节点问题分析代码展示 总结 递归思想 递归就是将一个很大的问题拆分成子问题&#xff0c;然后再将子问题继续拆分&#xff0c;拆…

【linux-IMX6ULL-字符设备驱动简单框架实验】

目录 1. 字符设备驱动简介1.1 重要函数1.2 简单框架代码流程1.3 linux中关于驱动的重要命令 2. 字符设备驱动简单框架编写2.1 添加LICENSE信息2.2 驱动模块的入口与出口2.3 入口和出口函数的编写2.4 设备操作结构体定义2.4.1 结构体函数内容填充 3. 应用程序简介&#xff1a;4.…

Design to code(2)

【碎碎念】从七点到十一点&#xff0c;累计用时4个小时完成的代码翻译Σ(&#xffe3;。&#xffe3;ノ)ノ DCDS图 顺序图&#xff08;支付过程&#xff09; 交互图&#xff08;订单&#xff09; 我的代码 Payment public class Payment { //定义支付订单金额 private…

FL Studio2025中文最新版本专业编曲软件有哪些新功能?

FL Studio 21&#xff0c;也被音乐制作爱好者亲切地称为“水果编曲软件”&#xff0c;是比利时的Image-Line公司研发的一款完整的音乐制作环境或数字音频工作站&#xff08;DAW&#xff09;。自从1990年代推出以来&#xff0c;FL Studio 以其直观的用户界面、丰富的插件支持和强…

玩机社区 - 2024年最美社区源码开源

玩机社区 - 2024年最美社区源码开源 教程源码文档都内置到压缩包了 https://pan.baidu.com/s/1xwcscTne-JMbmKEntiuAuA?pwd78oi

逻辑分析仪 - 采样率/采样深度

采样深度&#xff08;Sampling Depth&#xff09; 采样深度指的是逻辑分析仪在一次捕获过程中可以记录的最大样本数量。简单来说&#xff0c;采样深度越大&#xff0c;逻辑分析仪可以记录的数据量就越多。这对于分析长时间的信号变化或复杂的信号序列非常重要。 采样率&#…

2024年5月23日 (周四) 叶子游戏新闻

《Unclogged》Steam页面上线 马桶主题恐怖逃脱解谜Brody制作并发行&#xff0c;一款奇葩创意马桶主题恐怖逃脱解谜新游《Unclogged》Steam页面上线&#xff0c;本作暂不支持中文。 Meta人工智能主管杨立昆 大语言模型不会达到人类智能水平IT之家今日&#xff08;5月23日&#x…