如何实现三键导航的监听与避让
==============

**解决措施**

1、通过[settings.registerKeyObserver](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-settings#settingsregisterkeyobserver11)监听三键导航的开启。

settings.registerKeyObserver(this.getUIContext().getHostContext(), 'float\_navigation\_info',
  settings.domainName.USER\_PROPERTY, () => {
    this.adaptLayout();
  });

2、通过[setting.getValue](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-settings#settingsgetvalue11)获取导航的信息。

settings.getValue(this.getUIContext().getHostContext(), 'float\_navigation\_info',
  settings.domainName.USER\_PROPERTY).then((data: string) => {
  if (data) {
    let navigationInfo = JSON.parse(data) as NavigationButtonInfo;
    this.adaptValue = navigationInfo.getAdaptValue();
  }
})

3、定义三键导航信息。

class NavigationButtonInfo {
 _ // Display Status: -1 Not displayed; 0 Appears in a three-key form; 1 Displayed as a floating ball_
  private showType: number = -1;
 _ // Three-Key navigation location area: x coordinate; y coordinate; Width of the triple-key area; Triple key area height; unit: px_
  private region: number\[\] = \[0, 0, 0, 0\];

  _// Obtain the adaptation area and implement this function as required_
  public getAdaptValue(): number {
 _   // If the three keys are displayed and an app is in full screen, the width of the three keys is used as the adaptation value_
    _// this.region\[2\] < this.region\[3\] This indicates that the three buttons are displayed at the side of the screen when the screen is in landscape mode._
    if (this.showType === 0 && this.region\[2\] < this.region\[3\]) {
      return this.region\[2\];
    } else {
      return 0;
    }
  }
}

4、根据region中的布局信息进行适配。

.padding({ right: this.getUIContext().px2vp(this.adaptValue) })

示例代码参考如下：

import settings from '@ohos.settings';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
import window from '@ohos.window';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  @State adaptValue: number = 0;

  aboutToAppear(): void {
    this.watchNavigationButtonChange();
    window.getLastWindow(this.getUIContext().getHostContext(), ((err: BusinessError, data) => {
      data.setWindowLayoutFullScreen(true);
    }));
  }

 _ /__/ Monitor the changes of three-key navigation information_
  private watchNavigationButtonChange(): void {
    this.adaptLayout();

    settings.registerKeyObserver(this.getUIContext().getHostContext(), 'float\_navigation\_info',
      settings.domainName.USER\_PROPERTY, () => {
        this.adaptLayout();
      });
  }

  _// Adapt the app layout based on the Three Key Navigation information_
  private adaptLayout(): void {
    try {
      settings.getValue(this.getUIContext().getHostContext(), 'float\_navigation\_info',
        settings.domainName.USER\_PROPERTY).then((data: string) => {
        if (data) {
          let navigationInfo = JSON.parse(data) as NavigationButtonInfo;
          this.adaptValue = navigationInfo.getAdaptValue();
        }
      })
    } catch (e) {
      this.adaptValue = 0;
      hilog.warn(0, 'tag', 'adaptMargin err:' + e);
    }
  }

  build() {
    RelativeContainer() {
      Column() {
        Row() {
          Text(this.message)
            .id('HelloWorld')
            .fontSize($r('app.float.page\_text\_font\_size'))
            .fontWeight(FontWeight.Bold)
            .alignRules({
              center: { anchor: '\_\_container\_\_', align: VerticalAlign.Center },
              middle: { anchor: '\_\_container\_\_', align: HorizontalAlign.Center }
            })
            .onClick(() => {
              this.message = 'Welcome';
            })
        }
        .backgroundColor(Color.Red)
        .height('100%')
        .width('100%')
      }
      .backgroundColor(Color.Yellow)
      .padding({ right: this.getUIContext().px2vp(this.adaptValue) })
    }
    .height('100%')
    .width('100%')
  }
}

class NavigationButtonInfo {
 _ // Display Status: -1 Not displayed; 0 Appears in a three-key form; 1 Displayed as a floating ball_
  private showType: number = -1;
  /_/ Three-Key navigation location area: x coordinate; y coordinate; Width of the triple-key area; Triple key area height; unit: px_
  private region: number\[\] = \[0, 0, 0, 0\];

  /_/ Obtain the adaptation area and implement this function as required_
  public getAdaptValue(): number {
    _// If the three keys are displayed and an app is in full screen, the width of the three keys is used as the adaptation value_
    _// this.region\[2\] < this.region\[3\] This indicates that the three buttons are displayed at the side of the screen when the screen is in landscape mode._
    if (this.showType === 0 && this.region\[2\] < this.region\[3\]) {
      return this.region\[2\];
    } else {
      return 0;
    }
  }
}

导航条、状态栏、挖孔区沉浸式方案参考链接：[实现沉浸式效果](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-multi-device-window-immersive#section180431120426)。