• 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>  - Custom components are inherently unfocusable, and setting [focusable](#focusable) and [enabled](ts-universal-attributes-enable.md#enabled) attributes to **false** or setting the [visibility](ts-universal-attributes-visibility.md#visibility) attribute to **Hidden** or **None** does not impact their child components' capability to gain focus.
10>
11>  - Components can actively acquire focus independently of the window's focus state.
12>
13>  - For details about focus development, see [Focus Event](../../../ui/arkts-common-events-focus-event.md).
14
15## focusable
16
17focusable(value: boolean)
18
19Sets whether the component is focusable.
20
21**Atomic service API**: This API can be used in atomic services since API version 11.
22
23**System capability**: SystemCapability.ArkUI.ArkUI.Full
24
25**Parameters**
26
27| Name| Type   | Mandatory| Description                                                        |
28| ------ | ------- | ---- | ------------------------------------------------------------ |
29| value  | boolean | Yes  | Whether the component is focusable.<br>**true**: The component is focusable.<br>**false**: The component is not focusable.<br>**NOTE**<br>Components that have default interaction logic, such as [Button](ts-basic-components-button.md) and [TextInput](ts-basic-components-textinput.md), are focusable by default. Other components, such as [Text](ts-basic-components-text.md) and [Image](ts-basic-components-image.md), are not focusable by default. Only focusable components can trigger a [focus event](ts-universal-focus-event.md).|
30
31## tabIndex<sup>9+</sup>
32
33tabIndex(index: number)
34
35Sets the Tab order of the component in sequential focus navigation with the **Tab** key.
36
37**Atomic service API**: This API can be used in atomic services since API version 11.
38
39**System capability**: SystemCapability.ArkUI.ArkUI.Full
40
41**Parameters**
42
43| Name| Type  | Mandatory| Description                                                        |
44| ------ | ------ | ---- | ------------------------------------------------------------ |
45| 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** is not yet compatible with [UiExtension](../js-apis-arkui-uiExtension.md) component. As such, using **tabIndex** on a page that contains [UiExtension](../js-apis-arkui-uiExtension.md) may lead to disordered focus navigation.<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**<br> **NOTE**<br> **tabIndex** and **focusScopeId** cannot be used together.
46|
47
48## defaultFocus<sup>9+</sup>
49
50defaultFocus(value: boolean)
51
52Specifies whether to set the component as the default focus of the page.
53
54**Atomic service API**: This API can be used in atomic services since API version 11.
55
56**System capability**: SystemCapability.ArkUI.ArkUI.Full
57
58**Parameters**
59
60| Name| Type   | Mandatory| Description                                                        |
61| ------ | ------- | ---- | ------------------------------------------------------------ |
62| 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>The value **true** means to set the component as the default focus, and the value **false** has no effect.<br>If no component on the page has **defaultFocus(true)** set:<br>For API version 11 and earlier, the default focus is on the first focusable non-container component on the page.<br>For API version versions later than 11, the default focus is on the page's 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.|
63
64## groupDefaultFocus<sup>9+</sup>
65
66groupDefaultFocus(value: boolean)
67
68Specifies whether to set the component as the default focus of the container.
69
70**Atomic service API**: This API can be used in atomic services since API version 11.
71
72**System capability**: SystemCapability.ArkUI.ArkUI.Full
73
74**Parameters**
75
76| Name| Type   | Mandatory| Description                                                        |
77| ------ | ------- | ---- | ------------------------------------------------------------ |
78| 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>**true**: The component is the default focus of the parent container.<br>**false**: The component is not the default focus of the parent container.<br>Default value: **false**<br>**NOTE**<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.|
79
80## focusOnTouch<sup>9+</sup>
81
82focusOnTouch(value: boolean)
83
84Sets whether the component is focusable on touch.
85
86**Atomic service API**: This API can be used in atomic services since API version 11.
87
88**System capability**: SystemCapability.ArkUI.ArkUI.Full
89
90**Parameters**
91
92| Name| Type   | Mandatory| Description                                                        |
93| ------ | ------- | ---- | ------------------------------------------------------------ |
94| value  | boolean | Yes  | Whether the component is focusable on touch. <br>**true**: The component is focusable on touch.<br>**false**: The component is not focusable on touch.<br>Default value: **false**<br>**NOTE**<br>The component is focusable only when it is touchable.|
95
96## focusBox<sup>12+</sup>
97
98focusBox(style: FocusBoxStyle): T
99
100Sets the system focus box style for the component.
101
102**Atomic service API**: This API can be used in atomic services since API version 12.
103
104**System capability**: SystemCapability.ArkUI.ArkUI.Full
105
106**Parameters**
107
108| Name| Type| Mandatory| Description|
109| ---- | ---- | ---- | ---- |
110| style  | [FocusBoxStyle](#focusboxstyle12) | Yes  | System focus box style for the component.<br>**NOTE**<br>This style affects only the components that display the system focus box during focus traversal.|
111
112
113## focusControl<sup>9+</sup>
114
115Implements focus control.
116
117**Atomic service API**: This API can be used in atomic services since API version 11.
118
119### requestFocus<sup>9+</sup>
120
121requestFocus(value: string): boolean
122
123Requests the focus to move to the specified component. It is a global API. This API does not take effect in the current frame; the focus change will occur in the next frame. Use the [requestFocus](../js-apis-arkui-UIContext.md#requestfocus12) API in **FocusController** for immediate effect.
124
125**Atomic service API**: This API can be used in atomic services since API version 11.
126
127**Parameters**
128
129| Name| Type| Mandatory| Description|
130| ----- | ------ | ---- | ---- |
131| value | string | Yes  | String bound to the target component using **key(value: string)** or **id(value: string)**.|
132
133**Return value**
134
135| Type| Description|
136| ------- | ---- |
137| 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.|
138
139>  **NOTE**
140>
141>  The following components support focus control: [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). Currently, the running effect of the focus event can be displayed only on a real device.
142
143## FocusBoxStyle<sup>12+</sup>
144
145**Atomic service API**: This API can be used in atomic services since API version 12.
146
147| Name| Type| Mandatory| Description|
148| ---- | ---- | ---- | ---- |
149| margin  | [LengthMetrics](../js-apis-arkui-graphics.md#lengthmetrics12) | No| Distance of the focus box from the component's edge.<br>A positive number indicates the outside, and a negative number indicates the inside. The value cannot be in percentage.|
150| strokeColor  | [ColorMetrics](../js-apis-arkui-graphics.md#colormetrics12) | No| Stroke color of the focus box.|
151| strokeWidth | [LengthMetrics](../js-apis-arkui-graphics.md#lengthmetrics12) | No| Stroke width of the focus box.<br>Negative numbers and percentages are not supported.|
152
153## focusScopePriority<sup>12+</sup>
154
155focusScopePriority(scopeId: string, priority?: FocusPriority): T
156
157Sets the focus priority of this component in a specified container. It must be used together with **focusScopeId**.
158
159**Atomic service API**: This API can be used in atomic services since API version 12.
160
161**System capability**: SystemCapability.ArkUI.ArkUI.Full
162
163**Parameters**
164
165| Name| Type   | Mandatory| Description                                                        |
166| ------ | ------- | ---- | ------------------------------------------------------------ |
167| scopeId  | string | Yes  | ID of the container component where the current component's focus priority takes effect.<br>**NOTE**<br>1. The current component must be within the container identified by **scopeId**, or the container to which the current component belongs must be within the container identified by **scopeId**.<br>2. A component cannot set multiple priorities.<br>3. A container component with **focusScopeId** set cannot have its priority set.|
168| priority  | [FocusPriority](#focuspriority12)  | No  | Focus priority.<br>**NOTE**<br>If **priority** is not set, the component uses the default **AUTO** priority.<br>Impact of the priority on focus traversal and component focus:<br>1. When the container gains focus as a whole (page level switching/focus switching to a focus group/container component requesting focus with **requestFocus**), if there is a component with a priority of **PREVIOUS** within the container, that component gains focus; otherwise, the last focused component does.<br>2. When a container does not gain focus as a whole (using **Tab** or arrow keys in non-focus group scenarios), the highest priority component gets focus on first focus; subsequent focus follows position order regardless of priority.|
169
170### FocusPriority<sup>12+</sup>
171
172**Atomic service API**: This API can be used in atomic services since API version 12.
173
174**System capability**: SystemCapability.ArkUI.ArkUI.Full
175
176| Name         | Description       |
177| ----------- | --------- |
178| AUTO | Default priority, that is, the focus priority assigned by default.|
179| PRIOR | Priority that indicates the component is prioritized in the container. This level is higher than **AUTO**.|
180| PREVIOUS | Priority of a previously focused node in the container. This level is higher than **PRIOR**.|
181
182### KeyProcessingMode<sup>15+</sup>
183
184Enumerates the modes for processing key events.
185
186**Atomic service API**: This API can be used in atomic services since API version 15.
187
188**System capability**: SystemCapability.ArkUI.ArkUI.Full
189
190| Name    | Value   | Description       |
191| -----------| ----------- | --------- |
192| FOCUS_NAVIGATION  | 0 | Default value. When the current component does not consume the key event, focus navigation using the **Tab** and arrow keys preferentially stays within the current container.|
193| ANCESTOR_EVENT  | 1  |  When the current component does not consume the key event, focus navigation using the **Tab** and arrow keys is bubbled up to the parent component.|
194
195## focusScopeId<sup>12+</sup>
196
197focusScopeId(id: string, isGroup?: boolean)
198
199Assigns an ID to this container component and specifies whether the container is a focus group.
200
201**Atomic service API**: This API can be used in atomic services since API version 12.
202
203**System capability**: SystemCapability.ArkUI.ArkUI.Full
204
205**Parameters**
206
207| Name| Type   | Mandatory| Description                                                        |
208| ------ | ------- | ---- | ------------------------------------------------------------ |
209| id  | string | Yes  | ID of the current container component.<br>**NOTE**<br>The ID must be unique within a single level page.|
210| isGroup  | boolean | No  | Whether the current container component is a focus group. <br>**true**: The current container component is a focus group.<br>**false**: The current container component is not a focus group.<br>**NOTE**<br>Focus groups cannot be nested and should not be configured repeatedly.<br> The focus group and **tabIndex** cannot be used together.<br>The focus group enables the container and its elements to navigate focus according to the focus group rules as follows:<br>1. Only arrow keys are allowed for focus traversal within the focus group; the **Tab** key will move the focus out of the focus group.<br>2. When arrow keys are used to move the focus from outside the focus group to inside, if there is a component with a priority of **PREVIOUS** within the focus group, that component gains focus; otherwise, the last focused component does.|
211
212## focusScopeId<sup>14+</sup>
213
214focusScopeId(id: string, isGroup?: boolean, arrowStepOut?: boolean)
215
216Assigns an ID to this container component and specifies whether the container is a focus group.
217
218**System capability**: SystemCapability.ArkUI.ArkUI.Full
219
220**Parameters**
221
222| Name| Type   | Mandatory| Description                                                        |
223| ------ | ------- | ---- | ------------------------------------------------------------ |
224| id  | string | Yes  | ID of the current container component.<br>**NOTE**<br>The ID must be unique within a single level page.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
225| isGroup  | boolean | No  | Whether the current container component is a focus group. <br>**true**: The current container component is a focus group.<br>**false**: The current container component is not a focus group.<br>**NOTE**<br>Focus groups cannot be nested and should not be configured repeatedly.<br> The focus group and **tabIndex** cannot be used together.<br>The focus group enables the container and its elements to navigate focus according to the focus group rules as follows:<br>1. Only arrow keys are allowed for focus traversal within the focus group; the **Tab** key will move the focus out of the focus group.<br>2. When arrow keys are used to move the focus from outside the focus group to inside, if there is a component with a priority of **PREVIOUS** within the focus group, that component gains focus; otherwise, the last focused component does.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
226| arrowStepOut<sup>14+</sup>  | boolean | No  | Whether the focus can be moved out of the current focus group using arrow keys. <br>**true**: The focus can be moved out of the current focus group using arrow keys.<br>**false**: The focus cannot be moved out of the current focus group using arrow keys.<br>**Atomic service API**: This API can be used in atomic services since API version 14.|
227
228## tabStop<sup>14+</sup>
229
230tabStop(isTabStop: boolean) :T
231
232Sets whether this container component is a focus stop. During focus traversal, the focus stops at the container component serving as a focus stop.
233
234**Atomic service API**: This API can be used in atomic services since API version 14.
235
236**System capability**: SystemCapability.ArkUI.ArkUI.Full
237
238**Parameters**
239
240| Name| Type   | Mandatory| Description                                                        |
241| ------ | ------- | ---- | ------------------------------------------------------------ |
242| isTabStop  | boolean | Yes  | Whether the current container component is a focus stop. <br>**true**: The current container component is a focus stop.<br>**false**: The current container component is not a focus stop.<br>**NOTE**<br>1. To configure **tabStop**, make sure the component is a container and has focusable child components. By default, container components cannot directly gain focus.<br> 2. When [requestFocus](../js-apis-arkui-UIContext.md#requestfocus12) is used for requesting focus, if the component is a container and **tabStop** is configured, the focus can stop at the container. If **tabStop** is not configured, the component can still gain focus, even if there are other components in the focus chain with **tabStop** configured.<br>3. Containers with **tabStop** configured should not be nested more than two levels deep.<br>Focus traversal rules with **tabStop**:<br>1. During focus traversal using the **Tab** key or arrow keys, the focus stops at components with **tabStop** configured. If the focus is inside a container with **tabStop** configured, it can move to the next focusable component within the container. If the focus is outside such a container, it can move to the next focusable component outside the container.<br>2. When the focus is on a container with **tabStop** configured, pressing **Enter** moves the focus to the first focusable component inside the container. Pressing **ESC** moves the focus back to the previous component with **tabStop** configured, without exceeding the current level of the page root container. Pressing the spacebar triggers the **onClick** event of the container.<br>3. Whenever possible, avoid configuring **tabStop** on the root container. If **tabStop** is configured on the root container, the following behaviors will occur:<br>- Using [clearFocus](../js-apis-arkui-UIContext.md#clearfocus12) to clear the focus to the root container and then pressing **Enter** will move the focus to the previously focused component inside the root container.<br>- Using **ESC** to clear the focus to the root container and then pressing **Enter** will move the focus to the first focusable component inside the root container.|
243
244**Example for describing the keys and focusable components during focus traversal**
245
246![tabStop](figures/tabStop.png)
247
248If the current focus is on **button2**, pressing the **Tab** key will move the focus to **Column3**. Pressing the **Tab** key again will move the focus back to **button1**.
249
250## nextFocus<sup>18+</sup>
251
252nextFocus(nextStep: Optional\<FocusMovement>): T
253
254Sets the custom focus movement logic for the component.
255
256**Atomic service API**: This API can be used in atomic services since API version 18.
257
258**System capability**: SystemCapability.ArkUI.ArkUI.Full
259
260**Parameters**
261
262| Name| Type   | Mandatory| Description                                                        |
263| ------ | ------- | ---- | ------------------------------------------------------------ |
264| nextStep  | [FocusMovement](#focusmovement18) | No| Custom focus movement logic of the component.<br>**NOTE**<br>The default value resets **nextStep** to empty.<br>If custom focus movement is not set or the specified component does not exist, the default focus movement logic applies.|
265
266## FocusMovement<sup>18+</sup>
267
268Sets the target component for focus movement based on key presses. If it is not specified, the default focus movement logic applies.
269
270**Atomic service API**: This API can be used in atomic services since API version 18.
271
272**System capability**: SystemCapability.ArkUI.ArkUI.Full
273
274| Name| Type| Read-Only/Optional| Description|
275| ---- | ---- | ---- | ---- |
276| forward  | string | Optional| ID of the component to focus on when the **Tab** key is pressed.<br>The default value resets **forward** to empty.|
277| backward  | string | Optional| ID of the component to focus on when **Shift+Tab** is pressed.<br>The default value resets **backward** to empty.|
278| up  | string | Optional| ID of the component to focus on when the up arrow key is pressed.<br>The default value resets **up** to empty.|
279| down  | string | Optional| ID of the component to focus on when the down arrow key is pressed.<br>The default value resets **down** to empty.|
280| left  | string | Optional| ID of the component to focus on when the left arrow key is pressed.<br>The default value resets **left** to empty.|
281| right  | string | Optional| ID of the component to focus on when the right arrow key is pressed.<br>The default value resets **right** to empty.|
282
283## Example
284
285### Example 1: Setting Focus and Focus Traversal Effects for Components
286
287This example shows how to use **defaultFocus**, **groupDefaultFocus**, and **focusOnTouch**. **defaultFocus** sets the bound component as the initial focus after the page is created. **groupDefaultFocus** sets the bound component as the initial focus after the container with the specified **tabIndex** is created. **focusOnTouch** sets the bound component to obtain focus upon being clicked.
288
289```ts
290// focusTest.ets
291@Entry
292@Component
293struct FocusableExample {
294  @State inputValue: string = ''
295
296  build() {
297    Scroll() {
298      Row({ space: 20 }) {
299        Column({ space: 20 }) {
300          Column({ space: 5 }) {
301            Button('Group1')
302              .width(165)
303              .height(40)
304              .fontColor(Color.White)
305              .focusOnTouch(true)           // The button is focusable on touch.
306            Row({ space: 5 }) {
307              Button()
308                .width(80)
309                .height(40)
310                .fontColor(Color.White)
311              Button()
312                .width(80)
313                .height(40)
314                .fontColor(Color.White)
315                .focusOnTouch(true)           // The button is focusable on touch.
316            }
317            Row({ space: 5 }) {
318              Button()
319                .width(80)
320                .height(40)
321                .fontColor(Color.White)
322              Button()
323                .width(80)
324                .height(40)
325                .fontColor(Color.White)
326            }
327          }.borderWidth(2).borderColor(Color.Red).borderStyle(BorderStyle.Dashed)
328          .tabIndex(1)                      // The column is the initial component to have focus in sequential keyboard navigation.
329          Column({ space: 5 }) {
330            Button('Group2')
331              .width(165)
332              .height(40)
333              .fontColor(Color.White)
334            Row({ space: 5 }) {
335              Button()
336                .width(80)
337                .height(40)
338                .fontColor(Color.White)
339              Button()
340                .width(80)
341                .height(40)
342                .fontColor(Color.White)
343                .groupDefaultFocus(true)      // The button obtains focus when its upper-level column is in focus.
344            }
345            Row({ space: 5 }) {
346              Button()
347                .width(80)
348                .height(40)
349                .fontColor(Color.White)
350              Button()
351                .width(80)
352                .height(40)
353                .fontColor(Color.White)
354            }
355          }.borderWidth(2).borderColor(Color.Green).borderStyle(BorderStyle.Dashed)
356          .tabIndex(2)                      // The column is the second component to have focus in sequential keyboard navigation.
357        }
358        Column({ space: 5 }) {
359          TextInput({placeholder: 'input', text: this.inputValue})
360            .onChange((value: string) => {
361              this.inputValue = value
362            })
363            .width(156)
364            .defaultFocus(true)             // The <TextInput> component is the initial default focus of the page.
365          Button('Group3')
366            .width(165)
367            .height(40)
368            .fontColor(Color.White)
369          Row({ space: 5 }) {
370            Button()
371              .width(80)
372              .height(40)
373              .fontColor(Color.White)
374            Button()
375              .width(80)
376              .height(40)
377              .fontColor(Color.White)
378          }
379          Button()
380            .width(165)
381            .height(40)
382            .fontColor(Color.White)
383          Row({ space: 5 }) {
384            Button()
385              .width(80)
386              .height(40)
387              .fontColor(Color.White)
388            Button()
389              .width(80)
390              .height(40)
391              .fontColor(Color.White)
392          }
393          Button()
394            .width(165)
395            .height(40)
396            .fontColor(Color.White)
397          Row({ space: 5 }) {
398            Button()
399              .width(80)
400              .height(40)
401              .fontColor(Color.White)
402            Button()
403              .width(80)
404              .height(40)
405              .fontColor(Color.White)
406          }
407        }.borderWidth(2).borderColor(Color.Orange).borderStyle(BorderStyle.Dashed)
408        .tabIndex(3)                      // The column is the third component to have focus in sequential keyboard navigation.
409      }.alignItems(VerticalAlign.Top)
410    }
411  }
412}
413```
414Diagrams:
415
416On first-time access, the focus is on the **TextInput** component bound to **defaultFocus**.
417
418![defaultFocus](figures/defaultFocus.png)
419
420When you press the **Tab** key for the first time, the focus switches to the container that matches **tabIndex(1)** and automatically moves to the component bound to **groupDefaultFocus**.
421
422![groupDefaultFocus1](figures/groupDefaultFocus1.png)
423
424When you press the **Tab** key for the second time, the focus switches to the container that matches **tabIndex(2)** and automatically moves to the component bound to **groupDefaultFocus**.
425
426![groupDefaultFocus2](figures/groupDefaultFocus2.png)
427
428When you press the **Tab** key for the third time, the focus switches to the container that matches **tabIndex(3)** and automatically moves to the component bound to **groupDefaultFocus**.
429
430![groupDefaultFocus3](figures/groupDefaultFocus3.png)
431
432Clicking the component bound to **focusOnTouch** sets the focus on the component and removes the focus indicator. Pressing the Tab key again displays the focus indicator.
433
434![focusOnTouch](figures/focusOnTouch.png)
435
436### Example 2: Setting Focus on a Specific Component
437
438This example demonstrates how to set focus on a specific component using **focusControl.requestFocus**.
439
440> **NOTE**
441>
442> To avoid confusion with **focusControl** instances, it is recommended that you obtain a **UIContext** instance using the [getUIContext](../js-apis-arkui-UIContext.md#uicontext) API, and then obtain the **focusControl** instance bound to the context through the [getFocusController](../js-apis-arkui-UIContext.md#getfocuscontroller12) API.
443
444```ts
445// requestFocus.ets
446@Entry
447@Component
448struct RequestFocusExample {
449  @State idList: string[] = ['A', 'B', 'C', 'D', 'E', 'F', 'LastPageId']
450  @State selectId: string = 'LastPageId'
451
452  build() {
453    Column({ space:20 }){
454      Row({space: 5}) {
455        Button("id: " + this.idList[0] + " focusable(false)")
456          .width(200).height(70).fontColor(Color.White)
457          .id(this.idList[0])
458          .focusable(false)
459        Button("id: " + this.idList[1])
460          .width(200).height(70).fontColor(Color.White)
461          .id(this.idList[1])
462      }
463      Row({space: 5}) {
464        Button("id: " + this.idList[2])
465          .width(200).height(70).fontColor(Color.White)
466          .id(this.idList[2])
467        Button("id: " + this.idList[3])
468          .width(200).height(70).fontColor(Color.White)
469          .id(this.idList[3])
470      }
471      Row({space: 5}) {
472        Button("id: " + this.idList[4])
473          .width(200).height(70).fontColor(Color.White)
474          .id(this.idList[4])
475        Button("id: " + this.idList[5])
476          .width(200).height(70).fontColor(Color.White)
477          .id(this.idList[5])
478      }
479      Row({space: 5}) {
480        Select([{value: this.idList[0]},
481                {value: this.idList[1]},
482                {value: this.idList[2]},
483                {value: this.idList[3]},
484                {value: this.idList[4]},
485                {value: this.idList[5]},
486                {value: this.idList[6]}])
487          .value(this.selectId)
488          .onSelect((index: number) => {
489            this.selectId = this.idList[index]
490          })
491        Button("RequestFocus")
492          .width(200).height(70).fontColor(Color.White)
493          .onClick(() => {
494            // You are advised to use this.getUIContext().getFocusController().requestFocus().
495            let res = focusControl.requestFocus(this.selectId)      // Move the focus to the component specified by this.selectId.
496            if (res) {
497              this.getUIContext().getPromptAction().showToast({message: 'Request success'})
498            } else {
499              this.getUIContext().getPromptAction().showToast({message: 'Request failed'})
500            }
501          })
502      }
503    }.width('100%').margin({ top:20 })
504  }
505}
506```
507
508Diagrams:
509
510Press the **Tab** key to activate the focus state.
511Below shows how the UI behaves when you request focus for a component that does not exist.
512
513![requestFocus1](figures/requestFocus1.png)
514
515Below shows how the UI behaves when you request focus for a component that is not focusable.
516
517![requestFocus2](figures/requestFocus2.png)
518
519Below shows how the UI behaves when you request focus for a focusable component.
520
521![requestFocus3](figures/requestFocus3.png)
522
523### Example 3: Customizing the Focus Box Style
524
525This example shows how to change the focus box style of a component by configuring **focusBox**.
526
527```ts
528import { ColorMetrics, LengthMetrics } from '@kit.ArkUI'
529
530@Entry
531@Component
532struct RequestFocusExample {
533  build() {
534    Column({ space: 30 }) {
535      Button("small black focus box")
536        .focusBox({
537          margin: new LengthMetrics(0),
538          strokeColor: ColorMetrics.rgba(0, 0, 0),
539        })
540      Button("large red focus box")
541        .focusBox({
542          margin: LengthMetrics.px(20),
543          strokeColor: ColorMetrics.rgba(255, 0, 0),
544          strokeWidth: LengthMetrics.px(10)
545        })
546    }
547    .alignItems(HorizontalAlign.Center)
548    .width('100%')
549  }
550}
551```
552
553![focusBox](figures/focusBox.gif)
554
555
556### Example 4: Setting Focus Group Traversal
557
558This example demonstrates how to set a component as the initial focus when its container gains focus by configuring **focusScopePriority**. Configuring **focusScopeId** allows the bound container component to become a focus group.
559
560```ts
561// focusTest.ets
562@Entry
563@Component
564struct FocusableExample {
565  @State inputValue: string = ''
566
567  build() {
568    Scroll() {
569      Row({ space: 20 }) {
570        Column({ space: 20 }) {  // Labeled as Column1.
571          Column({ space: 5 }) {
572            Button('Group1')
573              .width(165)
574              .height(40)
575              .fontColor(Color.White)
576            Row({ space: 5 }) {
577              Button()
578                .width(80)
579                .height(40)
580                .fontColor(Color.White)
581              Button()
582                .width(80)
583                .height(40)
584                .fontColor(Color.White)
585            }
586            Row({ space: 5 }) {
587              Button()
588                .width(80)
589                .height(40)
590                .fontColor(Color.White)
591              Button()
592                .width(80)
593                .height(40)
594                .fontColor(Color.White)
595            }
596          }.borderWidth(2).borderColor(Color.Red).borderStyle(BorderStyle.Dashed)
597          Column({ space: 5 }) {
598            Button('Group2')
599              .width(165)
600              .height(40)
601              .fontColor(Color.White)
602            Row({ space: 5 }) {
603              Button()
604                .width(80)
605                .height(40)
606                .fontColor(Color.White)
607              Button()
608                .width(80)
609                .height(40)
610                .fontColor(Color.White)
611                .focusScopePriority('ColumnScope1', FocusPriority.PRIOR) // Focus when Column1 first gains focus.
612            }
613            Row({ space: 5 }) {
614              Button()
615                .width(80)
616                .height(40)
617                .fontColor(Color.White)
618              Button()
619                .width(80)
620                .height(40)
621                .fontColor(Color.White)
622            }
623          }.borderWidth(2).borderColor(Color.Green).borderStyle(BorderStyle.Dashed)
624        }
625        .focusScopeId('ColumnScope1')
626        Column({ space: 5 }) {  // Labeled as Column2.
627          TextInput({placeholder: 'input', text: this.inputValue})
628            .onChange((value: string) => {
629              this.inputValue = value
630            })
631            .width(156)
632          Button('Group3')
633            .width(165)
634            .height(40)
635            .fontColor(Color.White)
636          Row({ space: 5 }) {
637            Button()
638              .width(80)
639              .height(40)
640              .fontColor(Color.White)
641            Button()
642              .width(80)
643              .height(40)
644              .fontColor(Color.White)
645          }
646          Button()
647            .width(165)
648            .height(40)
649            .fontColor(Color.White)
650            .focusScopePriority('ColumnScope2', FocusPriority.PREVIOUS)  // Focuses when Column2 first gains focus.
651          Row({ space: 5 }) {
652            Button()
653              .width(80)
654              .height(40)
655              .fontColor(Color.White)
656            Button()
657              .width(80)
658              .height(40)
659              .fontColor(Color.White)
660          }
661          Button()
662            .width(165)
663            .height(40)
664            .fontColor(Color.White)
665          Row({ space: 5 }) {
666            Button()
667              .width(80)
668              .height(40)
669              .fontColor(Color.White)
670            Button()
671              .width(80)
672              .height(40)
673              .fontColor(Color.White)
674          }
675        }.borderWidth(2).borderColor(Color.Orange).borderStyle(BorderStyle.Dashed)
676        .focusScopeId('ColumnScope2', true) // Column2 is a focus group.
677      }.alignItems(VerticalAlign.Top)
678    }
679  }
680}
681```
682
683### Example 5: Setting Focus Stop
684
685This example illustrates how to use **tabStop** to make the focus stop on a component during focus traversal with the **Tab** key.
686
687```ts
688import { ColorMetrics, LengthMetrics } from '@kit.ArkUI'
689
690@Entry
691@Component
692struct TabStop {
693  build() {
694    Column({ space: 20 }) {
695      Column({ space: 20 }) {
696        Column({ space: 20 }) {
697          Row({ space: 5 }) {
698            Button("button 1")
699              .width(200).height(70).fontColor(Color.White)
700              .focusBox({
701                margin: LengthMetrics.px(20),
702                strokeColor: ColorMetrics.rgba(23, 169, 141),
703                strokeWidth: LengthMetrics.px(10)
704              })
705          }
706          Row({ space: 5 }) {
707            Button("button 2")
708              .width(200).height(70).fontColor(Color.White)
709              .focusBox({
710                margin: LengthMetrics.px(20),
711                strokeColor: ColorMetrics.rgba(23, 169, 141),
712                strokeWidth: LengthMetrics.px(10)
713              })
714          }
715        }.width('80%').margin({ top: 30 }).borderColor(Color.Black)
716      }.width('95%').margin({ top: 60 }).borderColor(Color.Black)
717      Column({ space: 20 }) {
718        Column({ space: 20 }) {
719          Row({ space: 5 }) {
720            Button("button 3")
721              .width(200)
722              .height('70%')
723              .fontColor(Color.White)
724              .focusBox({
725                margin: LengthMetrics.px(20),
726                strokeColor: ColorMetrics.rgba(23, 169, 141),
727                strokeWidth: LengthMetrics.px(10)
728              })
729              .margin({ top: 15 })
730          }
731        }
732        .width('80%')
733        .height('120')
734        .borderColor(Color.Black)
735        .margin({ top: 10 })
736        .tabStop(true)
737        .focusBox({
738          margin: LengthMetrics.px(20),
739          strokeColor: ColorMetrics.rgba(23, 169, 141),
740          strokeWidth: LengthMetrics.px(10)
741        })
742        .borderWidth(1)
743      }.width('95%').margin({ top: 50 }).borderColor(Color.Black)
744    }
745  }
746}
747```
748Diagrams:
749
750Pressing **Tab** twice moves the focus to **button2**.
751
752![tabStop2](figures/tabStop2.png)
753
754Pressing **Tab** again moves the focus to the component configured with **tabStop**.
755
756![tabStop3](figures/tabStop3.png)
757
758Pressing **Enter** moves the focus to **button3**.
759
760![tabStop4](figures/tabStop4.png)
761
762Pressing **ESC** again moves the focus to the component configured with **tabStop**.
763
764![tabStop3](figures/tabStop3.png)
765
766Pressing **Tab** moves the focus back to **button1**.
767
768![tabStop1](figures/tabStop1.png)
769
770### Example 6: Setting Custom Focus Movement
771
772This example demonstrates how to implement custom focus movement logic using the **nextFocus** API.
773Without **nextFocus** configured, the default focus navigation order using the **Tab** key is as follows: M -> A -> B -> C. After **nextFocus** is configured, the order changes to the following: M -> D -> F -> B.
774
775```ts
776class MyButtonModifier implements AttributeModifier<ButtonAttribute> {
777  applyNormalAttribute(instance: ButtonAttribute): void {
778    instance.id('M')
779    instance.nextFocus({forward: 'D', up: 'C', down: 'D'})
780  }
781}
782
783@Entry
784@Component
785struct Index {
786  @State modifier: MyButtonModifier = new MyButtonModifier()
787  @State idList: string[] = ['A', 'B', 'C', 'D', 'E', 'F']
788
789  build() {
790    Column({space: 10}) {
791      Row({space: 10}) {
792        Button("id: M")
793          .attributeModifier(this.modifier)
794        Button("id: " + this.idList[0])
795          .id(this.idList[0])
796          .nextFocus({forward: 'C', backward: 'M', up: 'E', right: 'F', down: 'B', left: 'D'});
797        Button("id: " + this.idList[1])
798          .id(this.idList[1])
799      }
800      Column({space: 10}) {
801        Button("id: " + this.idList[2])
802          .id(this.idList[2]);
803        Button("id: " + this.idList[3])
804          .id(this.idList[3])
805          .nextFocus({forward: 'F'});
806      }
807      Row({space: 10}) {
808        Button("id: " + this.idList[4])
809          .id(this.idList[4]);
810        Button("id: " + this.idList[5])
811          .id(this.idList[5])
812          .nextFocus({forward: 'B'});
813      }
814    }
815  }
816}
817```
818![focusBox](figures/nextStep.gif)
819