阅读 794

【Flutter 基础】 视图布局-前言

这是我参与更文挑战的第4天,活动详情查看: 更文挑战

注:本文从个人公众号(岛前屿端)中迁移重新发布

Flutter 是谷歌的移动 UI 框架,可以从单个代码库快速的为移动端(iOS & Android)、Web、桌面端、嵌入式设备上构建高质量的原生用户界面和应用程序。


在学习 Flutter 的过程中也看到一些人对于 Flutter 的议论。他们大多觉得 Flutter 不够友好、括号太多了,导致看起来代码非常复杂,对此嗤之以鼻并以唱衰之

当然也有一些人认为,不再以 xml 的方式实现结构布局且以代码逻辑来驱动和构建布局的方式对于一些审美感不高的人是一种乐于接受的方式。

所谓江湖纷杂,流派众多,也是各花入各眼。孰对孰错并无绝对之说。

而我的看法则是较为中立,应该是各取一半吧:

以代码驱动构建布局确实是可以省下对于布局的搔首挠耳之苦,但对于较为复杂的结构代码驱动的形式就显得没那么游刃有余了。当然在一些特性上相对传统确实是较为便捷不可否认。

这段时间学习以来,看过一些大侠们的作品,功力不一般。大多为独立实现的作品,让我看了煞是羡慕。

不过说来惭愧我也学了一月有余,对于 Flutter 的整体认识程度还不是很高,还不能很全面的去讲解整个 Flutter 的体系。但我能做到的是将我在学习过程中我遇到的问题、踩到的坑、理解上的问题解决完后,再重新整理输出出来,以便有需要或有兴趣学的少侠们提供帮助参考。

Ok,以上就是我瞎逼逼的废话了。那么接下来就来看一看 Flutter 的视图布局吧。

视图的布局方式

简单说一下我对 Flutter 视图布局的看法,在前篇中我有提到 Flutter 是使用了 Dart 语言进行编写,所以弱化了视图编辑的部分。视图的渲染、结构、布局都通过代码逻辑来生成。

这在一定程度上在视图结构和逻辑的关联性是强了,但在直观布局结构方面却弱了,所以就导致在代码中会发现嵌套层次很多很深,同时也会对开发者的能力有了一些要求,当然如果有面向对象编程的经验的话,那么就上手来说问题并不大。

在 Flutter 中主要的布局方式有两种:

  • 多子类元素布局
  • 单子类元素布局

还有一个比较特殊的 LayoutBuilder,这个主要是构建一个可以依赖父窗口大小的 Widget 树

此外在官方文档术语描述中将 2 个 Widget 嵌套关系为 Widget 下的子 Widget,这不便于一些已经学过 html 或 xml 的少侠们理解,故在此约定:

约定:在接下来的 《Flutter 视图布局》系列文章中我将 widget 下的第一级 widget 称之为 “子元素” 以便让少侠们理解。

多子类元素布局

即,该 Widget 下允许存在多个子 Widget 元素。

多子类元素布局的 Widget 有 10 种

  • Row 在水平方向上排列子 Widget 元素的列表。
  • Column 在垂直方向上排列子 Widget 元素的列表。
  • ListBody 一个 Widget,它沿着一个给定的轴,顺序排列它的子 Widget 元素。
  • ListView 可滚动的列表控件。ListView 是最常用的滚动 Widget,它在滚动方向上一个接一个地显示它的子 Widget 元素。在纵轴上,子元素们被要求填充ListView。
  • Table 为其子 Widget 元素使用表格布局算法的 Widget。
  • Wrap 可以在水平或垂直方向多行显示其子 Widget 元素。
  • Flow 一个可以实现流式布局算法的 Widget。
  • Stack 可以允许其子 Widget 元素简单的堆叠在一起。
  • IndexedStack 从一个子 Widget 元素列表中显示单个子 Widget 元素的 Stack。
  • CustomMultiChildLayout 使用一个委托来对多个子 Widget 元素进行设置大小和定位的小部件。

每一种 Widget 所实现的布局方式都不一样,都有一个主要的实现场景,以及对子 Widget 元素的展示方式

单子类元素布局

即,该 Widget 下只允许存在一个子 Widget 元素。

单子类元素布局的 Widget 有 18 种

  • Container 一个拥有绘制、定位、调整大小的 Widget。
  • Padding 可以将其子 Widget 元素添加填充指定的空间的 Widget。
  • Center 将其子 Widget 元素居中显示在自身内部的 Widget。
  • Align 一个 Widget,它可以将其子 Widget 元素对齐,并可以根据子 Widget 元素的大小自动调整大小。
  • Baseline 根据子 Widget 元素的基线对它们的位置进行定位的 Widget。
  • IntrinsicWidth 一个 Widget,它将它的子 Widget 元素的宽度调整其本身实际的宽度。
  • IntrinsicHeight 一个 Widget,它将它的子 Widget 元素的高度调整其本身实际的高度。
  • AspectRatio 一个 Widget,试图将子 Widget 元素的大小指定为某个特定的长宽比。
  • Transform 在绘制子 Widget 元素之前应用变换效果的 Widget。
  • Offstage 一个布局 Widget,可以控制其子 Widget 元素的显示和隐藏。
  • ConstrainedBox 对其子 Widget 元素施加附加约束的 Widget。
  • FittedBox 按自己的大小调整其子 Widget 元素的大小和位置。
  • LimitedBox 一个当其自身不受约束时才限制其大小的盒子。
  • OverflowBox 对其子 Widget 元素施加不同约束的 Widget,它可能允许子 Widget 元素溢出父级。
  • SizedBox 一个特定大小的盒子。这个 Widget 强制它的子 Widget 有一个特定的宽度和高度。如果宽度或高度为NULL,则此 Widget 将调整自身大小以匹配该维度中的子 Widget 的大小。
  • SizedOverflowBox 一个特定大小的 Widget,但是会将它的原始约束传递给它的子 Widget,它可能会溢出。
  • FractionallySizedBox 一个 Widget,它把它的子 Widget 元素放在可用空间的一小部分。关于布局算法的更多细节,见 RenderFractionallySizedOverflowBox。
  • CustomSingleChildLayout 一个自定义的拥有单个子元素的布局 Widget。

每一种 Widget 都会影响其子元素最终的视图显示效果,如大小、位置、边框、背景等

布局分篇

由于 Widget 布局的种类多达 28 + 1 种,单篇文章中无法将其一一列举说完,所以我打算将其分为多篇文章来对其进行说明。

关于单子类元素布局的 Widget,因部分只会在特定的需求场景中使用,所以这部分我可能不会太深入细说。

在整理之后,我考虑将其按如下分篇:

多子类元素布局

  • Row、Column(一)
  • ListBody、ListView(二)
  • Table、Wrap、Flow(三)
  • Stack、IndexedStack(四)

单子类元素布局

  • Container、Padding、Center、Align、Baseline(一)
  • IntrinsicWidth、IntrinsicHeight、AspectRatio (二)
  • Transform、Offstage(三)
  • ConstrainedBox、FittedBox、LimitedBox、OverflowBox (四)
  • SizedBox、SizedOverflowBox、FractionallySizedBox(五)

由于 CustomMultiChildLayout、CustomSingleChildLayout 较为相似,我将它们与 LayoutBuilder 放在一起。

此外我还考虑为了方便各位少侠小伙伴们更直观的学习和参考,我还将 Flutter 系列的 MyApp 项目同步到了 Github 上,以后如有文章更新都会将文章内的代码同步更新到 Github 的项目里。让有需要的小伙伴可以 clone 下来学习

当然,在代码中我尽量写了足够详细的注释,也是希望让少侠 & 小伙伴们不要去猜代码,这没有意义,而是要看懂这是怎么回事,然后再去尝试修改代码运行得到结果。


Github

Github 地址:github.com/linxsbox/my…

文章分类
前端
文章标签