Flutter的盒子约束
由Expanded widget引发的思考
设计稿如下

布局widget分解

很常见的一种布局方式:Column的子widget中包含ListView
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
ListView.builder(
itemCount: 30,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text("标题$index"),
);
},
),
],
);
}
当然这样仅仅这样写,在手机屏幕上会看到一片空白,如果是debug模式,则会在控制台中看到如下报错
════════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: RenderRepaintBoundary#e7255 relayoutBoundary=up2 NEEDS-PAINT
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1687 pos 12: 'hasSize'
The relevant error-causing widget was
Column
从报错信息可以得知是Column widget出错了,RenderBox未正确布局等等。
正确的写法
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Expanded(
child: ListView.builder(
itemCount: 30,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text("标题$index"),
);
},
),
),
],
);
}
在ListView外层嵌套一个Expanded widget
Expanded widget作用是给子 widget 分配剩余的空间,也就是只要给ListView指定高度即可。当然也就可以在ListView外层嵌套一个限定高度的Container widget。
Flutter盒子
In Flutter, widgets are rendered by their underlying RenderBox objects. Render boxes are given constraints by their parent, and size themselves within those constraints. Constraints consist of minimum and maximum widths and heights; sizes consist of a specific width and height.
Generally, there are three kinds of boxes, in terms of how they handle their constraints:
- Those that try to be as big as possible. For example, the boxes used by Center and ListView.
- Those that try to be the same size as their children. For example, the boxes used by Transform and Opacity
- Those that try to be a particular size. For example, the boxes used by Image and Text.
这是Flutter官网关于flutter 盒子约束的一段话。在Flutter中,widget由其底层的RenderBox对象渲染。 渲染框由它们的父级给出约束,并且在这些约束下调整自身大小。约束由最小宽高、最大宽高组成(这里是我个人看法,Flutter中文网翻译是,约束由最小宽度、最大宽度和高度组成 ); 尺寸由特定的宽度和高度组成。
按照宽高约束条件来划分,flutter 盒子有三类:
- 无限制边界(在某一个方向,比如纵向滚动那么宽度就是受限制的而高度无边界,并不是宽高都任意大),例如Center和ListView widget
- 由子widget的宽高决定了自己的边界,如 Transform 和 Opacity
- 有确定的宽高大小,如 Image和Text widget
而下面这句话就刚好解释了上面那个报错
A box that tries to be as big as possible won’t function usefully when given an unbounded constraint and, in debug mode, such a combination throws an exception that points to this file.
The most common cases where a render box finds itself with unbounded constraints are within flex boxes (
RowandColumn), and within scrollable regions (ListViewand otherScrollViewsubclasses).
上面那个例子中,Column在纵向上面是无限制的,而ListView在其滚动方向上也是无限制。而上面这句话也解释了,一个本身试图占用尽可能大的渲染盒在给定无边界约束时不会有用,在debug模式下,会抛出异常
所以当我们给ListView外层嵌套了Expanded或者限高的Container,避免了一个不限制高度的widget直接被嵌套于另外一个不限高的widget中,在VSCode终端直接运行flutter run 控制台是没有任何打印信息,只有在debug模式下,控制台会打印异常。
总结
开发中使用debug模式,不仅可以断点调试,更能在控制台看到异常信息。技术都有一定的共通性,虽然flutter一切基于widget,但是在盒子的宽高方面也如同CSS ,可以继承自父类,也可以自定义宽高,或者由子类宽高撑起来。
参考文档
https://flutter.dev/docs/development/ui/layout/box-constraints
https://flutterchina.club/layout/
Flutter的盒子约束的更多相关文章
- flutter 修饰盒子
decoration: BoxDecoration( borderRadius: BorderRadius.circular(), //圆角 gradient: RadialGradient( col ...
- 前端笔记之移动端&响应式(中)视口&百分比布局&弹性盒模型&rem&fillpage
一.viewport视口 1.1什么是屏幕尺寸.屏幕分辨率.屏幕像素密度? 屏幕尺寸:指屏幕的对角线的长度,单位是英寸,常见的屏幕尺寸有3.5.3.7.4.2.4.7.5.0.5.5.6.0等. 屏幕 ...
- 前端笔记之React(八)上传&图片裁切
一.上传 formidable天生可以处理上传的文件,非常简单就能持久上传的文件. 今天主要讲解的是,前后端的配合套路. 上传分为同步.异步.同步公司使用非常多,异步我们也会讲解. 1.1 先看一下a ...
- css基础04
所有浮动都是贴着浮动的.一左一右的话就毫无联系了. 浮动元素和标准流是两个级别了,浮起来了,后面的人会补上空缺的位置,让其他标准流的盒子占有. 很容易形成叠加效果,(蓝色的标准流会上去补上浮动的位置, ...
- 20个Flutter实例视频教程-第07节: 毛玻璃效果制作
视频地址: https://www.bilibili.com/video/av39709290/?p=7 博客地址: https://jspang.com/post/flutterDemo.html# ...
- Flutter学习笔记(22)--单个子元素的布局Widget(Container、Padding、Center、Align、FittedBox、Offstage、LimitedBox、OverflowBox、SizedBox)
如需转载,请注明出处:Flutter学习笔记(22)--单个子元素的布局Widget(Container.Padding.Center.Align.FittedBox.Offstage.Limited ...
- Flutter磨砂玻璃效果制作
Flutter的Fliter Widget 也是非常强大的,它可以制作出你想要的神奇滤镜效果.下面制作一个毛玻璃效果. 这个和以前的写法都一样,所以就直接贴代码了. import 'package:f ...
- Flutter的布局方法
重点是什么? Widgets 是用于构建UI的类. Widgets 用于布局和UI元素. 通过简单的widget来构建复杂的widget Flutter布局机制的核心就是widget.在Flutter ...
- 【Flutter学习】页面布局之宽高尺寸处理
一,概述 Flutter中拥有30多种预定义的布局widget,常用的有Container.Padding.Center.Flex.Row.Colum.ListView.GridView.按照< ...
随机推荐
- 概率DP——BZOJ4008 [HNOI2015]亚瑟王
[HNOI2015]亚瑟王 Description 小 K 不慎被 LL 邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑.他决定,在脱坑之前,最后再来打一盘亚瑟王.既然是最后一战,就一定要打得漂 ...
- django Field选项中null和blank的区别
blank只是在填写表单的时候可以为空,而在数据库上存储的是一个空字符串:null是在数据库上表现NULL,而不是一个空字符串: 需要注意的是,日期型(DateField.TimeField.Date ...
- 微信小游戏排行榜页滚动查看排行榜(canvas指定区域溢出滚动,懒渲染)
在微信小游戏中,好友排名数据是能在关系数据域操作,整个关系数据域只会返回一个最终的sharedCanvas,并且这个canvas不能调用toDataURL()方法,所以要展示好友排行榜的话只能在关系数 ...
- 对H5新增多线程的理解与简单使用
由于JavaScript的特性决定了JavaScript语言是一种单线程语言,但是有时候我们需要使用多线程比如进行大量的计算时.H5为此新增了多线程的方法. 在这里我是用JavaScript来实现著名 ...
- js寄生组合式继承
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- js 网页运行原理
当我们打开一个网页的时候,浏览器会首先创建一个窗口,这个窗口就是我所知道的window对象,也就是整个Javascript运行所依附的全局变量. 为了加载网页文档,当前窗口又需要创建一个Documen ...
- python socket粘包及实例
1.在linux中经常出现粘包的出现(因为两个send近靠着,造成接受到的数据是在一起的.)解决方法: 在服务端两send的中间中再添加一个recv(),客户端添加一个send(),服务端收到信息确认 ...
- 初识Mybatis之工程搭建
简介:MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 ...
- 多个计数器在Vuex中的状态
安装 安装vue-cli npm i -g vue-cli 生成目录 vue init webpack 启动开发环境 npm run dev 启动命令 npm install -g vue-cli v ...
- 下一个风口?迷你KTV能变成“绿巨人”吗
近段时间,在全国各地多个商场.大学城等繁华地点,一种全新娱乐方式--迷你KTV变得火爆起来.这种仅能容纳两三人,以单首.时段等进行计费,且价格不低的点唱新模式,正成为投资者眼中的"新宠&qu ...