hi好久不见~消失的这半年做了件大事,生了个兔宝宝🐰产假回来之后发现项目组又启动了一个新项目,这次做的网页,基于Nuxt3开发的,于是开始了学习前端知识。这一路从Android单端、到Flutter跨平台、再到现在Web,有种在大前端升级打怪的感觉。当然了,由于接触不深加上着急上手,第一步往往先做UI,本篇总结在Android、Flutter、Vue上最常用几种布局在实现上的区别,方便有客户端经验的开发更快理解和实践Web项目。
通用
在Web中使用CSS(Cascading Style Sheets,层叠样式表)来描述样式,在Android 中使用的是XML(Extensible Markup Language,可扩展标记语言),目的都是将把数据与样式分开。而Flutter使用一种称为Widget的组件系统来构建 UI,每个Widget都有自己的属性,创建时传入相应参数就能设置样式了。常见通用属性如间距、颜色、文本这些命名都是相似的,就不详细说明了,对照表如下:
| 属性 | Android | Flutter | Vue |
|---|---|---|---|
| 宽度 | android:layout_width |
width(组件Container 、 SizedBox) |
width |
| 高度 | android:layout_height |
height(组件Container 、 SizedBox) |
height |
| 外间距 | android:layout_margin |
margin(组件 Container 、 Padding) |
margin |
| 内间距 | android:padding |
padding(组件 Container 、 Padding) |
padding |
| 文本颜色 | android:textColor |
color(组件 Text) |
color |
| 背景颜色 | android:background |
color(组件 Container) |
background-color |
| 文本大小 | android:textSize |
fontSize(组件TextStyle) |
font-size |
| 文本粗细 | android:textStyle |
fontWeight(组件TextStyle) |
font-weight |
| 文本样式 | android:textStyle |
fontStyle(组件TextStyle) |
font-style |
相对布局
实现在容器中距顶部100距左侧50:

1、Android
- 使用
RelativeLayout或FrameLayout实现 - 可通过margin移动子控件
- 在
RelativeLayout还提供两类参考系帮助更快速定位——相对于父容器、相对其他兄弟控件,比如是否在父容器最底部(android:layout_alignParentBottom)、在父容器垂直居中(android:layout_centerVertical)、在某个控件下方(android:layout_below)、与某个控件顶部对齐(android:layout_alignTop)等
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"
android:layout_marginTop="100dp"
android:layout_marginLeft="50dp" />
</RelativeLayout>
2、Flutter
- 使用
Stack和Positioned一起实现 -
Stack表示这是一个可堆叠子组件的容器,其中的alignment属性可以用来控制未定位或部分定位的子组件的对齐方式 -
Positioned用来给子组件指定具体的位置,包括top、right、bottom和left,它只能作为Stack的直接子组件使用
Stack(
alignment: Alignment.center,
children: [
Positioned(
top: 100,
left: 50,
child: Text('A'),
),
],
)
3、Vue
- 使用
position属性来实现 - 同样的通过
top、right、bottom和left来定位 - 当
position设置为relative时元素会相对于其原始位置进行移动 - 当
position设置为absolute时元素会相对于其最近一个定位的父元素进行移动
<div style="position: relative; height: 200px; width: 200px;">
<div style="position: absolute; top: 100px; left: 50px;">A</div>
</div>
线性布局
实现三个控件水平排布,最后一个靠右,第二个元素分配剩余空间,整体在容器中垂直居中:

1、Android
- 使用
Linerlayout实现,默认horizontal -
android:orientation表示子控件的排布方向,值horizontal/vertical -
android:gravity表示子控件的对齐方式,默认start -
android:layout_weight表示子控件对剩余空间的占用比例,默认0
<LinearLayout
android:layout_width="200dp"
android:layout_height="50dp"
android:orientation="horizontal"
android:gravity="center_vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="B"
android:maxLines="1"
android:ellipsize="end"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="C"/>
</LinearLayout>
- 文本超过一行打点:
android:maxLines="1"
android:ellipsize="end"
2、Flutter
- 使用
Row(水平排列)或Column(垂直排列)实现 -
Expanded表示一个在主轴方向上撑满剩余空间的组件,只能作为Row或Column子节点 -
mainAxisAlignment表示主轴方向上的对齐方式,默认start -
crossAxisAlignment表示副轴方向上的对齐方式,默认center
Container(
width: 200,
height: 50,
child: Row(
children: [
Text("A"),
Expanded(
child: Text(
"B",
maxLines: 1,
overflow: overflow: TextOverflow.ellipsis,
),
),
Text("C"),
],
],
),
),
- 文本超过一行打点:
maxLines: 1,
overflow: TextOverflow.ellipsis,
3、Vue
- 通过
display: flex实现,默认row -
flex-direction表示子元素的排布方向,值row/column -
justify-content表示主轴方向上的对齐方式,默认start -
align-items表示副轴方向上的对齐方式,默认start -
flex-grow表示子元素对剩余空间的占用比例,默认0 -
flex-shrink表示子元素在控件不足时的缩小比例,默认1
<div style="display: flex; align-items:center; height: 50px; width: 200px" >
<span>A</span>
<span style="flex-grow: 1; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden;">B</span>
<span>C</span>
</div>
- 文本超过一行打点:
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;