• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Focus Control
2
3Focus control attributes set whether a component is focusable and how it participates in focus navigation.
4
5>  **NOTE**
6>
7>  The APIs of this module are supported since API version 8. Updates will be marked with a superscript to indicate their earliest API version.
8
9## focusable
10
11focusable(value: boolean)
12
13Whether the current component is focusable.
14
15**System capability**: SystemCapability.ArkUI.ArkUI.Full
16
17**Parameters**
18
19| Name| Type   | Mandatory| Description                                                        |
20| ------ | ------- | ---- | ------------------------------------------------------------ |
21| value  | boolean | Yes  | Whether the current component is focusable.<br>**NOTE**<br>Components that have default interaction logic, such as **\<Button>** and **\<TextInput>**, are focusable by default. Other components, such as **\<Text>** and **\<Image>**, are not focusable by default. Only focusable components can trigger a [focus event](ts-universal-focus-event.md).|
22
23## tabIndex<sup>9+</sup>
24
25tabIndex(index: number)
26
27Tab order of the component in sequential focus navigation with the **Tab** key.
28
29**System capability**: SystemCapability.ArkUI.ArkUI.Full
30
31**Parameters**
32
33| Name| Type  | Mandatory| Description                                                        |
34| ------ | ------ | ---- | ------------------------------------------------------------ |
35| index  | number | Yes  | Tab order of the component in sequential focus navigation with the **Tab** key. When components with positive **tabIndex** values are present, only these components are reachable through sequential focus navigation, and they are navigated cyclically in ascending order based on the **tabIndex** value. When components with positive **tabIndex** values are not present, those components with a **tabIndex** value of **0** are navigated based on the preset focus navigation rule.<br>- **tabIndex** >= 0: The component is focusable and can be reached through sequential keyboard navigation.<br>- **tabIndex** < 0 (usually **tabIndex** = -1): The component is focusable, but cannot be reached through sequential keyboard navigation.<br>Default value: **0**|
36
37## defaultFocus<sup>9+</sup>
38
39defaultFocus(value: boolean)
40
41Specifies whether to set the component as the default focus of the container.
42
43**System capability**: SystemCapability.ArkUI.ArkUI.Full
44
45**Parameters**
46
47| Name| Type   | Mandatory| Description                                                        |
48| ------ | ------- | ---- | ------------------------------------------------------------ |
49| value  | boolean | Yes  | Whether to set the component as the default focus of the page. This parameter takes effect only when the page is new and accessed for the first time.<br>Default value: **false**<br>**NOTE**<br><br>The value **true** means to set the component as the default focus, and the value **false** has no effect.<br>If **defaultFocus(true)** is not set for any component on the page, the default focus is the root container.<br>If **defaultFocus(true)** is set for multiple components on the page, the first component found in the component tree in-depth traversal is used as the default focus.|
50
51## groupDefaultFocus<sup>9+</sup>
52
53groupDefaultFocus(value: boolean)
54
55Specifies whether to set the component as the default focus of the container.
56
57**System capability**: SystemCapability.ArkUI.ArkUI.Full
58
59**Parameters**
60
61| Name| Type   | Mandatory| Description                                                        |
62| ------ | ------- | ---- | ------------------------------------------------------------ |
63| value  | boolean | Yes  | Whether to set the component as the default focus of the parent container. This parameter takes effect only when the container is new and obtains focus for the first time.<br>Default value: **false**<br>**NOTE**<br><br>This parameter must be used together with [tabIndex](#tabindex9). When **tabIndex** is set for a container and **groupDefaultFocus(true)** is set for a child in the container or for the container itself, then when the container obtains focus for the first time through sequential Tab navigation, the focus automatically moves to the specified component. If **groupDefaultFocus(true)** is set for multiple components in the container (including the container itself), the first component found in the component tree in-depth traversal receives the focus.|
64
65## focusOnTouch<sup>9+</sup>
66
67focusOnTouch(value: boolean)
68
69Whether the component is focusable on touch.
70
71**System capability**: SystemCapability.ArkUI.ArkUI.Full
72
73**Parameters**
74
75| Name| Type   | Mandatory| Description                                                        |
76| ------ | ------- | ---- | ------------------------------------------------------------ |
77| value  | boolean | Yes  | Whether the component is focusable on touch.<br>Default value: **false**<br>**NOTE**<br>The component is focusable only when it is touchable or clickable.|
78
79## focusControl<sup>9+</sup>
80
81Implements focus control.
82
83### requestFocus<sup>9+</sup>
84
85requestFocus(value: string): boolean
86
87Requests the focus to move to the specified component. This API can be used in global method statements.
88
89**Parameters**
90
91| Name| Type| Mandatory| Description|
92| ----- | ------ | ---- | ---- |
93| value | string | Yes  | String bound to the target component using the **key(value: string)**.|
94
95**Return value**
96
97| Type| Description|
98| ------- | ---- |
99| boolean | Returns whether the focus is successfully moved to the target component. Returns **true** if the specified component exists and the focus is successfully moved to the target component; returns **false** otherwise.|
100
101>  **NOTE**
102>
103>  The following components support focus control: **\<TextInput>**, **\<TextArea>**, **\<Search>**, **\<Button>**, **\<Text>**, **\<Image>**, **\<List>**, and **\<Grid>**. Currently, the running effect of the focus event can be displayed only on a real device.
104
105## Example
106
107### Example 1
108
109This example shows how to use **defaultFocus**, **groupDefaultFocus**, and **focusOnTouch**.
110
111**defaultFocus** sets the bound component as the initial focus of the page after the page is created. **groupDefaultFocus** sets the bound component as the initial focus of the **tabIndex** container after the container is created. **focusOnTouch** sets the bound component to obtain focus upon being clicked.
112
113```ts
114// focusTest.ets
115@Entry
116@Component
117struct FocusableExample {
118  @State inputValue: string = ''
119
120  build() {
121    Scroll() {
122      Row({ space: 20 }) {
123        Column({ space: 20 }) {
124          Column({ space: 5 }) {
125            Button('Group1')
126              .width(165)
127              .height(40)
128              .fontColor(Color.White)
129              .focusOnTouch(true)           // The button is focusable on touch.
130            Row({ space: 5 }) {
131              Button()
132                .width(80)
133                .height(40)
134                .fontColor(Color.White)
135              Button()
136                .width(80)
137                .height(40)
138                .fontColor(Color.White)
139                .focusOnTouch(true)           // The button is focusable on touch.
140            }
141            Row({ space: 5 }) {
142              Button()
143                .width(80)
144                .height(40)
145                .fontColor(Color.White)
146              Button()
147                .width(80)
148                .height(40)
149                .fontColor(Color.White)
150            }
151          }.borderWidth(2).borderColor(Color.Red).borderStyle(BorderStyle.Dashed)
152          .tabIndex(1)                      // The column is the initial component to have focus in sequential keyboard navigation.
153          Column({ space: 5 }) {
154            Button('Group2')
155              .width(165)
156              .height(40)
157              .fontColor(Color.White)
158            Row({ space: 5 }) {
159              Button()
160                .width(80)
161                .height(40)
162                .fontColor(Color.White)
163              Button()
164                .width(80)
165                .height(40)
166                .fontColor(Color.White)
167                .groupDefaultFocus(true)      // The button obtains focus when its upper-level column is in focus.
168            }
169            Row({ space: 5 }) {
170              Button()
171                .width(80)
172                .height(40)
173                .fontColor(Color.White)
174              Button()
175                .width(80)
176                .height(40)
177                .fontColor(Color.White)
178            }
179          }.borderWidth(2).borderColor(Color.Green).borderStyle(BorderStyle.Dashed)
180          .tabIndex(2)                      // The column is the second component to have focus in sequential keyboard navigation.
181        }
182        Column({ space: 5 }) {
183          TextInput({placeholder: 'input', text: this.inputValue})
184            .onChange((value: string) => {
185              this.inputValue = value
186            })
187            .width(156)
188            .defaultFocus(true)             // The <TextInput> component is the initial default focus of the page.
189          Button('Group3')
190            .width(165)
191            .height(40)
192            .fontColor(Color.White)
193          Row({ space: 5 }) {
194            Button()
195              .width(80)
196              .height(40)
197              .fontColor(Color.White)
198            Button()
199              .width(80)
200              .height(40)
201              .fontColor(Color.White)
202          }
203          Button()
204            .width(165)
205            .height(40)
206            .fontColor(Color.White)
207          Row({ space: 5 }) {
208            Button()
209              .width(80)
210              .height(40)
211              .fontColor(Color.White)
212            Button()
213              .width(80)
214              .height(40)
215              .fontColor(Color.White)
216          }
217          Button()
218            .width(165)
219            .height(40)
220            .fontColor(Color.White)
221          Row({ space: 5 }) {
222            Button()
223              .width(80)
224              .height(40)
225              .fontColor(Color.White)
226            Button()
227              .width(80)
228              .height(40)
229              .fontColor(Color.White)
230          }
231        }.borderWidth(2).borderColor(Color.Orange).borderStyle(BorderStyle.Dashed)
232        .tabIndex(3)                      // The column is the third component to have focus in sequential keyboard navigation.
233      }.alignItems(VerticalAlign.Top)
234    }
235  }
236}
237```
238Diagrams:
239
240When you press the **Tab** key for the first time, the focus switches to the component bound to **defaultFocus**.
241
242![defaultFocus](figures/defaultFocus.png)
243
244When you press the **Tab** key for the second time, the focus switches to the container that matches **tabIndex(1)** and automatically moves to the component bound to **groupDefaultFocus**.
245
246![groupDefaultFocus1](figures/groupDefaultFocus1.png)
247
248When you press the **Tab** key for the third time, the focus switches to the container that matches **tabIndex(2)** and automatically moves to the component bound to **groupDefaultFocus**.
249
250![groupDefaultFocus2](figures/groupDefaultFocus2.png)
251
252When you press the **Tab** key for the fourth time, the focus switches to the container that matches **tabIndex(3)** and automatically moves to the component bound to **groupDefaultFocus**.
253
254![groupDefaultFocus3](figures/groupDefaultFocus3.png)
255
256Click the component bound to **focusOnTouch**. The component then obtains focus.
257
258![focusOnTouch](figures/focusOnTouch.png)
259
260### Example 2
261
262This example shows how to use **focusControl.requestFocus** to move the focus to the specified component.
263
264```ts
265// requestFocus.ets
266import promptAction from '@ohos.promptAction';
267
268@Entry
269@Component
270struct RequestFocusExample {
271  @State idList: string[] = ['A', 'B', 'C', 'D', 'E', 'F', 'LastPageId']
272  @State selectId: string = 'LastPageId'
273
274  build() {
275    Column({ space:20 }){
276      Row({space: 5}) {
277        Button("id: " + this.idList[0] + " focusable(false)")
278          .width(200).height(70).fontColor(Color.White)
279          .key(this.idList[0])
280          .focusable(false)
281        Button("id: " + this.idList[1])
282          .width(200).height(70).fontColor(Color.White)
283          .key(this.idList[1])
284      }
285      Row({space: 5}) {
286        Button("id: " + this.idList[2])
287          .width(200).height(70).fontColor(Color.White)
288          .key(this.idList[2])
289        Button("id: " + this.idList[3])
290          .width(200).height(70).fontColor(Color.White)
291          .key(this.idList[3])
292      }
293      Row({space: 5}) {
294        Button("id: " + this.idList[4])
295          .width(200).height(70).fontColor(Color.White)
296          .key(this.idList[4])
297        Button("id: " + this.idList[5])
298          .width(200).height(70).fontColor(Color.White)
299          .key(this.idList[5])
300      }
301      Row({space: 5}) {
302        Select([{value: this.idList[0]},
303                {value: this.idList[1]},
304                {value: this.idList[2]},
305                {value: this.idList[3]},
306                {value: this.idList[4]},
307                {value: this.idList[5]},
308                {value: this.idList[6]}])
309          .value(this.selectId)
310          .onSelect((index: number) => {
311            this.selectId = this.idList[index]
312          })
313        Button("RequestFocus")
314          .width(200).height(70).fontColor(Color.White)
315          .onClick(() => {
316            let res = focusControl.requestFocus(this.selectId)      // Move the focus to the component specified by this.selectId.
317            if (res) {
318              promptAction.showToast({message: 'Request success'})
319            } else {
320              promptAction.showToast({message: 'Request failed'})
321            }
322          })
323      }
324    }.width('100%').margin({ top:20 })
325  }
326}
327```
328
329Diagrams:
330
331Press the **Tab** key to activate the focus state.
332Below shows how the UI behaves when you request focus for a component that does not exist.
333
334![requestFocus1](figures/requestFocus1.png)
335
336Below shows how the UI behaves when you request focus for a component that is not focusable.
337
338![requestFocus2](figures/requestFocus2.png)
339
340Below shows how the UI behaves when you request focus for a focusable component.
341
342![requestFocus3](figures/requestFocus3.png)
343