-
Notifications
You must be signed in to change notification settings - Fork 208
ArgoUI布局
ArgoUI新布局以flex box 为基础,结合了线性布局、SwiftUI布局里的优秀特性。让开发人员可以用更简洁扁平的方式布局UI。
分为以下几种布局,下面将通过demo示例逐步讲解。
我们将用新布局来完成一个简单的入门demo。效果图如下:
HStack
是横向线性布局,对于它而言,主轴即指水平方向,交叉轴指竖直方向。
如设置widthPercent(100)
来实现宽度占满。
mLabel(str, bgColor) {
Label(str)
.textColor(Color(255, 255, 255, 0.8))
.padding(3, 5, 3, 5)
.bgColor(bgColor)
.fontSize(10)
}
---
--- UI
ui {
--- layout views
HStack()
.widthPercent(100)
.bgColor(Color(220, 230, 200, 1))
.subs(
mLabel("0元配送", Color(100, 100, 200, 0.8))
,
mLabel("支持自取", Color(100, 120, 200, 0.8))
,
mLabel("食无忧", Color(140, 120, 200, 0.8))
,
mLabel("津贴2元", Color(180, 150, 100, 0.8))
,
mLabel("会员专享", Color(180, 100, 100, 0.8))
,
mLabel("首单立减", Color(150, 60, 100, 0.8))
)
}
---
--- preview
local function preview()
end
主轴默认是MainAxis.START
向起始方向对齐。
--demo1
mLabel(str, bgColor) {
Label(str)
.textColor(Color(255, 255, 255, 0.8))
.padding(3, 5, 3, 5)
.bgColor(bgColor)
.fontSize(10)
}
---
--- UI
ui {
--- layout views
HStack()
.mainAxis(MainAxis.START)
.widthPercent(100)
.bgColor(Color(220, 230, 200, 1))
.subs(
mLabel("0元配送", Color(100, 100, 200, 0.8))
,
mLabel("支持自取", Color(100, 120, 200, 0.8))
,
mLabel("食无忧", Color(140, 120, 200, 0.8))
,
mLabel("津贴2元", Color(180, 150, 100, 0.8))
,
mLabel("会员专享", Color(180, 100, 100, 0.8))
,
mLabel("首单立减", Color(150, 60, 100, 0.8))
)
}
---
--- preview
local function preview()
end
MainAxis.CENTER
向中心对齐。将demo1中MainAxis枚举值改为CENTER,ui显示如下
MainAxis.END
向结束方向对齐。将demo1中MainAxis枚举值改为END,ui显示如下
MainAxis.SPACE_BETWEEN
空闲区域在子view之间,等间距分布space,头尾不占space。
MainAxis.SPACE_AROUND
空闲区域在子view之间,等间距分布space,头尾各占1/2space。
MainAxis.SPACE_EVENLY
空闲区域在子view之间,等间距分布space,头尾各占1space。
3. 未设置自动换行时,通过crossAxis(int crossAxis)
设置子view在交叉轴方向的对齐方式。当子View的高度小于HStack的高度时才有意义。参数是CrossAxis枚举类型。
我们为HStack设置一个固定高度,来观察CrossAxis的枚举效果。
交叉轴默认是CrossAxis.START
向起始方向对齐。
mLabel(str, bgColor) {
Label(str)
.textColor(Color(255, 255, 255, 0.8))
.padding(3, 5, 3, 5)
.bgColor(bgColor)
.fontSize(10)
}
---
--- UI
ui {
--- layout views
HStack().height(50)
.crossAxis(CrossAxis.START)
.mainAxis(MainAxis.SPACE_EVENLY)
.widthPercent(100)
.bgColor(Color(220, 230, 200, 1))
.subs(
mLabel("0元配送", Color(100, 100, 200, 0.8))
,
mLabel("支持自取", Color(100, 120, 200, 0.8))
,
mLabel("食无忧", Color(140, 120, 200, 0.8))
,
mLabel("津贴2元", Color(180, 150, 100, 0.8))
,
mLabel("会员专享", Color(180, 100, 100, 0.8))
,
mLabel("首单立减", Color(150, 60, 100, 0.8))
)
}
---
--- preview
local function preview()
end
CrossAxis.CENTER
向中心对齐。
CrossAxis.END
向结束方向对齐。
CrossAxis.STRETCH
交叉轴上拉伸。注意:子view未设置高度时才会拉伸。
CrossAxis.BASELINE
沿基线对齐。为demo中子view设置不同的高度,ui显示如下:
CrossAxis.SPACE_BETWEEN
交叉轴方向上空闲区域在子view之间,等间距分布space,头尾不占space。
设置HStack多行,观察枚举效果(具体实现会在Wrap中介绍到)。
HStack()
.wrap(Wrap.WRAP)
.crossContent(CrossAxis.SPACE_BETWEEN)
CrossAxis.SPACE_AROUND
交叉轴方向上空闲区域在子view之间,等间距分布space,头尾各占1/2space。
HStack()
.wrap(Wrap.WRAP)
.crossContent(CrossAxis.SPACE_AROUND)
默认Wrap.NO_WRAP
不换行。
--wrap_demo
mLayout(str, imgBool) {
HStack()
.padding(0, 5, 0, 5)
.bgColor(Color(220, 220, 220, 0.5))
.cornerRadius(5)
.height(28)
.crossAxis(CrossAxis.CENTER)
.left(3)
.right(3)
.top(3)
.bottom(3)
.subs(
ImageView()
.width(18)
.height(18)
.image("https://s.momocdn.com/w/u/others/custom/MLNUI/icon.png")
.bind(function()
if imgBool then
self.display(true)
else
self.display(false)
end
end)
,
Label(str)
.fontSize(12)
)
}
---
--- UI
ui {
--- layout views
HStack()
.height(100)
.bgColor(Color(220, 230, 200, 0.2))
.wrap(Wrap.NO_WRAP)
.subs(
mLayout("汉堡", true)
,
mLayout("龙虾饭", true)
,
mLayout("番茄米线", false)
,
mLayout("健康蔬菜沙拉", true)
,
mLayout("车厘子优选", true)
,
mLayout("藤椒麻辣香锅", false)
)
}
---
--- preview
function preview()
end
设置wrap(Wrap.NO_WRAP)
后,我们分别设置crossAxis(CrossAxis.CENTER)
、crossContent(CrossAxis.CENTER)
:
--未设置自动换行时,设置crossAxis有效
HStack()
.wrap(Wrap.NO_WRAP)
.crossAxis(CrossAxis.CENTER)
--未设置自动换行时,设置crossContent无效
HStack()
.wrap(Wrap.NO_WRAP)
.crossContent(CrossAxis.CENTER)
Wrap.WRAP
自动换行。
--设置自动换行时,设置crossAxis无效
HStack()
.wrap(Wrap.WRAP)
.crossAxis(CrossAxis.CENTER)
--设置自动换行时,设置crossContent有效
HStack().wrap(Wrap.WRAP)
.crossContent(CrossAxis.CENTER)
Wrap.WRAP_REVERSE
反方向自动换行。
--设置自动换行时,设置crossAxis无效
HStack()
.wrap(Wrap.WRAP_REVERSE)
.crossAxis(CrossAxis.CENTER)
--设置自动换行时,设置crossContent有效
HStack()
.wrap(Wrap.WRAP_REVERSE)
.crossContent(CrossAxis.CENTER)
总结:未设置自动换行时通过crossAxis
方法设置子view在交叉轴方向的对齐方式。若设置自动换行,使用crossContent
方法。
HStack()
.height(100)
.bgColor(Color(220, 230, 200, 0.2))
.wrap(Wrap.WRAP)
.mainAxis(MainAxis.SPACE_EVENLY)
.crossContent(CrossAxis.CENTER)
下面我们为demo中子view设置crossSelf
来观察效果。
初始ui如下:
为子view设置crossSelf
后如下:
mLabel(str, bgColor) {
Label(str)
.textColor(Color(255, 255, 255, 0.8))
.padding(3, 5, 3, 5)
.bgColor(bgColor)
.fontSize(10)
}
---
--- UI
ui {
--- layout views
HStack().height(50)
.widthPercent(100)
.bgColor(Color(220, 230, 200, 1))
.subs(
mLabel("0元配送", Color(100, 100, 200, 0.8))
,
mLabel("支持自取", Color(100, 120, 200, 0.8))
.crossSelf(CrossAxis.CENTER)
,
mLabel("食无忧", Color(140, 120, 200, 0.8))
.crossSelf(CrossAxis.END)
,
mLabel("津贴2元", Color(180, 150, 100, 0.8))
.crossSelf(CrossAxis.STRETCH)
,
mLabel("会员专享", Color(180, 100, 100, 0.8))
,
mLabel("首单立减", Color(150, 60, 100, 0.8))
)
}
---
--- preview
local function preview()
end
basis:设置view自身在主轴方向的基础尺寸。
HStack的子view 同时设置固定宽度和basis时,basis生效)
grow:填充拉伸。所有设置grow的子View,先走自身尺寸或basis尺寸,剩余多出来的空间,再由grow比例分配加到每个子View上。
shrink:压缩。当空间不足以放下所有子View时,按照shrink比例对每个子View进行压缩。
HStack().bgColor(Color(0xffff00))
.widthPercent(100)
.height(50)
.subs(
Label("label1").bgColor(Color(0xff0000))
.width(100).grow(1)
,
Label("label2").bgColor(Color(0xfff0f0))
.basis(50).grow(1)
,
Label("label3")
)
通过display(boolean display)
设置View是否可见。设置false后View不占空间。PositionType.ABSOLUTE
后,display方法会失效。
通过hidden(boolean hidden)
设置View是否可见。设置true后View不可见,但仍占空间。
mLabel(str, bgColor) {
Label(str)
.textColor(Color(255, 255, 255, 0.8))
.padding(3, 5, 3, 5)
.bgColor(bgColor)
.fontSize(10)
}
---
--- UI
ui {
--- layout views
HStack().height(50)
.widthPercent(100)
.bgColor(Color(220, 230, 200, 1))
.subs(
mLabel("0元配送1", Color(100, 100, 200, 0.8))
.display(true)
,
mLabel("支持自取2", Color(100, 120, 200, 0.8))
.display(false)
,
mLabel("食无忧3", Color(140, 120, 200, 0.8))
,
mLabel("津贴2元4", Color(180, 150, 100, 0.8))
.hidden(true)
,
mLabel("会员专享5", Color(180, 100, 100, 0.8))
.hidden(false)
,
mLabel("首单立减6", Color(150, 60, 100, 0.8))
)
}.safeArea(SafeArea.TOP)
---
--- preview
local function preview()
end
positionType(int positionType)
,参数为PositionType枚举。
PositionType.ABSOLUTE
:绝对定位。相对父View的偏移,偏移后其他同级控件会受影响。
PositionType.RELATIVE
:相对定位。相对自身位置的基础上进行偏移,偏移后其他同级控件位置不变。
通过position(top, right,bottom,left)/positionLeft(left)
等设置偏移量。
初始ui如下:
如下代码中设置PositionType.ABSOLUTE
相关后,可以看到设置position的控件不再占位,其之后的同级控件位置会前移:
--为Label设置position如下
mLabel("津贴2元", Color(180, 150, 100, 0.8))
.positionType(PositionType.ABSOLUTE)
.positionLeft(10)
.positionTop(10)
如下代码中设置PositionType.RELATIVE
相关后,可以看到设置position的控件原位置仍保留,其同级控件位置不变:
mLabel("津贴2元", Color(180, 150, 100, 0.8))
.positionType(PositionType.RELATIVE)
.positionLeft(10)
.positionTop(10)
--完整demo
mLabel(str, bgColor) {
Label(str)
.textColor(Color(255, 255, 255, 0.8))
.padding(3, 5, 3, 5)
.bgColor(bgColor)
.fontSize(10)
}
---
--- UI
ui {
--- layout views
HStack().height(50)
.widthPercent(100)
.bgColor(Color(220, 230, 200, 1))
.subs(
mLabel("0元配送", Color(100, 100, 200, 0.8))
,
mLabel("支持自取", Color(100, 120, 200, 0.8))
,
mLabel("食无忧", Color(140, 120, 200, 0.8))
,
mLabel("津贴2元", Color(180, 150, 100, 0.8))
.positionType(PositionType.ABSOLUTE)
.positionLeft(10)
.positionTop(10)
,
mLabel("会员专享", Color(180, 100, 100, 0.8))
,
mLabel("首单立减", Color(150, 60, 100, 0.8))
)
}.safeArea(SafeArea.TOP)
---
--- preview
local function preview()
end
总结:
- 之前想要实现类似等间隔布局,需要通过计算设置每个子view的margin值,现在直接设置HStack的MainAxis即可快速实现;
- 之前想要实现子view保持一致的对齐方式,需要为每个子view设置gravity,重复工作较多,现在直接设置HStack的MainAxis、CrossAxis即可快速实现;
- 我们经常会遇到如下业务场景,多个子view长度不等,按行排列,放不下的标签折行继续排列。之前的做法,我们需要计算剩余空间能否放下子view,然后再进行布局,现在只需要设置HStack的wrap属性即可轻松实现。
VStack
是纵向线性布局,对于它而言,主轴即指竖直方向,交叉轴指水平方向。VStack使用与HStack类似。
主轴默认是MainAxis.START
向起始方向对齐。
mLabel(str, bgColor) {
Label(str)
.textColor(Color(255, 255, 255, 0.8))
.padding(3, 5, 3, 5)
.bgColor(bgColor)
.fontSize(10)
}
colorLabel(str, color, size) {
Label(str)
.textColor(color)
.fontSize(size)
}
---
--- UI
ui {
--- layout views
VStack()
.mainAxis(MainAxis.START)
.widthPercent(100)
.height(100)
.bgColor(Color(220, 230, 200, 1))
.subs(
colorLabel("小龙虾饭 ", Color(20, 20, 20, 1), 14)
,
colorLabel("评分4.5 ", Color(250, 60, 100, 1), 12)
,
colorLabel("起送 ¥20", Color(120, 120, 120, 1), 12)
,
HStack()
.widthPercent(100)
.mainAxis(MainAxis.SPACE_BETWEEN)
.bgColor(Color(220, 230, 200, 1))
.subs(
mLabel("0元配送", Color(100, 100, 200, 0.8))
,
mLabel("支持自取", Color(100, 120, 200, 0.8))
,
mLabel("食无忧", Color(140, 120, 200, 0.8))
,
mLabel("津贴2元", Color(180, 150, 100, 0.8))
,
mLabel("会员专享", Color(180, 100, 100, 0.8))
,
mLabel("首单立减", Color(150, 60, 100, 0.8))
)
)
}
---
--- preview
local function preview()
end
MainAxis.CENTER
向中心对齐。将demo1中MainAxis枚举值改为CENTER,ui显示如下
MainAxis.END
向结束方向对齐。将demo1中MainAxis枚举值改为END,ui显示如下
MainAxis.SPACE_BETWEEN
空闲区域在子view之间,等间距分布space,头尾不占space。
MainAxis.SPACE_AROUND
空闲区域在子view之间,等间距分布space,头尾各占1/2space。
MainAxis.SPACE_EVENLY
空闲区域在子view之间,等间距分布space,头尾各占1space。
交叉轴默认是CrossAxis.START
向起始方向对齐。
VStack()
.crossAxis(CrossAxis.START)
CrossAxis.CENTER
向中心对齐。
CrossAxis.END
向结束方向对齐。
VStack使用与HStack类似,其他用法说明请参考HStack。
占位布局,需配合HStack
、VStack
使用。
我们以下图布局为例,开始使用Spacer。
colorLabel(str, color, size) {
Label(str)
.textColor(color)
.fontSize(size)
}
---
--- UI
ui = {
--- layout views
HStack()
.subs(
colorLabel("评分4.5", Color(250, 60, 100, 1), 12)
,
colorLabel("销量66", Color(50, 50, 50, 1), 12)
,
Spacer()
,
colorLabel("35分钟", Color(50, 150, 50, 1), 12)
,
colorLabel("1.2km", Color(50, 50, 150, 1), 12)
)
}
HStack()
.subs(
colorLabel("评分4.5", Color(250, 60, 100, 1), 12)
,
colorLabel("销量66", Color(50, 50, 50, 1), 12)
,
Spacer()
,
colorLabel("35分钟", Color(50, 150, 50, 1), 12)
,
Spacer()
,
colorLabel("1.2km", Color(50, 50, 150, 1), 12)
)
点击查看完整demo
mLabel(str, bgColor) {
Label(str)
.textColor(Color(255, 255, 255, 0.8))
.padding(3, 5, 3, 5)
.bgColor(bgColor)
.fontSize(10)
}
colorLabel(str, color, size) {
Label(str)
.textColor(color)
.fontSize(size)
}
mLayout(str, imgBool) {
HStack()
--.width(MeasurementType.WRAP_CONTENT)
.padding(0, 5, 0, 5)
.bgColor(Color(220, 220, 220, 0.5))
.cornerRadius(5)
.height(28)
.crossAxis(CrossAxis.CENTER)
.left(3)
.right(3)
.top(3)
.bottom(3)
.subs(
ImageView()
.width(18)
.height(18)
.image("https://s.momocdn.com/w/u/others/custom/MLNUI/icon.png")
.bind(function()
if imgBool then
self.display(true)
else
self.display(false)
end
end)
,
Label(str)
.fontSize(12)
)
}
---
--- UI
ui = {
--- layout views
VStack().widthPercent(100)
.subs(
colorLabel("热门搜索", Color(20, 20, 20, 1), 14)
,
HStack().bgColor(Color(220, 230, 200, 0.2))
.wrap(Wrap.WRAP)
.subs(
mLayout("汉堡", true)
,
mLayout("龙虾饭", true)
,
mLayout("番茄米线", false)
,
mLayout("健康蔬菜沙拉", true)
,
mLayout("车厘子优选", true)
,
mLayout("藤椒麻辣香锅", false)
)
,
HStack()
.bgColor(Color(220, 230, 200, 1))
.crossAxis(CrossAxis.CENTER)
.widthPercent(100)
.subs(
ImageView("https://hbimg.huabanimg.com/7c41bc5871d74c9036932ca9bba76de363727be113b6fd-NApej6_fw658")
.width(50)
.height(50)
.contentMode(ContentMode.SCALE_ASPECT_FILL)
.cornerRadius(40)
,
ImageView("https://s.momocdn.com/w/u/others/custom/MLNUI/hot2.png")
.width(15)
.height(15)
.positionType(PositionType.RELATIVE)
.positionLeft(-15)
.positionBottom(15)
,
VStack()
.width(250)
.mainAxis(MainAxis.SPACE_EVENLY)
.crossAxis(CrossAxis.START)
.height(100)
.subs(
colorLabel("小龙虾饭 ", Color(20, 20, 20, 1), 14)
,
colorLabel("起送 ¥20", Color(120, 120, 120, 1), 12)
,
HStack()
.widthPercent(100)
.subs(
colorLabel("评分4.5", Color(250, 60, 100, 1), 12)
,
colorLabel(" 销量66", Color(50, 50, 50, 1), 12)
,
Spacer()
,
colorLabel("35分钟", Color(50, 150, 50, 1), 12)
,
colorLabel(" 1.2km", Color(50, 50, 150, 1), 12)
)
,
HStack()
.widthPercent(100)
.mainAxis(MainAxis.SPACE_BETWEEN)
.subs(
mLabel("支持自取", Color(100, 120, 200, 0.8))
,
mLabel("食无忧", Color(140, 120, 200, 0.8))
,
mLabel("津贴2元", Color(180, 150, 100, 0.8))
,
mLabel("会员专享", Color(180, 100, 100, 0.8))
,
mLabel("首单立减", Color(150, 60, 100, 0.8))
)
)
,
mLabel("分享", Color(100, 100, 200, 1), 12)
.positionType(PositionType.ABSOLUTE)
.positionRight(0)
.positionTop(0)
,
mLabel("赞", Color(150, 60, 100, 1), 12)
.crossSelf(CrossAxis.END)
.positionType(PositionType.ABSOLUTE)
.positionRight(0)
)
,
HStack()
.widthPercent(100)
.subs(
mLabel("\"吃货强推\"", Color(200, 100, 0, 0.5))
.width(60)
,
mLabel("\"人气飙升\"", Color(100, 100, 0, 0.5))
.width(60)
.basis(2)
,
mLabel("\"赞\"", Color(200, 100, 0, 0.5))
.basis(1)
,
mLabel("\"就很棒哇\"", Color(100, 100, 0, 0.5))
.basis(2)
,
mLabel("\"吃货强推啊啊啊啊\"", Color(200, 100, 0, 0.5))
.basis(3)
)
)
}
---
--- preview
function preview()
end
使用过程中,如有任何问题,欢迎反馈~