怎么解决进入RichEditor组件页面无法自动拉起软键盘的问题
================================

#### 问题现象

进入到某个含有RichEditor组件的页面，没有自动拉起软键盘，需要点击后才能拉起软键盘。

#### 背景知识

RichEditor是支持图文混排和文本交互式编辑的组件，需要通过[主动获取当前页面焦点](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-focus#requestfocus9)拉起软键盘。

#### 问题定位

RichEditor组件无法拉起软键盘，说明当前页面焦点不在该组件上。因此需要确认当前页面焦点。

1.  首先查看RichEditor组件有没有设置获取焦点。通过实现onFocus获取焦点监听事件，查看是否执行。
2.  排查当前页面默认焦点是否冲突。需要排查当前页面布局下，其他组件（包括自定义组件）是否也获取焦点。
3.  排查具体哪个组件获取了焦点。在所有获取焦点组件下实现onFocus获取焦点监听事件，查看最后具体哪个组件获得了当前页面焦点。

#### 分析结论

经过排查，发现是由于某个自定义组件中也设置了defaultFocus属性为true，导致RichEditor没有获取到焦点，无法拉起软键盘。

@Entry
@Component
struct Index {
  controller: RichEditorController \= new RichEditorController();

  build() {
    Column() {
      _// 内部设置了defaultFocus属性为true。_
      RichEditor({ controller: this.controller })
        .focusable(true)
        .onFocus(() \=\> {
          console.info('RichEditor onfocus')
        })
        .key('editor')
    }
    .width('100%')
    .height('100%')
  }
}

#### 修改建议

1.  排查删除不必要的组件获取焦点。
2.  设置RichEditor组件获取焦点，具体有如下两种方式：
    *   **方式一**：设置RichEditor组件的defaultFocus属性为true。
        
        @Component
        struct Solution1 {
          controller: RichEditorController \= new RichEditorController();
        
          build() {
            Column() {
              RichEditor({ controller: this.controller })
                .focusable(true)
                .onFocus(() \=\> {
                  console.info('RichEditor onfocus');
                })
                .defaultFocus(true)
                .key('editor')
            }
            .width('100%')
            .height('100%')
          }
        }
        
    *   **方式二**：通过requestFocus在页面展示或者组件挂载后获取焦点。
        
        @Component
        struct Solution2 {
          controller: RichEditorController \= new RichEditorController();
        
          aboutToAppear(): void {
            focusControl.requestFocus('editor'); _//_ _页面展示时获取_
          }
        
          build() {
            Column() {
              RichEditor({ controller: this.controller })
                .focusable(true)
                .onFocus(() \=\> {
                  console.info('RichEditor onfocus');
                })
                .key('editor')
                .onAppear(() \=\> {
                  focusControl.requestFocus('editor'); _// 组件挂载时_
                })
            }
            .width('100%')
            .height('100%')
          }
        }
        

完整示例参考如下：

@Entry
@Component
struct RichEditorFocusDemo {
  private controller: TabsController \= new TabsController();

  build() {
    Column() {
      Tabs({ barPosition: BarPosition.End, controller: this.controller }) {
        TabContent() {
          Solution1();
        }.width('100%')
        .tabBar('solution1')
        TabContent() {
          Solution2();
        }.width('100%')
        .tabBar('solution2')
      }
    }
    .width('100%')
    .height('100%')
  }
}

@Component
struct Solution1 {
  controller: RichEditorController \= new RichEditorController();

  build() {
    Column() {
      RichEditor({ controller: this.controller })
        .focusable(true)
        .onFocus(() \=\> {
          console.info('RichEditor onfocus');
        })
        .defaultFocus(true)
        .key('editor')
    }
    .width('100%')
    .height('100%')
  }
}

@Component
struct Solution2 {
  controller: RichEditorController \= new RichEditorController();

  aboutToAppear(): void {
    focusControl.requestFocus('editor'); _// 页面展示时获取_
  }

  build() {
    Column() {
      RichEditor({ controller: this.controller })
        .focusable(true)
        .onFocus(() \=\> {
          console.info('RichEditor onfocus');
        })
        .key('editor')
        .onAppear(() \=\> {
          focusControl.requestFocus('editor'); _//_ _组件挂载时_
        })
    }
    .width('100%')
    .height('100%')
  }
}

#### 总结

1.  复杂的页面需要仔细排查是否只有一个组件有默认焦点，避免冲突。
2.  通过设置defaultFocus属性或者requestFocus都可以首次让RichEditor获取焦点拉起软键盘。requestFocus方式能动态控制获取焦点的组件，通过传入其他组件的Key值，能实现代码控制收起软键盘的效果。