flutter布局详解及代码示例(补充)

布局

基本布局

  • Container(基本布局):最常见widget
  • Padding(内边距布局):Container增加padding的布局
  • Center(居中布局):Container设置居中的布局
  • Align(对齐布局):Container设置自定义对齐方式的布局
  • FittedBox(自定义约束布局):可以控制子widget是否可以超出父widget约束的布局
  • AspectRatio(宽高比布局):基于宽高比约束child的布局
  • ConstrainedBox(边界约束布局):Container设置constraints的布局;基于最大最小宽高,约束child的布局
  • Baseline(基线布局):根据基线约束子widget位置的布局
  • FractionallySizedBox(自适应尺寸布局):根据现有空间,来调整child的尺寸,child就算设置了具体的尺寸,也不起作用。
  • IntrinsicHeight(不固定高度布局):根据子widget的高度调整其自身高度
  • IntrinsicWidth(不固定宽度布局):根据子widget的宽度调整其自身宽度
  • LimitedBox(限制子控件宽高的布局):一个当其自身不受约束时才限制其大小的布局
  • Offstage(显隐布局):控制某些组件是否展示,不可见但实际存在
  • OverflowBox(允许自己的子控件溢出自己父控件的布局):允许子控件溢出父控件。
  • SizedBox(尺寸布局):Container增加宽高的布局
  • SizedOverflowBox(允许超出的有宽高的布局):SizedBox与OverflowBox的结合体
  • Transform(矩阵变换布局):能平移旋转缩放等操作的布局
  • CustomSingleChildLayout(纯自定义布局):单个child所有都能自定义的布局

Container

参数解释

  • alignment child在容器内的对齐方式
  • padding child在容器内的内间距
  • margin 容器与父类的外边距
  • color 背景颜色
  • decoration 背景装饰,不能与color属性同时设置
  • foregroundDecoration 前景装饰,会遮住child,可设置颜色透明度使其可见
  • width 容器的宽度
  • height 容器的高度
  • constraints 容器宽高的最大最小限制
  • transform 在绘制容器之前应用的转换矩阵。

补充

  • Alignment有个子类FractionalOffset,可以基于坐标系偏移
  • BoxDecoration的值:
    • BoxDecoration:绘制一个不可变的矩形或圆形框
    • ShapeDecoration:绘制一个不可变的任意形状。
    • FlutterLogoDecoration:绘制一个不变的Flutter的logo和标签。(没用)

FittedBox

构造函数

const FittedBox({super.key,this.fit = BoxFit.contain,  //默认包含this.alignment = Alignment.center,this.clipBehavior = Clip.none,  //默认超出不剪裁super.child,
});
  • fit: 该参数若是:
    • BoxFit.contain,则当子widget超出父widget尺寸限制时,为了确保包含,会对子widget进行缩放,尽可能包含。
    • BoxFit.none,则当子widget超出父widget尺寸限制时,子widget会无视父widget直接显示
  • clipBehavior:搭配BoxFit.none使用,因为只有子widget超出父widget尺寸约束了,才存在是否剪裁的可能。

常见实践

  • 不同设备屏幕宽度有很多,如果出现子widget太大,通过BoxFit.contain属性就能实现尽可能的对子widget缩放,而展示出完整的子widget。

补充

  • FittedBox不会在debug模式提示“尺寸溢出”错误。

AspectRatio

构造函数

const AspectRatio({super.key,required this.aspectRatio,  // 宽:高,比如2.0/1.0,比如0.5,反正是个doublesuper.child,
})
  • AspectRatio 宽高比是相对父容器的,根据宽高比,绘制对应的AspectRatio内部的child的尺寸。
  • 内部的child设置了宽高,可能不起效。

常见实践

  • 绘制一些16:9的图片或者视频view

ConstrainedBox

构造函数

ConstrainedBox({super.key,required this.constraints,super.child,
})
/// constraints的构造函数
const BoxConstraints({this.minWidth = 0.0,this.maxWidth = double.infinity,this.minHeight = 0.0,this.maxHeight = double.infinity,
})
  • ConstrainedBox用于对齐子widget添加额外的约束。
  • 限制的是子widget的尺寸,且一旦冲突,以ConstrainedBox的限制为主。

代码

ConstrainedBox(constraints: BoxConstraints(minWidth: double.infinity, //宽度尽量大minHeight: 50.0 //最小高度为50),child: Container(height: 10.0, child: xx ),
)
  • 这段代码就体现了“限制的是子widget的尺寸,且一旦冲突,以ConstrainedBox的限制为主”。
  • 哪怕子widget的高度设置10.0,但是和最小高度为50冲突,于是使用ConstrainedBox的最小高度为50。

Baseline

构造函数

const Baseline({super.key,required this.baseline,required this.baselineType,super.child,
})
/// TextBaseline枚举
enum TextBaseline {alphabetic,  //对齐字母字符字形底部ideographic,  //对齐表意字符的水平线
} 
  • 对齐字母字符字形底部,指的是如jpg这些字母,基线都在靠上一点,而“对齐表意字符的水平线”,则当汉字和jpg这些字母在一起时,底部都是对齐的。
  • baseline 可以为负值,会把基线下调

常见实践

  • 基本都是中英文混用时,可能需要基线对齐

FractionallySizedBox

构造函数

const FractionallySizedBox({super.key,this.alignment = Alignment.center,this.widthFactor,  // 宽因子,父widget宽度*这个指=child的宽度this.heightFactor,  // 高因子,同理super.child,
})
  • 若不设置宽高因子,则对应方向默认填满父widget

示例

Container(color: Colors.blue,height: 150.0,width: 150.0,child: new FractionallySizedBox(alignment: Alignment.center,widthFactor: 1.5,heightFactor: 0.5,child: xxWidget,),
)
  • xxWidget的宽度为1501.5,高度为1500.5

IntrinsicHeight

示例

IntrinsicHeight(child: Row(children: [Container(width: 50,color: Colors.red,),Container(width: 28,height: 50,color: Colors.red,),],),
),

IntrinsicWidth

构造函数

IntrinsicWidth({ super.key, this.stepWidth, this.stepHeight, super.child })
  • 相比IntrinsicHeight多了两个参数:
    • stepWidth:宽度步长
      • 当步长小于子widget宽度时,子widget宽度*步长/10=自身宽度
      • 当步长大于子widget宽度时,自身宽度=步长
    • stepHeight:高度步长(同理)

代码

  • 只展示用步长的,不用步长或者步长=1,和IntrinsicHeight用法一致
IntrinsicWidth(stepWidth: 100,child: Container(color: Colors.blue,child: Center(child: Container(color: Colors.red,width: 50,height: 50,),),),
),

这段代码IntrinsicWidth的宽度就是100

LimitedBox

构造函数

const LimitedBox({super.key,this.maxWidth = double.infinity,this.maxHeight = double.infinity,super.child,
})

代码

  • LimitedBox只有在自身不受约束时才能限制
  • 将child限制在指定的最大宽高中,这样即使child自身没有约束大小,也会有具有外部约束,依然控制其大小
Container(color: Colors.blue,child: UnconstrainedBox(child: LimitedBox(maxWidth: 100,maxHeight: 100,child: Text('啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊'),),),
),

用UnconstrainedBox就是为了让LimitedBox没有外部限制

Offstage

构造函数

Offstage({ super.key, this.offstage = true, super.child })
  • 如果offstage=true,那么Offstage的子child就会处于隐藏状态。这时候子child不会占用任何空间,但实际存在

OverflowBox

构造函数

const OverflowBox({super.key,this.alignment = Alignment.center,this.minWidth,this.maxWidth,this.minHeight,this.maxHeight,super.child,
});
  • minWidth:子控件宽度小于这个值,按这个值显示
  • maxWidth:子控件宽度大于这个值,按这个值显示
  • minHeight:子控件高度小于这个值,按这个值显示
  • maxHeight:子控件高度大于这个值,按这个值显示
  • OverflowBox自己是没有宽高的,他的属性都是对子控件的约束
  • OverflowBox的尺寸是由他的父控件约束来决定的
  • 利用这个能实现超出布局的展示

代码

@override
Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('OverflowBox'),),body: Container(color: Colors.blue,height: 100,child: OverflowBox(alignment: Alignment.topCenter,minWidth: 20,maxWidth: 100,maxHeight: 200,minHeight: 20,child: Container(width: 50,height: 250,color: Colors.red,),),),);
}
  • 如上代码,就会让OverflowBox包裹的Container,超过OverflowBox的父布局Container约束,形成类似Stack的效果。

SizedBox

代码

  • 本身是Container增加宽高的布局
  • 比较多的用于当间隔布局,如下:
Row(children:[Container(),SizedBox(width:100),Container(),]
)

这样两个Container之间就有100间距了

SizedOverflowBox

  • SizedBox与OverflowBox的结合体
  • SizedBox的特性部分:
    • 通过将自身的固定尺寸,传递给child,来达到控制child尺寸
  • OverflowBox的特性部分:
    • 通过设置超出的属性,来决定如何渲染超出的child

构造函数

const SizedOverflowBox({super.key,required this.size,this.alignment = Alignment.center,super.child,
})

代码示例

SizedOverflowBox(size: Size(100.0, 200.0),child: Container(color: Colors.red,width: 200.0,height: 100.0,),
)

Transform

构造函数

const Transform({super.key,required this.transform,this.origin,this.alignment,this.transformHitTests = true,this.filterQuality,super.child,
});

旋转child

  • pi/4就是 180 / 4 = 45 度
Transform.rotate(angle: pi/4,child: const Icon("图片地址",size: 200,color: Colors.blue,),
);

缩放child

  • scale: 0.5就是缩放50%
Transform.scale(scale: 0.5,child: const Icon("图片地址",size: 200,color: Colors.blue,),
);

平移child

  • offset:const Offset(50.0, 0), 就是向右平移50
Transform.translate(offset:const Offset(50.0, 0),child: const Icon("图片地址",size: 200,color: Colors.blue,),
);

CustomSingleChildLayout

  • 灵活实现自己想要的布局以及约束情况
  • 确定 child 的 constrains => 实现getConstraintsForChild
  • 确定 自己的 大小 => 实现getSize
  • 摆放 child => 实现getPositionForChild

构造函数

const CustomSingleChildLayout({super.key,required this.delegate,super.child,
})
  • delegate需要继承SingleChildLayoutDelegate
/// SingleChildLayoutDelegate的定义
abstract class SingleChildLayoutDelegate {const SingleChildLayoutDelegate({ Listenable? relayout }) : _relayout = relayout;final Listenable? _relayout;///获取父容器约束条件,来确定layout的大小Size getSize(BoxConstraints constraints) => constraints.biggest;///确定child的约束BoxConstraints getConstraintsForChild(BoxConstraints constraints) => constraints;///确定child的位置,返回一个相对于parent的偏移值;size是layout的大小,由getSize确定;childSize由getConstraintsForChild得出的Constraints对child进行约束,得到child自身的sizeOffset getPositionForChild(Size size, Size childSize) => Offset.zero;///是否需要relayoutbool shouldRelayout(covariant SingleChildLayoutDelegate oldDelegate);
}

delegate代码

class _MyDelegate extends SingleChildLayoutDelegate {@overrideSize getSize(BoxConstraints constraints) {//用父容器约束条件return super.getSize(constraints);}@overridebool shouldRelayout(covariant SingleChildLayoutDelegate oldDelegate) {//不需要relayoutreturn false;}@overrideBoxConstraints getConstraintsForChild(BoxConstraints constraints) {//child的大小var childWidth = min(constraints.maxWidth, constraints.maxHeight);var childBoxConstraints = BoxConstraints.tight(Size(childWidth / 2, childWidth / 2),);return childBoxConstraints;}@overrideOffset getPositionForChild(Size size, Size childSize) {// 确定child的位置,返回一个相对于parent的偏移值// size由getSize确定// childSize由getConstraintsForChild得出的Constraints对child进行约束,得到child自身的sizevar dx = (size.width - childSize.width) / 2;var dy = (size.height - childSize.height) / 2;return Offset(dx, dy);}
}

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

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

相关文章

Java零基础——vue篇

1.【熟悉】Vue简介 1.1 简介 它是一个构建用户界面的框架 Vue是一个前端框架 js jq https://www.pmdaniu.com/#file UI网站 UI 一般开发者使用蓝湖 工具 看着UI图 写接口 https://lanhuapp.com/web/#/item 是一个轻量级的MVVM(Model-View-ViewModel&#xff0…

统计素数并求和(Python)

题目描述 统计素数并求和 本题要求统计给定整数 M M M 和 N N N 区间内素数的个数并对它们求和。 输入格式: 输入在一行中给出两个正整数 M M M 和 N ( 1 ≤ M ≤ N ≤ 500 ) N(1≤M≤N≤500) N(1≤M≤N≤500)。 输出格式: 在一行中顺序输出 M M M 和 N N N 区间内…

(使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))

使用vite搭建vue3项目(vite vue3 vue router pinia element plus) 初始化项目安装依赖,运行项目初始配置 初始化项目 1.需要在创建项目的位置cmd目录下执行 2. npm init vitelatest 回车 npm init vitelatest3.填上自己的项目名称 回车…

【开源】基于JAVA的厦门旅游电子商务预订系统

项目编号: S 030 ,文末获取源码。 \color{red}{项目编号:S030,文末获取源码。} 项目编号:S030,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 景点类型模块2.2 景点档案模块2.3 酒…

Django的回顾的第4天

1.模型层 1.1简介 你可能已经注意到我们在例子视图中返回文本的方式有点特别。 也就是说&#xff0c;HTML被直接硬编码在 Python代码之中。 def current_datetime(request):now datetime.datetime.now()html "<html><body>It is now %s.</body><…

[网鼎杯 2020 青龙组]singal 1

前言 在主函数中找到了一个vm的译码器&#xff0c;译码器主要是解释传入的opcode&#xff0c;然后对我们输入的字符操作&#xff0c;这里我们发现他是单字节比较的&#xff0c;方法很多可以使用单字节映射&#xff0c;也可以是使用符号化执行&#xff0c;当然也可以硬着头皮去…

17、神经网络的性能以及那些框架存在的意义

前几节,我们介绍了推理和训练的大致过程,以及训练过程中要用损失函数来作为评判预测值和真实值差距的标准。 在很多时候,一个神经网络从开始训练到训练完成是要经过很长的时间的,这是因为模型需要不断的校正自己学习到的参数,直到最终loss值降为0。 如果一轮迭代训练耗时…

canvas基础:渲染文本

canvas实例应用100 专栏提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。 canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重要的帮助。 文章目录 示例…

Postman如何导入和导出接口文件

本文介绍2种导出和导入的操作方法&#xff1a;一种是分享链接&#xff0c;导入链接的方式&#xff08;需要登录&#xff09;&#xff1b;另一种是导出json文件&#xff0c;再次导入。下面将详细介绍。 由于第一种分享链接&#xff0c;导入链接的方式需要登录&#xff0c;所以推…

jsp 分页查询展示,实现按 上一页或下一页实现用ajax刷新内容

要实现按上一页或下一页使用 Ajax 刷新内容&#xff0c;可以按照以下步骤进行操作&#xff1a; 1. 在前端页面中添加两个按钮&#xff0c;分别为“上一页”和“下一页”。当用户点击按钮时&#xff0c;触发 Ajax 请求。 2. 在后端控制器中接收 Ajax 请求&#xff0c;并根据传…

KNN回归-GridSearchCV模型调优(波士顿房价)

数据集简介 数据介绍 波士顿房价数据集(Boston Housing Dataset) 是一个经典的用于回归分析的数据集。它包含了波士顿地区506个街区的房价信息以及与房价相关的13个特征。这个数据集的目标是根据这些特征来预测波士顿地区房屋的中位数价格(以千美元为单位) 数据说明 Data S…

Vue 3.0 组合式API 生命周期钩子

文章目录 前言配置项api图表on配置项api后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;vue.js &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错误&#xff0…

微软 Power Platform 零基础 Power Pages 网页搭建教程学习实践进阶以及常见问题解答(二)

微软 Power Platform 零基础 Power Pages 网页搭建教程学习实践进阶及常见问题解答&#xff08;二&#xff09; Power Pages 学习实践进阶 微软 Power Platform 零基础 Power Pages 网页搭建教程学习实践进阶及常见问题解答&#xff08;二&#xff09;Power Pages 核心工具和组…

Openwrt 系统安装 插件名称与中文释义

系统镜像 当时是去官网找对应的&#xff0c;但是作为门外汉&#xff0c;想简单&#xff0c;可以试试这个网站 插件 OpenWrt/Lede全部插件列表功能注释

【AUTOSAR】【通信栈】IPduM

AUTOSAR专栏——总目录_嵌入式知行合一的博客-CSDN博客文章浏览阅读310次。本文主要汇总该专栏文章,以方便各位读者阅读。https://xianfan.blog.csdn.net/article/details/132072415 目录 一、概述 二、相关模块 2.1 OS

Java实现获取文件MD5值工具类

我们在工作中通常使用MD5对文件进行校验完整性&#xff0c;比较&#xff0c;提高安全性等&#xff0c;一般MD5有以下几种作用 1.数据完整性验证&#xff1a;MD5值是通过对文件的内容计算生成的固定长度哈希值。如果文件内容发生任何变化&#xff0c;其MD5值也会发生变化。因此…

2023年第十二届数学建模国际赛小美赛B题工业表面缺陷检测求解分析

2023年第十二届数学建模国际赛小美赛 B题 工业表面缺陷检测 原题再现&#xff1a; 金属或塑料制品的表面缺陷不仅影响产品的外观&#xff0c;还可能对产品的性能或耐久性造成严重损害。自动表面异常检测已经成为一个有趣而有前景的研究领域&#xff0c;对视觉检测的应用领域有…

成倍提高生产力工具Notion

成倍提高生产力工具Notion Notion已经成为了很多内容创作者的唯一生产力工具&#xff0c;甚至很多企业已经把Notion当作他们的唯一的工作平台&#xff0c;学习这款软件不仅能提高你的工作效率甚至在职场上也会成为一个吃香的技能&#xff0c;在美国有人制作销售Notion模板&…

【openGauss】如何通过pg_trigger.tgtype获取触发器的各种触发条件

前言 最近有客户反馈兼容的dba_triggers视图中&#xff0c;同一个触发器的trigger_event被拆成了多行&#xff0c;和ORACLE中表现不一致&#xff0c;于是我进行了一些分析&#xff0c;发现是在其引用的information_schema.triggers视图中就已经拆开成了INSERT/DELETE/UPDATE&a…

人工智能基础创新的第二增长曲线

编者按&#xff1a;2023年是微软亚洲研究院建院25周年。借此机会&#xff0c;我们特别策划了“智启未来”系列文章&#xff0c;邀请到微软亚洲研究院不同研究领域的领军人物&#xff0c;以署名文章的形式分享他们对人工智能、计算机及其交叉学科领域的观点洞察及前沿展望。希望…