线性布局——通过线性容器Row和Column构建。
Column容器内子元素按照垂直方向排列,Row容器内子元素按照水平方向排列。
主轴:线性布局容器在布局方向上的轴线,子元素默认沿主轴排列。Row容器主轴为水平方向,Column容器主轴为垂直方向。
交叉轴:垂直于主轴方向的轴线。Row容器交叉轴为垂直方向,Column容器交叉轴为水平方向。
间距:布局子元素的间距。
布局子元素在主轴上的间距——space参数对象
Column容器内排列方向上的间距
Row容器内排列方向上的间距
Column({ space: 20 }) {})
布局子元素在交叉轴上的对齐方式——alignItems属性
交叉轴为水平,取值为HorizontalAlign——Column容器内子元素在水平方向上的排列
HorizontalAlign.Start:子元素在水平方向左对齐。
HorizontalAlign.Center:子元素在水平方向居中对齐。
HorizontalAlign.End:子元素在水平方向右对齐。
Column({}) {
}.alignItems(HorizontalAlign.Start)
交叉轴为垂直,取值为VerticalAlign——Row容器内子元素在垂直方向上的排列
VerticalAlign.Top:子元素在垂直方向顶部对齐。
VerticalAlign.Center:子元素在垂直方向居中对齐。
VerticalAlign.Bottom:子元素在垂直方向底部对齐。
Row({}) {
}.AlignItems(VerticalAlign.Bottom)
alignSelf属性用于控制单个子元素在容器交叉轴上的对齐方式,其优先级高于alignItems属性,如果设置了alignSelf属性,则在单个子元素上会覆盖alignItems属性。
布局子元素在主轴上的排列方式——justifyContent属性
Column容器内子元素在垂直方向上的排列
justifyContent(FlexAlign.Start):元素在垂直方向方向首端对齐,第一个元素与行首对齐,同时后续的元素与前一个对齐。
justifyContent(FlexAlign.Center):元素在垂直方向方向中心对齐,第一个元素与行首的距离与最后一个元素与行尾距离相同。
justifyContent(FlexAlign.End)
//间隔对齐
//两端对齐
justifyContent(FlexAlign.SpaceBetween):垂直方向均匀分配元素,相邻元素之间距离相同。第一个元素与行首对齐,最后一个元素与行尾对齐。
//两端间距取一半
justifyContent(FlexAlign.SpaceAround):垂直方向均匀分配元素,相邻元素之间距离相同。第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半。
//两端间距取完整
justifyContent(FlexAlign.SpaceEvenly):垂直方向均匀分配元素,相邻元素之间的距离、第一个元素与行首的间距、最后一个元素到行尾的间距都完全一样。
Row容器内子元素在水平方向上的排列
同Column容器内子元素在垂直方向上的排列
自适应拉伸
在线性布局下,常用空白填充组件Blank
,在容器主轴方向自动填充空白空间
,达到自适应拉伸效果。
Row和Column作为容器,````只需要添加宽高为百分比```,当屏幕宽高发生变化时,会产生自适应效果。
build() {
Column() {
Row() {
Text('Bluetooth').fontSize(18)
Blank()//自适应填充空白
Toggle({ type: ToggleType.Switch, isOn: true })
}.backgroundColor(0xFFFFFF).borderRadius(15).padding({ left: 12 }).width('100%')
}.backgroundColor(0xEFEFEF).padding(20).width('100%')
}
自适应缩放
自适应缩放是指子元素随容器尺寸的变化而按照预设的比例自动调整尺寸,适应各种不同大小的设备。在线性布局中,可以使用以下两种方法实现自适应缩放。
- 父容器尺寸确定时,使用
layoutWeight属 性
设置子元素和兄弟元素在主轴上的权重
,忽略元素本身尺寸设置,使它们在任意尺寸的设备下自适应占满剩余空间。
build() {
Column() {
Text('1:2:3').width('100%')
Row() {
}.layoutWeight(1).backgroundColor(0xF5DEB3).height('100%')
Column() {
}.layoutWeight(2).backgroundColor(0xD2B48C).height('100%')
Column() {
}.layoutWeight(3).backgroundColor(0xF5DEB3).height('100%')
}.backgroundColor(0xffd306).height('30%')
}
}
- 父容器尺寸确定时,使用百分比设置子元素和兄弟元素的宽度,使他们在任意尺寸的设备下保持固定的自适应占比。
.width('20%')
自适应延伸
自适应延伸是指在不同尺寸设备下,当页面的内容超出屏幕大小而无法完全显示时,可以通过滚动条进行拖动展示。这种方法适用于线性布局中内容无法一屏展示的场景。通常有以下两种实现方式。
-
在List中添加滚动条:当List子项过多一屏放不下时,可以将每一项子元素放置在不同的组件中,通过滚动条进行拖动展示。可以通过scrollBar属性设置滚动条的常驻状态,edgeEffect属性设置拖动到内容最末端的回弹效果。
-
使用Scroll组件:在线性布局中,开发者可以进行垂直方向或者水平方向的布局。当一屏无法完全显示时,可以在Column或Row组件的外层包裹一个可滚动的容器组件Scroll来实现可滑动的线性布局。
垂直方向布局中使用Scroll组件:
@Entry
@Component
struct ScrollExample {
scroller: Scroller = new Scroller();
build() {
Scroll(this.scroller) {
Column() {
}
}
.backgroundColor(0xDCDCDC)
.scrollable(ScrollDirection.Vertical) // 滚动方向为垂直方向
.scrollBar(BarState.On) // 滚动条常驻显示
.scrollBarColor(Color.Gray) // 滚动条颜色
.scrollBarWidth(10) // 滚动条宽度@Entry
.edgeEffect(EdgeEffect.Spring) // 滚动到边沿后回弹
}
}
水平方向布局中使用Scroll组件:
@Entry
@Component
struct ScrollExample {
scroller: Scroller = new Scroller();
build() {
Scroll(this.scroller) {
Row() {
}
}
.backgroundColor(0xDCDCDC)
//滚动方向不同
.scrollable(ScrollDirection.Horizontal) // 滚动方向为水平方向
.scrollBar(BarState.On) // 滚动条常驻显示
.scrollBarColor(Color.Gray) // 滚动条颜色
.scrollBarWidth(10) // 滚动条宽度
.edgeEffect(EdgeEffect.Spring) // 滚动到边沿后回弹
}
}
实战案例
(不明白为什么顶部和底部有留白)
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
//线性布局——交叉轴对齐方式
build() {
Column({
// space: 10
}){
Row(){
Image($r('app.media.jd_cancel'))
.width(20)
Text('帮助')
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
Image($r('app.media.jd_logo'))
.width(250)
.height(250)
//画一个按钮
Row(){
Text('国家/地区')
.fontColor('#666')
// .layoutWeight(1)
Blank()
Text('中国(+86)')
.fontColor('#666')
.margin({
right:5
})
Image($r('app.media.jd_right'))
.width(20)
.fillColor('#666')
}.backgroundColor('#fff')
.width('100%')
.height(40)
.borderRadius(20)
.padding({
left:15,
right:10
})
//请输入电话号码
TextInput({
placeholder:'请输入电话号码'
})
.placeholderColor('#666')
.height(40)
.borderRadius(20)
.backgroundColor('#fff')
.margin({
top:20
})
//协议
Row(){
Checkbox()
.width(10)
.margin({top:7})
Text(){
Span('我已经阅读并同意')
Span('《京东隐私政策》').fontColor('#3274f6')
Span('《京东用户服务协议》').fontColor('#3274f6')
Span('未注册的手机号自动注册')
}
.fontColor('#666')
.fontSize(12)
.lineHeight(20)
}
.alignItems(VerticalAlign.Top)
.margin({ top:10 })
Button('登录')
.backgroundColor('#bf2838')
.width('100%')
.margin(({top:25}))
Row({space:25}){
Text('新用户注册')
.fontColor('#666')
.fontSize(14)
Text('账户密码登录')
.fontColor('#666')
.fontSize(14)
Text('无法登录')
.fontColor('#666')
.fontSize(14)
}.margin({top:15})
Blank()//弹性空白组件填充
//底部
Column(){
Text('其他登录方式')
.fontColor('#666')
.fontSize(14)
.height(22)
.margin(({bottom:28}))
Row(){
Image($r('app.media.jd_huawei')).width(34)
Image($r('app.media.jd_wechat')).width(34)
Image($r('app.media.jd_weibo')).width(34)
Image($r('app.media.jd_QQ')).width(34).fillColor('#4ba8e8')
}.width('100%')
.justifyContent(FlexAlign.SpaceAround)
.margin({bottom:30})
}
}.height('100%')
.width('100%')//容器.width('100%')默认居中效果
.padding(20)//添加内边距
.backgroundImage($r('app.media.jd_login_bg'))
.backgroundImageSize(ImageSize.Cover)
}
}