智能表如何适配智慧手势
===========

#### 问题现象

智慧手势是智能穿戴设备除屏幕交互、表冠交互和按键交互外的独特感知交互方式，应用如何进行适配？

#### 效果预览

1.  佩戴智能表，开启智慧手势识别开关：设置-手势-智慧手势识别。打开应用：
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/e1/v3/BcSNbiSxT1Kz48gMO5MDAg/zh-cn_image_0000002658804083.png?HW-CC-KV=V1&HW-CC-Date=20260709T134104Z&HW-CC-Expire=86400&HW-CC-Sign=375A2B1767B182AAFBCB7BE364D647E05F0F187688DFE01B92DFC15B87F6ADA4 "点击放大")
    
2.  捏合确认，第一个按钮文字变为“Confirmed”：
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/fc/v3/kDgJiwvzQkGUsG8YaIeXaw/zh-cn_image_0000002628564720.png?HW-CC-KV=V1&HW-CC-Date=20260709T134104Z&HW-CC-Expire=86400&HW-CC-Sign=8BB1A0DFC5BC13943694220B1BB951193C76CA66B5C8109ECD73530F42E63502 "点击放大")
    
3.  滑动切焦，焦点从第一个按钮切换到第二个按钮：
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/e5/v3/QwN5ptBwQ_ieQv-YAMuDnw/zh-cn_image_0000002658924027.png?HW-CC-KV=V1&HW-CC-Date=20260709T134104Z&HW-CC-Expire=86400&HW-CC-Sign=E504F44C8B25AF8722F3544A3A533E71BA24F4BA9DD9D100DFE01AF049C0E6FB "点击放大")
    
4.  捏合确认，第二个按钮文字变为“Confirmed”：
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/9b/v3/DBdGclCJRuyjSNJ8X5jE2g/zh-cn_image_0000002628404816.png?HW-CC-KV=V1&HW-CC-Date=20260709T134104Z&HW-CC-Expire=86400&HW-CC-Sign=D1CB7E0E0E28F88AFF2DDEC4DEE17EC4E5D3F0F3482710351140CB76FEEECA4B "点击放大")
    

#### 背景知识

*   使用智慧手势功能要确保设备上的智慧手势识别开关已打开。
*   手势类型包括捏合确认和滑动切焦。捏合确认会触发组件的[onKeyEvent](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-events-key#onkeyevent)事件，KeyCode为KEYCODE\_ENTER，type为KeyType.Down。滑动切焦会分别触发失焦组件和获焦组件的[onBlur](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-focus-event#onblur)和[onFocus](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-focus-event#onfocus)事件。

#### 解决方案

1.  使用[activate](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-uicontext-focuscontroller#activate14)激活当前界面的焦点激活态。
    
    aboutToAppear(): void {
      this.getUIContext().getFocusController().activate(true, false);
    }
    
2.  激活焦点激活态后，可调用[requestFocus](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-uicontext-focuscontroller#requestfocus12)方法使目标组件获得焦点，随后手势操作方可生效。
    
    onDidBuild(): void {
      try {
      _  // register a button to get focus by default._
        this.getUIContext().getFocusController().requestFocus('btn1');
      } catch (error) {
        console.error(\`requestFocus function error. Code is ${error.code}, message is ${error.message}.\`);
      }
    }
    
3.  捏合确认会触发组件的onKeyEvent事件，KeyCode为KEYCODE\_ENTER，type为KeyType.Down，应用可以在该条件触发后进行功能执行。
    
    .onKeyEvent((event: KeyEvent) \=\> {
      if (event.keyCode \=== KeyCode.KEYCODE\_ENTER && event.type \=== KeyType.Down) {
       _ // Trigger the pinching gesture_
        this.oneButton1Text \= 'Confirmed';
      }
    });
    
4.  滑动切焦会分别触发失焦组件和获焦组件的onBlur和onFocus事件，应用可以在该条件触发后进行功能执行。
    
    .onFocus(() \=\> {
      this.oneButton1Text \= 'One';
      this.oneButton2Text \= 'Two';
    })
    .onBlur(() \=\> {
      this.oneButton1Text \= 'One';
    })
    
5.  退出页面时，设置当前界面的焦点激活态为false，退出焦点激活态。
    
    aboutToDisappear(): void {
      this.getUIContext().getFocusController().activate(false);
    }
    

完整示例参考如下：

import { KeyCode } from '@kit.InputKit';
import { ColorMetrics, LengthMetrics } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  @State oneButton1Text: string \= 'One';
  @State oneButton2Text: string \= 'Two';

  aboutToAppear(): void {
    this.getUIContext().getFocusController().activate(true, false);
  }

  onDidBuild(): void {
    try {
   _   // register a button to get focus by default._
      this.getUIContext().getFocusController().requestFocus('btn1');
    } catch (error) {
      console.error(\`requestFocus function error. Code is ${error.code}, message is ${error.message}.\`);
    }
  }

  aboutToDisappear(): void {
    this.getUIContext().getFocusController().activate(false);
  }

  build() {
    NavDestination() {
      Scroll() {
        Column({ space: 20 }) {
          Button(this.oneButton1Text)
            .width(165)
            .height(40)
            .focusBox({
              margin: LengthMetrics.px(10),
              strokeColor: ColorMetrics.rgba(255, 255, 255),
              strokeWidth: LengthMetrics.px(5)
            })
            .defaultFocus(true)
            .id('btn1')

            .onFocus(() \=\> {
              this.oneButton1Text \= 'One';
              this.oneButton2Text \= 'Two';
            })
            .onBlur(() \=\> {
              this.oneButton1Text \= 'One';
            })
            .onKeyEvent((event: KeyEvent) \=\> {
              if (event.keyCode \=== KeyCode.KEYCODE\_ENTER && event.type \=== KeyType.Down) {
             _   // Trigger the pinching gesture_
                this.oneButton1Text \= 'Confirmed';
              }
            });
          Button(this.oneButton2Text)
            .width(165)
            .height(40)
            .focusBox({
              margin: LengthMetrics.px(10),
              strokeColor: ColorMetrics.rgba(255, 255, 255),
              strokeWidth: LengthMetrics.px(5)
            })
            .onFocus(() \=\> {
              this.oneButton1Text \= 'One';
              this.oneButton2Text \= 'Two';
            })
            .onBlur(() \=\> {
              this.oneButton2Text \= 'Two';
            })
            .onKeyEvent((event: KeyEvent) \=\> {
              if (event.keyCode \=== KeyCode.KEYCODE\_ENTER && event.type \=== KeyType.Down) {
          _      // Trigger the pinching gesture_
                this.oneButton2Text \= 'Confirmed';
              }
            });

        }
        .alignItems(HorizontalAlign.Center)
        .justifyContent(FlexAlign.Center)
        .width('100%')
        .height('100%');
      };
    }
    .hideTitleBar(true)
    .width('100%')
    .height('100%');
  }
}