• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 焦点控制
2
3自定义组件的走焦效果,可设置组件是否走焦和具体的走焦顺序,tab键或者方向键切换焦点。
4
5>  **说明:**
6>
7>  从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
8
9## focusable
10
11focusable(value: boolean)
12
13设置当前组件是否可以获焦。
14
15**系统能力:** SystemCapability.ArkUI.ArkUI.Full
16
17**参数:**
18
19| 参数名 | 类型    | 必填 | 说明                                                         |
20| ------ | ------- | ---- | ------------------------------------------------------------ |
21| value  | boolean | 是   | 设置当前组件是否可以获焦。<br/>**说明:**<br/>存在默认交互逻辑的组件例如[Button](ts-basic-components-button.md)、[TextInput](ts-basic-components-textinput.md)等,默认即为可获焦,[Text](ts-basic-components-text.md)、[Image](ts-basic-components-image.md)等组件则默认状态为不可获焦。不可获焦状态下,无法触发[焦点事件](ts-universal-focus-event.md)。 |
22
23## tabIndex<sup>9+</sup>
24
25tabIndex(index: number)
26
27自定义组件tab键走焦能力。
28
29**系统能力:** SystemCapability.ArkUI.ArkUI.Full
30
31**参数:**
32
33| 参数名 | 类型   | 必填 | 说明                                                         |
34| ------ | ------ | ---- | ------------------------------------------------------------ |
35| index  | number | 是   | 自定义组件tab键走焦能力。若有配置了tabIndex大于0的组件,则tab键走焦只会在tabIndex大于0的组件内按照tabIndex的值从小到大并循环依次走焦。若没有配置tabIndex大于0的组件,则tabIndex等于0的组件按照组件预设的走焦规则走焦。<br />- tabIndex >= 0:表示元素是可聚焦的,并且可以通过tab键走焦来访问到该元素。<br />- tabIndex < 0(通常是tabIndex = -1):表示元素是可聚焦的,但是不能通过tab键走焦来访问到该元素。<br/>默认值:0 |
36
37## defaultFocus<sup>9+</sup>
38
39defaultFocus(value: boolean)
40
41设置当前组件是否为当前页面上的默认焦点。
42
43**系统能力:** SystemCapability.ArkUI.ArkUI.Full
44
45**参数:**
46
47| 参数名 | 类型    | 必填 | 说明                                                         |
48| ------ | ------- | ---- | ------------------------------------------------------------ |
49| value  | boolean | 是   | 设置当前组件是否为当前页面上的默认焦点,仅在初次创建的页面第一次进入时生效。<br/>默认值:false<br/>**说明:** <br/>值为true则表示为默认焦点,值为false无效。<br/>若页面内无任何组件设置defaultFocus(true),页面的默认焦点就是页面的根容器。<br/>若某页面内有多个组件设置了defaultFocus(true),则以组件树深度遍历找到的第一个组件为默认焦点。 |
50
51## groupDefaultFocus<sup>9+</sup>
52
53groupDefaultFocus(value: boolean)
54
55设置当前组件是否为当前组件所在容器获焦时的默认焦点。
56
57**系统能力:** SystemCapability.ArkUI.ArkUI.Full
58
59**参数:**
60
61| 参数名 | 类型    | 必填 | 说明                                                         |
62| ------ | ------- | ---- | ------------------------------------------------------------ |
63| value  | boolean | 是   | 设置当前组件是否为当前组件所在容器获焦时的默认焦点,仅在初次创建容器节点第一次获焦时生效。<br/>默认值:false<br/>**说明:** <br/>必须与[tabIndex](#tabindex9)联合使用,当某个容器设置了tabIndex,且容器内某子组件或容器自身设置了groupDefaultFocus(true),当该容器首次TAB键获焦时,会自动将焦点转移至该指定的组件上。若容器内(包含容器本身)有多个组件设置了groupDefaultFocus(true),则以组件树深度遍历找到的第一个组件为最终结果。 |
64
65## focusOnTouch<sup>9+</sup>
66
67focusOnTouch(value: boolean)
68
69设置当前组件是否支持点击获焦能力。
70
71**系统能力:** SystemCapability.ArkUI.ArkUI.Full
72
73**参数:**
74
75| 参数名 | 类型    | 必填 | 说明                                                         |
76| ------ | ------- | ---- | ------------------------------------------------------------ |
77| value  | boolean | 是   | 设置当前组件是否支持点击获焦能力。<br/>默认值:false<br/>**说明:** <br/>仅在组件可点击时才能正常获取焦点。 |
78
79## focusControl<sup>9+</sup>
80
81焦点控制模块
82
83### requestFocus<sup>9+</sup>
84
85requestFocus(value: string): boolean
86
87方法语句中可使用的全局接口,调用此接口可以主动让焦点转移至参数指定的组件上。
88
89**参数:**
90
91| 名称 | 类型 | 必填 | 描述 |
92| ----- | ------ | ---- | ---- |
93| value | string | 是   | 目标组件使用接口key(value: string)或id(value: string)绑定的字符串。 |
94
95**返回值:**
96
97| 类型 | 说明 |
98| ------- | ---- |
99| boolean | 返回是否成功给目标组件申请到焦点。若参数指向的目标组件存在,且目标组件可获焦,则返回true,否则返回false。 |
100
101>  **说明:**
102>
103>  支持焦点控制的组件:[TextInput](ts-basic-components-textinput.md)、[TextArea](ts-basic-components-textarea.md)、[Search](ts-basic-components-search.md)、[Button](ts-basic-components-button.md)、[Text](ts-basic-components-text.md)、[Image](ts-basic-components-image.md)、[List](ts-container-list.md)、[Grid](ts-container-grid.md)。焦点事件当前仅支持在真机上显示运行效果。
104
105
106## 示例
107
108### 示例1
109
110defaultFocus/groupDefaultFocus/focusOnTouch示例代码:
111
112defaultFocus可以使绑定的组件成为页面创建后首次获焦的焦点。groupDefaultFocus可以使绑定的组件成为tabIndex容器创建后首次获焦的焦点。focusOnTouch可以使绑定的组件点击后立即获焦。
113
114```ts
115// focusTest.ets
116@Entry
117@Component
118struct FocusableExample {
119  @State inputValue: string = ''
120
121  build() {
122    Scroll() {
123      Row({ space: 20 }) {
124        Column({ space: 20 }) {
125          Column({ space: 5 }) {
126            Button('Group1')
127              .width(165)
128              .height(40)
129              .fontColor(Color.White)
130              .focusOnTouch(true)           // 该Button组件点击后可获焦
131            Row({ space: 5 }) {
132              Button()
133                .width(80)
134                .height(40)
135                .fontColor(Color.White)
136              Button()
137                .width(80)
138                .height(40)
139                .fontColor(Color.White)
140                .focusOnTouch(true)           // 该Button组件点击后可获焦
141            }
142            Row({ space: 5 }) {
143              Button()
144                .width(80)
145                .height(40)
146                .fontColor(Color.White)
147              Button()
148                .width(80)
149                .height(40)
150                .fontColor(Color.White)
151            }
152          }.borderWidth(2).borderColor(Color.Red).borderStyle(BorderStyle.Dashed)
153          .tabIndex(1)                      // 该Column组件为按TAB键走焦的第一个获焦的组件
154          Column({ space: 5 }) {
155            Button('Group2')
156              .width(165)
157              .height(40)
158              .fontColor(Color.White)
159            Row({ space: 5 }) {
160              Button()
161                .width(80)
162                .height(40)
163                .fontColor(Color.White)
164              Button()
165                .width(80)
166                .height(40)
167                .fontColor(Color.White)
168                .groupDefaultFocus(true)      // 该Button组件上级Column组件获焦时获焦
169            }
170            Row({ space: 5 }) {
171              Button()
172                .width(80)
173                .height(40)
174                .fontColor(Color.White)
175              Button()
176                .width(80)
177                .height(40)
178                .fontColor(Color.White)
179            }
180          }.borderWidth(2).borderColor(Color.Green).borderStyle(BorderStyle.Dashed)
181          .tabIndex(2)                      // 该Column组件为按TAB键走焦的第二个获焦的组件
182        }
183        Column({ space: 5 }) {
184          TextInput({placeholder: 'input', text: this.inputValue})
185            .onChange((value: string) => {
186              this.inputValue = value
187            })
188            .width(156)
189            .defaultFocus(true)             // 该TextInput组件为页面的初始默认焦点
190          Button('Group3')
191            .width(165)
192            .height(40)
193            .fontColor(Color.White)
194          Row({ space: 5 }) {
195            Button()
196              .width(80)
197              .height(40)
198              .fontColor(Color.White)
199            Button()
200              .width(80)
201              .height(40)
202              .fontColor(Color.White)
203          }
204          Button()
205            .width(165)
206            .height(40)
207            .fontColor(Color.White)
208          Row({ space: 5 }) {
209            Button()
210              .width(80)
211              .height(40)
212              .fontColor(Color.White)
213            Button()
214              .width(80)
215              .height(40)
216              .fontColor(Color.White)
217          }
218          Button()
219            .width(165)
220            .height(40)
221            .fontColor(Color.White)
222          Row({ space: 5 }) {
223            Button()
224              .width(80)
225              .height(40)
226              .fontColor(Color.White)
227            Button()
228              .width(80)
229              .height(40)
230              .fontColor(Color.White)
231          }
232        }.borderWidth(2).borderColor(Color.Orange).borderStyle(BorderStyle.Dashed)
233        .tabIndex(3)                      // 该Column组件为按TAB键走焦的第三个获焦的组件
234      }.alignItems(VerticalAlign.Top)
235    }
236  }
237}
238```
239示意图:
240
241首次进入,焦点默认在defaultFocus绑定的TextInput组件上:
242
243![defaultFocus](figures/defaultFocus.png)
244
245首次按TAB键,焦点切换到tabIndex(1)的容器上,且自动走到其内部的groupDefaultFocus绑定的组件上:
246
247![groupDefaultFocus1](figures/groupDefaultFocus1.png)
248
249第二次按TAB键,焦点切换到tabIndex(2)的容器上,且自动走到其内部的groupDefaultFocus绑定的组件上:
250
251![groupDefaultFocus2](figures/groupDefaultFocus2.png)
252
253第三次按TAB键,焦点切换到tabIndex(3)的容器上,且自动走到其内部的groupDefaultFocus绑定的组件上:
254
255![groupDefaultFocus3](figures/groupDefaultFocus3.png)
256
257点击绑定了focusOnTouch的组件,组件自身获焦,焦点框被清除,再按下Tab键显示焦点框:
258
259![focusOnTouch](figures/focusOnTouch.png)
260
261### 示例2
262
263focusControl.requestFocus示例代码:
264
265使用focusControl.requestFocus接口使指定组件获取焦点。
266```ts
267// requestFocus.ets
268import promptAction from '@ohos.promptAction';
269
270@Entry
271@Component
272struct RequestFocusExample {
273  @State idList: string[] = ['A', 'B', 'C', 'D', 'E', 'F', 'LastPageId']
274  @State selectId: string = 'LastPageId'
275
276  build() {
277    Column({ space:20 }){
278      Row({space: 5}) {
279        Button("id: " + this.idList[0] + " focusable(false)")
280          .width(200).height(70).fontColor(Color.White)
281          .id(this.idList[0])
282          .focusable(false)
283        Button("id: " + this.idList[1])
284          .width(200).height(70).fontColor(Color.White)
285          .id(this.idList[1])
286      }
287      Row({space: 5}) {
288        Button("id: " + this.idList[2])
289          .width(200).height(70).fontColor(Color.White)
290          .id(this.idList[2])
291        Button("id: " + this.idList[3])
292          .width(200).height(70).fontColor(Color.White)
293          .id(this.idList[3])
294      }
295      Row({space: 5}) {
296        Button("id: " + this.idList[4])
297          .width(200).height(70).fontColor(Color.White)
298          .id(this.idList[4])
299        Button("id: " + this.idList[5])
300          .width(200).height(70).fontColor(Color.White)
301          .id(this.idList[5])
302      }
303      Row({space: 5}) {
304        Select([{value: this.idList[0]},
305                {value: this.idList[1]},
306                {value: this.idList[2]},
307                {value: this.idList[3]},
308                {value: this.idList[4]},
309                {value: this.idList[5]},
310                {value: this.idList[6]}])
311          .value(this.selectId)
312          .onSelect((index: number) => {
313            this.selectId = this.idList[index]
314          })
315        Button("RequestFocus")
316          .width(200).height(70).fontColor(Color.White)
317          .onClick(() => {
318            let res = focusControl.requestFocus(this.selectId)      // 使选中的this.selectId的组件获焦
319            if (res) {
320              promptAction.showToast({message: 'Request success'})
321            } else {
322              promptAction.showToast({message: 'Request failed'})
323            }
324          })
325      }
326    }.width('100%').margin({ top:20 })
327  }
328}
329```
330
331示意图:
332
333按下TAB键,激活焦点态显示。
334申请不存在的组件获焦:
335
336![requestFocus1](figures/requestFocus1.png)
337
338申请不可获焦的组件获焦:
339
340![requestFocus2](figures/requestFocus2.png)
341
342申请存在且可获焦的组件获焦:
343
344![requestFocus3](figures/requestFocus3.png)