首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Harmony错题本--RelativeContainer 默认占全屏问题

问题描述

学习中在写界面的时候,用到了一个叫RelativeContainer的组件,楼主本来想实现如图所示的界面

但是楼主在写代码的时候,如下方代码、所示,发现RelativeContainer这个空间,如果不给定确切的宽高,默认是铺满,展示的跟原本预期的不同

如下方代码,是按照下方这种布局思路来的

--Colum //竖向线性布局

|--RelativeContainer //个人任务, 工作任务选框布局

|--个人任务及单选框布局

|--工作任务单选框布局

|--Text// 新建任务文案

代码如下:

@Extend(Text) function myRadioDescribeText1(){

.fontColor($r("app.color.radio_describe"))

.fontSize($r("app.float.text_H5"))

}

@Entry

@Component

struct test{

build() {

Column(){

// 相对布局控件, 代码里没有对这个相对布局设置宽高

RelativeContainer(){

// 个人任务的单选框

Radio({value : "个人任务", group : "task_type"})

.id("private_radio")

.checked(true)

.alignRules(

{start : {anchor : "__container__", align : HorizontalAlign.Start},

top : {anchor : "__container__", align : VerticalAlign.Top},

}

)

Text($r("app.string.add_task_type_private"))

.myRadioDescribeText1()

.alignRules({

start : {anchor : "private_radio", align : HorizontalAlign.End},

center : {anchor : "private_radio", align : VerticalAlign.Center}

}

).offset({x : 10})

Text($r("app.string.add_task_type_work"))

.id("work_radio")

.myRadioDescribeText1()

.alignRules({

end : {anchor : "__container__", align : HorizontalAlign.End},

center : {anchor : "private_radio", align : VerticalAlign.Center}

})

.offset({x : -10})

// 工作任务的单选框

Radio({value : "工作任务", group : "task_type"})

.checked(false)

.alignRules(

{end : {anchor : "work_radio", align : HorizontalAlign.Start},

center : {anchor : "work_radio", align : VerticalAlign.Center}

}

).offset({x : -10})

}

.border({width : 3, color : Color.Blue})

// 新建任务,文本框

Text($r("app.string.add_task_page_title"))

.id("page_title")

.fontSize($r("app.float.title_H5"))

.fontColor($r("app.color.title_color2"))

.fontWeight(FontWeight.Bold)

}

}

}

展示:

因为展示不如预期,所以楼主对RelativeContainer部分加了蓝色边框。图上效果很明显,RelativeContainer 占满全屏幕了,显然不符合预期的。

于是楼主看了网上的帖子,也问了AI, 在RelativeContainer后面指定宽度为100%, 高度为 auto。发现还是不好用。

RelativeContainer(){

// 这里即使只有一个Text控件。他也是占满全屏

}

.width('100%').height('auto') //不好使!照样是铺满全屏

这是网上看来的答案,结果并没有解决,所谓的自适应效果根本没有!绝知此事要躬行啊!这么重要的控件连自适应能力都没有的话, 不太可能啊?

RelativeContainer的自适应在什么时候奏效?

这里的自适应就是当写如上方代码, 将width或者height给为auto的时候,什么时候是奏效的。

楼主经过测试得到一个答案是:.width('100%').height('auto')这种代码给RelativeContainer设置, 在某些情况下是奏效的, 某些情况下却又不会奏效。

比如您设置了纵向高度为自适应,到底真实情况下,究竟是不是自适应,得看子元素alignRules是怎么设置的!

里如下面的代码, 楼主测得,在RelativeContainer设置为高度 auto 的时候

子控件alignRules 中,只设置横向锚点,来确定其横向应该在什么位置, 此时,RelativeContainer可以满足自适应要求。

子控件alignRules中, 但凡设置了纵向的锚点,而且这个锚点正好是父布局RelativeContainer的一个边,此时RelativeContainer的 height  auto特点原地消失!RelativeContainer直接撑开全屏了就!(比较过分)

RelativeContainer(){

Radio({value : "个人任务", group : "task_type"})

.width(20).height(20)

.id("private_radio")

.checked(true)

.alignRules(

{start : {anchor : "__container__", align : HorizontalAlign.Start},

// top : {anchor : "__container__", align : VerticalAlign.Top},

}

)

}

.width('100%').height('auto')

为了方便理解,现象如下图所示:

将RelativeContainer的高度设置为 "auto"

将RelativeContainer的所有子控件的相对位置锚点,纵向上的那些锚点, top, bottom, center, 不要与父布局的任何边边, 任何中间点建立锚点关系。

修改完后的代码如下:

@Extend(Text) function myRadioDescribeText1(){

.fontColor($r("app.color.radio_describe"))

.fontSize($r("app.float.text_H5"))

}

@Entry

@Component

struct test{

build() {

Column(){

RelativeContainer(){

Radio({value : "个人任务", group : "task_type"})

.width(20).height(20)

.id("private_radio")

.checked(true)

.alignRules(

{start : {anchor : "__container__", align : HorizontalAlign.Start}}

// bugFix 删除 top : {anchor : "__container__", align : VerticalAlign.Top},

// 因为楼主的其余子控件相对位置都是根据这个空间来进行标锚的,所以其余子控件不用改,只改

// 这个就好了

)

Text($r("app.string.add_task_type_private"))

.myRadioDescribeText1()

.alignRules({

start : {anchor : "private_radio", align : HorizontalAlign.End},

center : {anchor : "private_radio", align : VerticalAlign.Center}

}

).offset({x : 10})

//

Text($r('app.string.add_task_type_work'))

.id("work_radio")

.myRadioDescribeText1()

.alignRules({

end : {anchor : "__container__", align : HorizontalAlign.End},

center : {anchor : "private_radio", align : VerticalAlign.Center}

})

.offset({x : -10})

Radio({value : "工作任务", group : "task_type"})

.checked(false)

.alignRules(

{end : {anchor : "work_radio", align : HorizontalAlign.Start},

center : {anchor : "work_radio", align : VerticalAlign.Center}

}

).offset({x : -10})

}

.border({width : 3, color : Color.Blue})

.width("100%").height("auto") // bugFix 对相对布局容器高度指定为 auto

Text($r("app.string.add_task_page_title"))

.id("page_title")

.fontSize($r("app.float.title_H5"))

.fontColor($r("app.color.title_color2"))

.fontWeight(FontWeight.Bold)

}

}

}

关于 RelativeContainer 的理解与扩展

为了方便记忆,我们不妨认为这个RelativeContainer的 宽高指定auto的情况下,应该是,只要不较真设置相应方向的锚点, 就会自适应, 一旦程序员较真设置了相应方向的锚点关系, 并且这个锚点的边还是父布局RelativeContainer的某些边边,那么,就得计算测量了。您又没给确切的宽高,那人家只能默认撑开父布局的大小。

我们可以将每个锚点简单的理解为,一个橡皮筋。这个与Android上的约束布局--ConstraintLayout极其相似。

小小扩展

楼主的整篇文章,是建立在读者已经会使用RelativeContainer的基础上来的,或者来说,最低也会会照葫芦画瓢的程度来写案例的水平之上。

对于RelativeContainer,初学者开始学的话,可以通过看视频或者看官方文档进行学习。

但是楼主读文档时仍然觉得晦涩。看这些文章之前, 我们不妨先建立一个拟物化的想象。就是我们可以在不知道这文章里提出的所有概念前, 拟物一个场景, 就是橡皮筋拉扯,将物体固定在空间中的场景,然后再带入,看代码看文章。或许就更容易理解其中的思想。

指南中 RelativeContainer 的解释:

API中 RelativeContainer 的解释:

如果按照弹簧思想来理解今天遇到的问题,我们就不难解释了。就是高度上设置了 auto , 但是,一旦子控件设置竖向上锚点,正好是父布局 RelativeContainer 自己的边, 那么,就意味着这个“边”必须要“存在了”, 并且还要有个确切的距离,来约束被链接上的物体。既然存在,那这个位置到底离物体多远呢?用户没有给,只给了个auto。如果还按照auto来,那么之后的占比权重怎么计算?所以这个距离应是确定的。为父布局。

总结

AI问答得到的答案暂时解决不了一些看似刁钻实则普通的问题,要全面替代程序员,有段路程要走。

RelativeContainer 可以为宽高设置为 auto 来实现自适应宽度或者高度。但是这个自适应,会因为子控件的alignRules设置方式而被打破。子控件没有面向RelativeContainer边上的锚点时((left, middel, right)横向,   (top, center, bottom)纵向), 则其对应的方向就会自适应。一旦有了锚点则相关方向默认铺满。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/ORKiQU5QIrRvifd7v0-6M68g0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券