DEV Community

HarmonyOS
HarmonyOS

Posted on

getRectangleById retrieves component position abnormally

Read the original article:getRectangleById retrieves component position abnormally

Requirement Description

The rotate attribute can be used to rotate components. In the following example, Component 2 is obtained by rotating Component 1 by 90 degrees. Although the two components appear in different positions on the screen, when using getRectangleById(id: string) to get their coordinates, the returned screenOffset values are the same.

The problematic code is as follows:

@Entry
@Component
struct Index {
  build() {
    NavDestination() {
      RelativeContainer() {
        Text('1')
          .width(50)
          .height(50)
          .backgroundColor('#0A59F7')
          .alignRules({
            'middle': { 'anchor': '__container__', 'align': HorizontalAlign.Center },
            'top': { 'anchor': '__container__', 'align': VerticalAlign.Top }
          })
          .id('item1')

        RelativeContainer() {
          Text('2')
            .width(50)
            .height(50)
            .backgroundColor('#0A59F7')
            .alignRules({
              'middle': { 'anchor': '__container__', 'align': HorizontalAlign.Center },
              'top': { 'anchor': '__container__', 'align': VerticalAlign.Top }
            })
            .rotate({
              angle: '-90deg'
            })
            .id('item2')
        }.width('100%').height('100%')
        .rotate({
          angle: '90deg'
        })
      }
      .width(233)
      .height(233)
      .backgroundColor('#F1F3F5')
      .onAppear(() => {
        setTimeout(() => {
          const info1 = this.getUIContext().getComponentUtils().getRectangleById('item1')
          console.info('Coordinate 1:', 'x:' + info1.screenOffset.x.toString(), ' y:', info1.screenOffset.y.toString())
          const info2 = this.getUIContext().getComponentUtils().getRectangleById('item2')
          console.info('Coordinate 2:', 'x:', info2.screenOffset.x.toString(), ' y:', info2.screenOffset.y.toString())
        }, 1000);
      })
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The actual effect and returned information are as follows:

cke_3029.png

I Coordinate 1: x:183 y: 0

I Coordinate 2: x: 183 y: 0

Background Knowledge

The componentUtils API provides the ability to obtain the coordinates and size of a component’s rendering area.

In the returned ComponentInfo, screenOffset represents the component’s position on the screen.

Implementation Steps

The abnormal ComponentInfo values are caused by improper layout usage. By removing the nested RelativeContainer layout, correct coordinates can be obtained.

Code Snippet / Configuration

@Entry
@Component
struct Index {
  build() {
    NavDestination() {
      RelativeContainer() {
        Row() {
          Text('1')
        }
        .width(50)
        .height(50)
        .backgroundColor('#0A59F7')
        .alignRules({
          top: { anchor: '__container__', align: VerticalAlign.Top },
          left: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .margin({ left: -25 })
        .id('Item1')
        .onClick(() => {
          let modePosition = this.getUIContext().getComponentUtils().getRectangleById('Item1')
          console.info('Coordinate 1:', 'x:', modePosition.screenOffset.x.toString(), ' y:',
            modePosition.screenOffset.y.toString())
        })

        Row() {
          Text('2')
        }
        .width(50)
        .height(50)
        .backgroundColor('#0A59F7')
        .alignRules({
          top: { anchor: '__container__', align: VerticalAlign.Center },
          right: { anchor: '__container__', align: HorizontalAlign.End }
        })
        .rotate({
          angle: '-90deg'
        })
        .onClick(() => {
          let modePosition = this.getUIContext().getComponentUtils().getRectangleById('Item2')
          console.info('Coordinate 2:', 'x:', modePosition.screenOffset.x.toString(), ' y:',
            modePosition.screenOffset.y.toString())
        })
        .margin({ top: -25 })
        .id('Item2')
      }
      .background("#fff")
      .width(233).height(233)
      .border({ width: 2, color: '#6699FF' })
    }
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

Test Results

Returned information:

cke_778.png

I Coordinate 1: x: 183 y: 4

I Coordinate 2: x: 362 y: 183

It can be seen that the screenOffset values of Component 1 and Component 2 are no longer the same.

Limitations or Considerations

This example supports API Version 19 Release and above.

This example supports HarmonyOS 5.1.1 Release SDK and above.

This example requires DevEco Studio 5.1.1 Release or later for compilation and execution.

Written by Bunyamin Akcay

Top comments (0)