1、常用布局的对比
为澄江等地区用户提供了全套网页设计制作服务,及澄江网站建设行业解决方案。主营业务为成都网站设计、网站建设、澄江网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
使用下来其他组件大致还算方便,但是相对布局而言使用便利程度上Android原生完胜,ConstraintLayout内部的所有子View可以设置互相之间的位置依赖关系。
而Flutter的Stack组件内部的Children只能通过外层包裹 Align后 固定位置,比如 Alignment.topLeft、Alignment.bottomRight 等。遇到复杂的堆叠布局需要通过外层包裹 Positioned 组件后设置固定的 top 和 left 距离以达到效果,内部子组件之间无法设置位置关联关系。
2、一些常用属性设置上的差异:
Margin外边距
Android:直接在布局文件对View设置android:layout_marginStart、android:layout_marginTop
Flutter:需嵌套 Container 组件并在内部设置具体的 margin 值
Padding内边距
Android:TextView、ImageView、各种Layout都可以直接在属性上设置android:paddingStart
Flutter:需嵌套 Padding 组件并在内部设置具体的值
组件的可见性
Android:每个view都可以通过setVisibility来设置可见、隐藏或者隐藏但占位
Flutter:没有单独设置组件是否显示的api,只能通过 bool 值控制是否添加该组件
事件监听
Android:常规的setOnClickListener和setOnLongClickListener设置单击和长按事件
Flutter:在需要添加事件监听的组件外层嵌套 InkWell 或 GestureDetector 并设置 onTap 等
3、生命周期
Android:
Activity和Fragment各自有完整的生命周期链路onCreate、onStart、onResume、onPause、onDestroy等
Flutter:
万物皆组件,组件继承 WidgetsBindingObserver 并重写 didChangeAppLifecycleState 函数进行监听
退回桌面依次执行inactive 》= paused,此时界面不可见用户不可操作,从桌面重新进入app执行resumed,状态较少如需在某些条件下触发特定操作可能要找别的方案,比如发通知之类的
Stack 组件是一种层叠式布局,即组件覆盖另一个组件,覆盖的顺序取决于在children中放置的顺序,使用场景比如在图片上加上一些文字描述,即将文本Widget覆盖在图片组件,详见下面的小例。
Stack 是可以将视图根据children中子组件的顺序进行叠加的组件,根据子组件是否被Positioned包裹判断布局的方式
Stack 的fit 属性用来控制Stack如何将自己的父级组件的尺寸约束传达给无位置组件,通过fit属性约束Stack中无位置组件的尺寸,默认值是 StackFie.loose. 如:Stack的父级组件要求Stack的尺寸是 200x200 ~ 500x500.在默认的StackFit.loose(宽松状态)下,Stack 可以运行其children在不违反父级约束的前提下,自由选择尺寸,即可在0x0~500x500的范围内任意选择。相反如何传入的fit是StackFit.expand(扩张状态)下,则会要求所有无位置children必须占满父级约束的最大空间,即尺寸必须为500x500,最后当传入的StackFit.passthrough(穿透状态)时,Stack会将自己父级组件的尺寸约束直接传递给子组件,即保留原有的200x200 ~ 500x500的约束。
StackFie.loose 和StackFit.passthrough的效果
StackFit.expand的效果
表格布局和线性布局比较相似,只是使用起来更简洁一些。
本地Flutter 2.10.1,Mac版Android Studio Bumblebee | 2021.1.1 Patch 2
我是小栗子,初学Flutter ,文章会根据学习进度不定时更新,请多多指教~~
在Material的设计准则里面,tabs是一个常用的模块。Flutter里面包含了 material library 创建tab布局的简便方法
为了使tab起作用,我们需要保持选中的tab和相关内容同步。这就是 TabController 的职责。
我们可以手动创建 TabController ,也可以使用 DefaultTabController 小部件。使用 DefaultTabController 是最简单的选项,因为它将为我们创建一个 TabController ,并使它可用于所有子类Widget。
现在我们已经有个一个 TabController ,我们可以 TabBar Widget去使用创建我们的tab。在这个示例中,我们将会在一个 AppBar 下.创建一个包含3个 Tab Widgets 的 TabBar 。
默认情况下, TabBar 在Widget树中查找最近的 DefaultTabController 。如果是手动创建的 TabController ,则需要将其传递到“TabBar”。
既然我们有了选项卡,那么我们就需要在选择选项卡时显示相关的内容。因此,我们将使用 TabBarView Widget.
备注: 顺序很重要,必须与 TabBar 中的选项卡的顺序相对应!
1. Flutter初步探索(二)使用Tabs
1. Working with Tabs
相对于iOS开发,Flutter的布局更具有灵活性,每个页面设计都不一样,相同页面可选择的布局方式也不一样,如果单纯的说应该如何去布局,我觉得不现实,大家可以参考下 Flutter官方的布局教程 。接下来,笔者,通过项目中的一个页面,来一步一步的拆解布局的流程。整个过程,基本上按照拆解、组件封装、具体布局这三步来的。
根据设计图,可以看出整体可以分成两部分,上面一部分是系统介绍模块,下面一部分是真正的登录内容,因为涉及到叠加,因此考虑用Stack;
系统介绍模块部分:整体也是涉及到叠加,考虑用Stack,分为四部分。最底部渐变色背景用一个contanier,无须指定位置,全视图扩展;载放logo图标在上一层,用Image。最后两个Text同级放在最上层。Image,Text各用Positioned包裹去指定位置。
登录内容模块是最外层是一个Contanier容器,去控制背景色和圆角。然后是一个Column元素,逐行排列。
第一行为Image,
第二行为Text,
第三行可以看成一个小Column,分两块进行布局
第四行可以看成一个小Column,分两块进行布局
第五行可以看作一个TextButton,
第六行可以看作一个Row,分三块进行布局
通过上面这样一步一步的分析后,基本上对大致的布局有了一个了解,最外层的控件大致选对(只要能实现的话,就是复杂度以及效率的问题),然后一步一步的拆解每一行的元素,如果有重复的或者觉得可以封装出来的部分,则进行下一步。
每一行的拆解,大致也是按照这个思路来进行,因此笔者在这里就不做讲解了。
在做到第三第四行的时候,发现这两个很相似,而且设计到一些交互逻辑,笔者就想对第三第四行的这种展示进行封装,觉得今后的布局可能会用到,因此在这一步,可以先把这一块儿抽离出一个控件。利用TextField来实现这种输入操作,具体的实现笔者不再详细的描述了。
经过这一步,整体的规划设计图已经有了,各个组件也都有了,接下来的工作就是组装了。
具体布局设计到一些细节的地方,例如整体Column的居中对齐(crossAxisAlignment)、间隔(Padding或Container包裹,笔者更喜欢用SizedBox占位)、居左居右居中(Align)、点击事件(GestureDetector)以及圆角(BorderRadius)等一些特殊情况。
像第六行row是放在底部的,就可以在第六行前面增加一个Spacer()去填充空白区域。
对文字颜色大小等,可以用TextStyle直接设置。
对于输入框的删除按钮,可以用Offstage这种Flutter特有的控制显示隐藏的控件。