在开发中遇到过一个问题,首先我们是在4k分辨率下开发的,界面要求如下
我们以第二行为例子,第二行有3个界面,其中中间的界面是比较长的
面板中使用Vertical和Horizontal排列,并且勾选了ControlChildSize和ChildForceExpand,保证每个物体都对齐
[图1]
[图2]
[图3]
但是在界面的第二行(以下的操作是第二行的)父物体Row2勾选了ControlChildSize和ChildForceExpand后,出现一个下面的问题,如图4:
[图4]
中间的间隔,被移动了。其实是最中间的面板被缩小了,而两边的面板被拉长了。
原因:在父物体勾选了ControlChildSize和ChildForceExpand后,子物体会等宽平均分布
ControlChildSize:强制父物体完全控制子物体的宽度(以宽度为例子),不允许子物体自己修改
ChildForceExpand:使剩余空间均匀分配给子物体
那么怎么解决这种情况呢?我们想要的是图1中的效果,间隙是对齐的
解决办法:
1.给每个子物体都添加LayoutElement组件
2.确定Preferred Width
我们以4k分辨率作为设计分辨率,此时先取消ControlChildSize和ChildForceExpand,将3个子物体手动调整到正确的宽度,调整后的子物体宽度:A=920,B=1900,C=920。
3个宽度相加920+1900+920=3740;父物体的Spacing为50,但是有2条间隙,所以50*2=100,再100+3740=3840,保证占满整个屏幕的宽度,如图5
[图5]
此时3个子物体的宽度,就是他们的Preferred Width
[图6]
[图7]
这个时候我们再设置父物体的ControlChildSize,ChildForceExpand,就可以正常缩放了,如图8
[图8]
此时我相信你们肯定有疑问:他是怎么做到按照比例缩放的呢?调了这个Preferred Width到底有什么作用?Preferred Width到底应该调多少合适?别急,下面我们来解释下原理
LayoutElement的Preferred Width,是一个最佳的宽度值,父物体在有空闲空间时,会将子物体的宽度优先设置为这个值,空间不足这个值时,如果勾选了ControlChildSize和ChildForceExpand时,则会基于这个值进行缩放。下面展示3种情况:
情况1:父物体空位刚好被子物体全部填充
解释:
已知父物体Width=3840,Spacing=50,勾选了ControlChildSize和ChildForceExpand。子物体A Preferred Width=920,子物体B Preferred Width=1900, 子物体C Preferred Width=920
此时父物体的空闲空间有3840-50 * 2=3740,这个50是Spacing,* 2是因为有2个间隙。先尝试将3个子物体的Preferred 填充进去 920+1900+920=3740,此时所有子物体的Preferred Width刚好可以填充父物体的空闲空间,所以每个子物体都可以分配到全部的Width,也就是Width=Preferred。不会做任何缩放,这是我们要的最佳效果。
计算过程:
父空闲空间:3840-50 * 2=3740
子物体占用空间:920+1900+920=3740
父空闲空间=子物体占用空间,不需要缩放
情况2:父物体空位不足
不想看解释可以直接看下面的计算过程
解释:
当分辨率变小时,此时父物体Width=2880,父物体、子物体的 其他参数都不变
此时父物体的空闲空间有2880-50 * 2=2780,子物体3个Preferred尝试填充920+1900+920=3740。2780<3740,空闲空间不够!还差3740-2780=960,这个960的意思,就是我们每个子物体都需要缩放一定大小,3个子物体共缩放960,就可以填充满父物体了
因为我们设置了Preferred Width,所以缩放并不是ControlChildSize默认的等比缩放,而是根据三者的Preferred Width加权平均决定的
子物体A Preferred Width=920,A Preferred Width占比=920/3740=0.2459, 需要缩放 0.2459 * 960=236.064
子物体B Preferred Width=1900,B Preferred Width占比=1900/3740=0.508, 需要缩放 0.508 * 960=487.68
子物体C Preferred Width=920,C Preferred Width占比=920/3740=0.2459,需要缩放 0.2459 * 960=236.064
得出3个子物体需要缩放多少,那么再用Preferred Width-需要缩放的宽度,结果就是实际的宽度了
子物体A实际宽度:920-236.064=683.936
子物体B实际宽度:1900-487.68=1412.32
子物体C实际宽度:920-236.064=683.936
所以Preferred Width的作用,就是将子物体按照一定比例分配宽度,他的用法,就是先确定一个合适的分辨率,以这个分辨率为主,设定好实际宽度,然后将Preferred Width设置为这个宽度
计算过程:
父物体空闲空间:2880-50×2=2780
子物体Preferred:920+1900+920=3740
父物体空间2780<3740,进行缩放
子物体A 缩放=920/3740=0.2459×960=236.064 --> A Width=920-236.064=683.936
子物体B 缩放=1900/3740=0.508×960=487.68 --> B Width=1900-487.68=1412.32
子物体C 缩放=920/3740=0.2459×960=236.064 --> C Width=920-236.064=683.936
情况3:父物体空间有剩余
解释:
缩小分辨率没有问题了,我们再试试放大:一个极端的例子,比如带鱼屏,如图9
[图9]
此时发现,间隙又对不齐了,这是因为我们只设置了Preferred Width,这个表示的是最佳宽度,如果父物体有空闲空间时,会将其子物体Width设置为Preferred Width,但是额外的空闲部分怎么办呢?在勾选了ControlChildSize和ChildForceExpand下,父物体会将所有子物体等比拉伸,就是说每个子物体拉伸的长度都是固定的,所以造成了对不齐的情况。这个时候就需要用到Flexible Width,用来决定空闲空间怎么分配,注意这个Flexible Width单位是权重,而不是像素
我们知道子物体宽度为A:920,B:1900,C:920,此时3者的比值为1,2,1,这时将3个子物体的Flexible Width设置为1,2,1,就可以实现正确的放大了,如图10
[图10]
这个与情况2的计算一样,就是说Flexible Width设置后,子物体以在空闲空间进行分配时,如果Flexible Width更高,则得到更多的空闲空间
用法:在正常分辨率情况下,计算好子物体之间的比值,这个比值就是Flexible Width,如果父物体空闲空间不够,则不计算Flexible Width