DEV Community

HarmonyOS
HarmonyOS

Posted on

getRectangleById Gets The Component Position Abnormally

Read the original article:getRectangleById Gets The Component Position Abnormally

Problem Description

The rotate property 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 are located at different positions on the screen, the screenOffset values returned when using getRectangleById(id: string) to obtain the coordinates of the two components are the same.

The problem 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(300)
      .height(300)
      .backgroundColor('#F1F3F5')
      .onAppear(() => {
        setTimeout(() => {
          const info1 = this.getUIContext().getComponentUtils().getRectangleById('item1')
          console.info('Coordinate1:', 'x:' + info1.screenOffset.x.toString(), ' y:', info1.screenOffset.y.toString())
          const info2 = this.getUIContext().getComponentUtils().getRectangleById('item2')
          console.info('Coordinate2:', 'x:', info2.screenOffset.x.toString(), ' y:', info2.screenOffset.y.toString())
        }, 1000);
      })
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The achieved effect and returned information are as follows:

cke_1377.png

I Coordinate 1: x: 570.5 y: 136 I Coordinate 2: x: 570.5 y: 136
Enter fullscreen mode Exit fullscreen mode

It can be observed that the screenOffset values of Component 1 and Component 2 are exactly the same.

Background Knowledge

  • componentUtilsAPI: Provides the capability to obtain the coordinates and size of a component's drawing area. The screenOffset in the returned ComponentInfo represents the position information of the component on the screen.
  • rotate: Allows you to rotate the component.

Solution

The abnormal content of ComponentInfo is caused by improper layout. Correct coordinates can be obtained after no longer using the nested RelativeContainer layout.

@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('Coordinate1:', '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('Coordinate2:', 'x:', modePosition.screenOffset.x.toString(), ' y:',
            modePosition.screenOffset.y.toString())
        })
        .margin({ top: -25 })
        .id('Item2')
      }
      .width(300).height(300)
      .border({ width: 2, color: '#6699FF' })
    }
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode
Coordinate 1: x: 570 y: 14
Coordinate 2: x: 1001 y: 573
Enter fullscreen mode Exit fullscreen mode

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

Verification Result

cke_14329.png

-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 and above for compilation and execution.

Written by Recep Sadullah Yegin

Top comments (0)