组件间布局遮挡
=======

#### 问题现象

打开应用后，出现页面组件间布局遮挡问题，如文本框和图片重叠显示、按钮遮挡文字等异常情况。

#### 背景知识

*   [layoutWeight](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-size#layoutweight)设置组件的布局权重，使用该属性的组件在父容器（Row/Column/Flex）的主轴方向按照权重分配尺寸。
    
    | 
    参数名
    
     | 
    
    类型
    
     | 
    
    必填
    
     | 
    
    说明
    
     |
    | :-- | :-- | :-- | :-- |
    | 
    
    value
    
     | 
    
    number /string
    
     | 
    
    是
    
     | 
    
    父容器尺寸确定时，设置了layoutWeight属性的子元素与兄弟元素占主轴尺寸按照权重进行分配，忽略元素本身尺寸设置，表示自适应占满剩余空间。默认值：0。
    
     |
    
*   [margin](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-size#margin)设置外边距属性。参数：
    
    | 
    参数名
    
     | 
    
    类型
    
     | 
    
    必填
    
     | 
    
    说明
    
     |
    | :-- | :-- | :-- | :-- |
    | 
    
    value
    
     | 
    
    [Margin](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-types#margin) /[Length](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-types#length) / [LocalizedMargin12+](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-types#localizedmargin12)
    
     | 
    
    是
    
     | 
    
    设置组件的外边距。参数为Length类型时，四个方向外边距同时生效。默认值：0，单位：vp 。
    
     |
    
*   [padding](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-size#padding)设置内边距属性。参数：
    
    | 
    参数名
    
     | 
    
    类型
    
     | 
    
    必填
    
     | 
    
    说明
    
     |
    | :-- | :-- | :-- | :-- |
    | 
    
    value
    
     | 
    
    [Padding](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-types#padding) /[Length](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-types#length) / [LocalizedPadding12+](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-types#localizedpadding12)
    
     | 
    
    是
    
     | 
    
    设置组件的内边距。参数为Length类型时，四个方向内边距同时生效。默认值：0，单位：vp。padding设置百分比时，上下左右内边距均以父容器的width作为基础值。
    
     |
    

#### 问题定位

#### \[h2\]场景一

排查容器布局是否存在约束，即是否使用了Stack堆叠布局。如使用了Stack布局，这种布局子元素默认进行居中堆叠，子元素被约束在Stack下，这会导致组件间布局遮挡，关键代码如下：

Stack(){
  Image($r('app.media.startIcon'))
    .width('100%')
  TextInput({text:'图片被文本框遮挡'})
    .backgroundColor(Color.Grey)
    .fontSize(24)
    .fontColor(Color.Black)
}

#### \[h2\]场景二

排查组件是否使用线性布局，如果线性布局的宽高设置不合理，也会出现遮挡，关键代码如下：

Column() {
  Column(){
    Text('Test Test')
  }.height('70%').width('100%').backgroundColor('red')
  Row(){
    _// 此处的文本被遮挡_
    Text('hello world')
  }.height('100%').width('100%').backgroundColor('blue')
}.width('100%').height('100%')

#### \[h2\]场景三

排查组件是否有设置内/外边距，以及内/外边距属性设置是否合理，过大/过小的内外边距都会导致组件间布局遮挡，关键代码如下：

Stack(){
  Image($r('app.media.startIcon'))
    .width('100%')
  TextInput({text:'图片被文本框遮挡'}) 
    .backgroundColor(Color.Grey)
    .fontSize(24)
    .fontColor(Color.Black)
    .margin({top:'-50'})
}

#### 分析结论

#### \[h2\]场景一

容器存在布局约束，造成组件间堆叠，布局遮挡。

#### \[h2\]场景二

线性布局的宽高设置不合理，造成组件间布局遮挡。

#### \[h2\]场景三

内/外边距属性设置不合理，造成组件间布局遮挡。

#### 修改建议

#### \[h2\]场景一

布局约束造成的组件间布局遮挡问题，可以更改为Flex弹性布局，并设置layoutWeight属性来分配剩余空间。

_// 改成Flex布局_
Flex(){
  Image($r('app.media.startIcon'))
    .width('100%')
    _// 这个页面的占比为1份_
    .layoutWeight(1)
  TextInput({text:'图片被文本框遮挡'})
    .backgroundColor(Color.Grey)
    .fontSize(24)
    .fontColor(Color.Black)
    _// 整个页面的占比为2份_
    .layoutWeight(2)
}

#### \[h2\]场景二

线性布局的宽高设置不合理造成的组件间布局遮挡问题，可以根据实际应用场景，动态调整width、height等属性的值。

Column() {
  Column(){
    Text('Test Test')
  }.height('50%').width('100%').backgroundColor('red')
  Row(){
    _// 调整height，此处的文本可正常展示，未被遮挡_
    Text('hello world')
  }.height('40%').width('100%').backgroundColor('blue')
}.width('100%').height('100%')

#### \[h2\]场景三

组件内/外边距属性设置不合理造成的组件间布局遮挡问题，可以根据实际应用场景，动态调整margin、padding等属性的值。

Stack(){
  Image($r('app.media.startIcon'))
    .width('100%')
  TextInput({text:'图片被文本框遮挡'})
    .backgroundColor(Color.Grey)
    .fontSize(24)
    .fontColor(Color.Black)
    _// 调整了margin的值，可以正常展示，未被遮挡_
    .margin({top:'0'})
}