• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Focus Event
2
3## Basic Concepts and Specifications
4
5### Basic Concepts
6
7**Focus, Focus Chain, and Focus Traversal**
8
9- Focus: refers to the single interactive element on the current application screen. When users interact indirectly with the application using non-pointing input devices such as keyboards, TV remote controls, or in-car joysticks/knobs, navigation and interaction based on focus are crucial means of input.
10- Focus chain: refers to the sequence of nodes from the root to a focused component in the application's component tree, where all nodes are considered focused.
11- Focus traversal: refers to the behavior of focus shifting between components in an application. This process is transparent to the user but can be monitored through **onFocus** and **onBlur** events. For details on how focus traversal is managed, see [Focus Traversal Guidelines](#focus-traversal-guidelines)
12
13
14**Focus State**
15
16Refers to the style indicating the currently focused component.
17
18- Display rules: The focus state is not displayed by default; it only appears when the application is active. A component with the focus state is definitely focused, but not all focused components show the state, depending on the activation status. Most components come with default focus state styles; you customize these styles when needed. Once customized, the component will no longer display the default focus state style. In a focus chain, if multiple components have the focus state, the system shows the focus state for only one, prioritizing the child component's focus state over others.
19- Entering the activated state: Pressing the Tab key on an external keyboard activates focus, allowing subsequent use of the **Tab** key or arrow keys for focus traversal. The initial **Tab** press that activates focus does not cause focus to move.
20- Exiting the activated state: Focus activation ends upon any click event, including touch screen presses or mouse clicks.
21
22
23**Hierarchical Pages**
24
25Hierarchical pages are specialized container components, such as **Page**, **Dialog**, **SheetPage**, **ModalPage**, **Menu**, **Popup**, **NavBar**, and **NavDestination**, within a focus framework. These components typically have the following key features:
26
27- Visual layering: They appear on top of other content, creating a distinct visual hierarchy.
28- Focus capture: They automatically take focus when first displayed.
29- Focus limitation: When focus is within these components, users cannot use keyboard keys to move focus outside to other elements. In other words, focus movement is confined within the component.
30
31An application always has at least one hierarchical page in focus. When this hierarchical page is closed or no longer visible, the focus shifts to another, ensuring smooth user interaction.
32
33
34
35> **NOTE**
36>
37> The **Popup** component does not capture focus if it has **focusable** set to **false**.
38>
39> The **NavBar** and **NavDestination** components do not restrict focus movement and share the focus scope of their immediate parent hierarchical page.
40
41
42
43
44
45**Root Container**
46
47In hierarchical pages, the root container is where the default focus resides when the page is first shown.
48
49You can change the default focus using the **defaultFocus** attribute.
50
51Pressing **Tab** with focus on the root container activates focus and passes it to child components. Focus proceeds to the last focused child or the first child if no previous focus exists, until it reaches the leaf node.
52
53
54
55### Focus Traversal Guidelines
56
57Focus traversal can be divided into active and passive based on how it is triggered.
58
59
60
61**Active Focus Traversal**
62
63
64Active focus traversal refers to focus movement initiated by deliberate actions, such as keyboard shortcuts (**Tab**, **Shift+Tab**, arrow keys) and programmatic focus control through **requestFocus**, **clearFocus**, and **focusOnTouch**.
65
66
67- Keyboard traversal
681. Prerequisite: The application is in the focus activated state.
692. Scope: limited to the currently focused hierarchical page, as detailed in the "Focus limitation" section under "Hierarchical Pages."
703. Key types:
71**Tab** key: follows a Z-shaped logic to traverse all leaf nodes within the scope, looping back to the first after the last.
72**Shift+Tab**: reverses the direction of the **Tab** key.
73Arrow keys (up, down, left, and right): moves focus in a cross-shaped pattern, with container-specific algorithms determining the next focus in a single-layer container. If the algorithm determines the next focus should be on a container component, the system uses a center-point distance priority algorithm to further identify the target child node within the container.
744. Traversal algorithm: Each focusable container has a unique algorithm defining how focus moves.
755. Priority: Child components take precedence in handling keyboard events over parents.
76
77- requestFocus
78Moves focus to a specific component, which is allowed across hierarchical pages but not across windows or different ArkUI instances.
79For details, see [Active Focus Acquisition/Loss](#active-focus-acquisitionloss).
80
81- clearFocus
82Clears the focus within the current hierarchical page, with the focus reverting to the root container. For details, see [clearFocus](../reference/apis-arkui/arkui-ts/ts-universal-attributes-focus.md#clearfocus12).
83
84- focusOnTouch
85Enables a component to gain focus on touch. It is ineffective on non-focusable components. For container components, focus goes to the last focused child or the first focusable child upon touch. For details, see [focusOnTouch](../reference/apis-arkui/arkui-ts/ts-universal-attributes-focus.md#focusontouch9).
86
87
88**Passive Focus Traversal**
89
90Passive focus traversal occurs when the focus automatically shifts due to system actions or other operations without developer intervention, reflecting the default behavior of the focus system.
91
92
93Mechanisms that trigger passive focus traversal include:
94
95- Component removal: If a focused component is removed, the system tries to shift focus to the next available sibling, following a back-to-front order. If no siblings are focusable, focus is released to the parent component.
96- Attribute change: Changing a component's **focusable** or **enabled** to **false**, or **visibility** to invisible causes the system to automatically move focus to another focusable component, using the same method as for component removal.
97- Hierarchical page transition: During switching between hierarchical pages, the current page's focus is automatically released, and the new page may automatically gain focus according to preset logic.
98- **Web** component initialization: The **Web** component may immediately gain focus upon creation if designed to do so (for example, certain dialog boxes or text boxes), which is part of the component's behavior and not governed by the focus framework specifications.
99
100
101
102### Focus Traversal Algorithms
103
104In the focus management system, every focusable container is assigned a specific algorithm that dictates how focus moves from the current to the next focusable child component when **Tab**, **Shift+Tab**, or arrow keys are used.
105
106The algorithm used by a container is based on its UX design and is implemented by the component itself. The focus framework supports three focus traversal algorithms: linear, projection, and custom.
107
108
109
110**Linear Focus Traversal Algorithm**
111
112
113The linear focus traversal algorithm is the default algorithm, focusing on the order of child nodes in the node tree, commonly used in single-direction layouts such as **Row**, **Column**, and **Flex** containers. Its operation rules are as follows:
114
115
116- Order dependency: The focus order is based solely on the mounting sequence of child nodes in the node tree, independent of their visual layout.
117- **Tab** key traversal: The **Tab** key moves focus through nodes in their mounting sequence.
118- Arrow key traversal: Arrow keys perpendicular to the container's layout direction are ignored. For example, a horizontal **Row** container does not accept focus requests from up and down keys.
119- Boundary handling: The container rejects focus requests in the opposite direction from the current focus edge. For example, if the focus is on the first child of a horizontal **Row** container, it won't process leftward focus requests.
120
121
122**Projection Focus Traversal Algorithm**
123
124The projection focus traversal algorithm determines the next focus based on the overlap area and center-point distance of the projection of the current focused component in the direction of focus movement. It is particularly suitable for containers with varying child sizes, such as the **Flex** component with the **wrap** attribute. Its operation rules are as follows:
125
126
127- Arrow keys: Focus goes to the child with the largest overlap area and the shortest center-point distance to the projection of the current focus. If multiple children qualify, the first in the node tree is chosen. If no components overlap with the projection, the focus request is unprocessable.
128- **Tab** key: It mimics a rightward shift to find the next focus; if none is available, it simulates moving the current focus down its height, and then checks leftward. The child farthest in the direction with overlapping projection wins.
129- **Shift+Tab** key: It mimics a leftward shift to find the next focus; if none is available, it simulates moving the current focus up its height, and then checks rightward. The child farthest in the direction with overlapping projection wins.
130
131
132**Custom Focus Traversal Algorithm**
133
134The custom focus traversal algorithm is defined by the component itself, allowing for specific focus traversal behaviors as determined by the component's design specifications.
135
136## onFocus/onBlur Events
137
138```ts
139onFocus(event: () => void)
140```
141
142
143Triggered when the bound component obtains focus.
144
145```ts
146onBlur(event:() => void)
147```
148
149Triggered when the bound component loses focus.
150
151The **onFocus** and **onBlur** APIs are usually used in pairs to listen for the focus changes of the component.
152
153```ts
154// xxx.ets
155@Entry
156@Component
157struct FocusEventExample {
158  @State oneButtonColor: Color = Color.Gray;
159  @State twoButtonColor: Color = Color.Gray;
160  @State threeButtonColor: Color = Color.Gray;
161
162  build() {
163    Column({ space: 20 }) {
164      // You can use the up and down arrow keys on an external keyboard to move the focus between the three buttons. When a button gains focus, its color changes. When it loses focus, its color changes back.
165      Button('First Button')
166        .width(260)
167        .height(70)
168        .backgroundColor(this.oneButtonColor)
169        .fontColor(Color.Black)
170          // Listen for the focus obtaining event of the first component and change its color when it obtains focus.
171        .onFocus(() => {
172          this.oneButtonColor = Color.Green;
173        })
174          // Listen for the focus loss event of the first component and change its color when it loses focus.
175        .onBlur(() => {
176          this.oneButtonColor = Color.Gray;
177        })
178
179      Button('Second Button')
180        .width(260)
181        .height(70)
182        .backgroundColor(this.twoButtonColor)
183        .fontColor(Color.Black)
184          // Listen for the focus obtaining event of the second component and change its color when it obtains focus.
185        .onFocus(() => {
186          this.twoButtonColor = Color.Green;
187        })
188          // Listen for the focus loss event of the second component and change its color when it loses focus.
189        .onBlur(() => {
190          this.twoButtonColor = Color.Grey;
191        })
192
193      Button('Third Button')
194        .width(260)
195        .height(70)
196        .backgroundColor(this.threeButtonColor)
197        .fontColor(Color.Black)
198          // Listen for the focus obtaining event of the third component and change its color when it obtains focus.
199        .onFocus(() => {
200          this.threeButtonColor = Color.Green;
201        })
202          // Listen for the focus loss event of the third component and change its color when it loses focus.
203        .onBlur(() => {
204          this.threeButtonColor = Color.Gray ;
205        })
206    }.width('100%').margin({ top: 20 })
207  }
208}
209```
210
211
212![en-us_image_0000001511740584](figures/en-us_image_0000001511740584.gif)
213
214
215The preceding example includes three steps:
216
217- When the application is opened, pressing the **Tab** key activates focus traversal, **First Button** displays a focus state style – a blue bounding box around the component – and its **onFocus** callback is triggered, changing the background color to green.
218- When the **Tab** key is pressed again, **Second Button** gains focus, triggering its **onFocus** callbacktriggered, and its background color turns green, while **First Button** loses focus, triggering its **onBlur** callback, and its background color reverts to gray.
219- A subsequent **Tab** key press causes **Third Button** to gain focus, triggering its **onFocus** callback, and its background color turns green. Concurrently, **Second Button** loses focus, triggering its **onBlur** callback, and its background color reverts to gray.
220
221## Setting Whether a Component Is Focusable
222
223```ts
224focusable(value: boolean)
225```
226
227Sets whether the component is focusable.
228
229Components can be classified into the following types based on their focusability:
230
231- Default focusable components: These components are usually interactive components, such as **Button**, **Checkbox**, and **TextInput**.
232
233- Focusable but default unfocusable components: Typical examples are **Text** and **Image**. To enable them to be focusable, use the **focusable(true)** attribute. When these components do not have the **focusable** attribute set, setting an **onClick** event or a single-tap gesture implicitly makes them focusable. However, when these components have the **focusable** attribute set to **false**, they remain unfocusable even if you bind the aforementioned event or gesture to them.
234
235- Non-focusable components: Components that do not allow for interactions, such as **Blank** and **Circle**, cannot be made focusable, even with the **focusable** attribute applied.
236
237
238
239
240```ts
241enabled(value: boolean)
242```
243
244Sets the component's interactivity. If [enabled](../reference/apis-arkui/arkui-ts/ts-universal-attributes-enable.md#enabled) is set to **false**, the component becomes non-interactive and cannot gain focus.
245
246
247```ts
248visibility(value: Visibility)
249```
250
251Sets the component's visibility. If [visibility](../reference/apis-arkui/arkui-ts/ts-universal-attributes-visibility.md#visibility) set to **Visibility.None** or **Visibility.Hidden**, the component becomes invisible and cannot gain focus.
252
253
254```ts
255focusOnTouch(value: boolean)
256```
257
258Sets whether the component is focusable on touch.
259
260
261
262
263>**NOTE**
264>
265>- When a component that is currently focused has its **focusable** or **enabled** attribute set to **false**, it automatically loses focus. The focus then shifts to another component according to the [Focus Traversal Guidelines](#focus-traversal-guidelines).
266
267
268```ts
269// xxx.ets
270@Entry
271@Component
272struct FocusableExample {
273  @State textFocusable: boolean = true;
274  @State textEnabled: boolean = true;
275  @State color1: Color = Color.Yellow;
276  @State color2: Color = Color.Yellow;
277  @State color3: Color = Color.Yellow;
278
279  build() {
280    Column({ space: 5 }) {
281      Text('Default Text')    // The first Text component does not have the focusable attribute set, and is not focusable by default.
282        .borderColor(this.color1)
283        .borderWidth(2)
284        .width(300)
285        .height(70)
286        .onFocus(() => {
287          this.color1 = Color.Blue;
288        })
289        .onBlur(() => {
290          this.color1 = Color.Yellow;
291        })
292      Divider()
293
294      Text('focusable: ' + this.textFocusable)    // The second Text component initially has focusable set to true and focusOnTouch true.
295        .borderColor(this.color2)
296        .borderWidth(2)
297        .width(300)
298        .height(70)
299        .focusable(this.textFocusable)
300        .focusOnTouch(true)
301        .onFocus(() => {
302          this.color2 = Color.Blue;
303        })
304        .onBlur(() => {
305          this.color2 = Color.Yellow;
306        })
307
308      Text('enabled: ' + this.textEnabled)    // The third Text component has focusable set to true, enabled initially true.
309        .borderColor(this.color3)
310        .borderWidth(2)
311        .width(300)
312        .height(70)
313        .focusable(true)
314        .enabled(this.textEnabled)
315        .focusOnTouch(true)
316        .onFocus(() => {
317          this.color3 = Color.Blue;
318        })
319        .onBlur(() => {
320          this.color3 = Color.Yellow;
321        })
322
323      Divider()
324
325      Row() {
326        Button('Button1')
327          .width(140).height(70)
328        Button('Button2')
329          .width(160).height(70)
330      }
331
332      Divider()
333      Button('Button3')
334        .width(300).height(70)
335
336      Divider()
337    }.width('100%').justifyContent(FlexAlign.Center)
338    .onKeyEvent((e) => {
339      // Bind onKeyEvent. When this Column component has focus, pressing F will toggle the focusable state of the second Text component.
340      if (e.keyCode === 2022 && e.type === KeyType.Down) {
341        this.textFocusable = !this.textFocusable;
342      }
343      // Bind onKeyEvent. When this Column component has focus, pressing G will toggle the enabled state of the third Text component.
344      if (e.keyCode === 2023 && e.type === KeyType.Down) {
345        this.textEnabled = !this.textEnabled;
346      }
347    })
348  }
349}
350```
351
352
353Operation result:
354
355
356![focus-1.gif](figures/focus-1.gif)
357
358The preceding example includes three steps:
359
360
361- As the first **Text** component does not have **focusable(true)** set, it is unfocusable.
362- The second **Text** component is set with **focusOnTouch(true)**, allowing it to gain focus on touch. Pressing the **Tab** key triggers focus traversal, but the focus remains on the second component. When the **F** key is pressed, the **onKeyEvent** callback toggles **focusable** to **false**, making the second **Text** component unfocusable, and the focus shifts to the next available focusable component, which is the third **Text** component.
363- Pressing the **G** key triggers the **onKeyEvent** callback, which sets **enabled** to **false**, making the third **Text** component unfocusable. The focus then automatically moves to the **Row** container, where the default configuration causes the focus to shift to **Button1**.
364
365## Default Focus
366
367### Default Focus on a Page
368
369```ts
370defaultFocus(value: boolean)
371```
372
373Specifies whether to set the component as the default focus of the page.
374
375
376```ts
377// xxx.ets
378@Entry
379@Component
380struct morenjiaodian {
381  @State oneButtonColor: Color = Color.Gray;
382  @State twoButtonColor: Color = Color.Gray;
383  @State threeButtonColor: Color = Color.Gray;
384
385  build() {
386    Column({ space: 20 }) {
387      // You can use the up and down arrow keys on an external keyboard to move the focus between the three buttons. When a button gains focus, its color changes. When it loses focus, its color changes back.
388      Button('First Button')
389        .width(260)
390        .height(70)
391        .backgroundColor(this.oneButtonColor)
392        .fontColor(Color.Black)
393          // Listen for the focus obtaining event of the first component and change its color when it obtains focus.
394        .onFocus(() => {
395          this.oneButtonColor = Color.Green;
396        })
397          // Listen for the focus loss event of the first component and change its color when it loses focus.
398        .onBlur(() => {
399          this.oneButtonColor = Color.Gray;
400        })
401
402      Button('Second Button')
403        .width(260)
404        .height(70)
405        .backgroundColor(this.twoButtonColor)
406        .fontColor(Color.Black)
407          // Listen for the focus obtaining event of the second component and change its color when it obtains focus.
408        .onFocus(() => {
409          this.twoButtonColor = Color.Green;
410        })
411          // Listen for the focus loss event of the second component and change its color when it loses focus.
412        .onBlur(() => {
413          this.twoButtonColor = Color.Grey;
414        })
415
416      Button('Third Button')
417        .width(260)
418        .height(70)
419        .backgroundColor(this.threeButtonColor)
420        .fontColor(Color.Black)
421          // Set the default focus.
422        .defaultFocus(true)
423          // Listen for the focus obtaining event of the third component and change its color when it obtains focus.
424        .onFocus(() => {
425          this.threeButtonColor = Color.Green;
426        })
427          // Listen for the focus loss event of the third component and change its color when it loses focus.
428        .onBlur(() => {
429          this.threeButtonColor = Color.Gray ;
430        })
431    }.width('100%').margin({ top: 20 })
432  }
433}
434```
435
436![defaultFocus.gif](figures/defaultFocus.gif)
437
438The preceding example includes two steps:
439
440- The **defaultFocus(true)** is set on the third **Button** component, which means it gains focus by default when the page is loaded, displaying in green.
441- Pressing the **Tab** key triggers focus traversal, and since the third **Button** component is in focus, a focus frame appears around it.
442
443### Default Focus for Containers
444
445The default focus within a container is affected by [focus priority](#focus-group-and-focus-priority).
446
447**Differences Between defaultFocus and FocusPriority**
448
449[defaultFocus](../reference/apis-arkui/arkui-ts/ts-universal-attributes-focus.md#defaultfocus9) specifies the initial focus when the page loads. [FocusPriority](../reference/apis-arkui/arkui-ts/ts-universal-attributes-focus.md#focuspriority12) defines the order in which child components gain focus within a container. Behavior is undefined when both attributes are set in some scenarios. For example, a page's initial display cannot simultaneously meet the focus requirements of a component with **defaultFocus **and a high-priority component.
450
451Example
452
453```ts
454@Entry
455@Component
456struct Index {
457  build() {
458    Row() {
459      Button('Button1')
460        .defaultFocus(true)
461      Button('Button2')
462        .focusScopePriority('RowScope', FocusPriority.PREVIOUS)
463    }.focusScopeId('RowScope')
464  }
465}
466```
467
468### Focus Chain for Pages/Containers
469
470**Overall Focus and Non-Overall Focus**
471
472- Overall focus: The entire page or container gains focus first, then the focus shifts to its child components. Examples include page transitions, route switches within **Navigation** components, focus group traversal, and when a container component proactively calls **requestFocusById**.
473
474- Non-overall focus: A specific component gains focus, pulling its parent components into focus. Examples include a **TextInput** component proactively obtaining focus or using the **Tab** key for traversal in non-focus group.
475
476**Formation of the Focus Chain in Overall Focus**
477
4781. Initial page focus:
479
480- The leaf node of the focus chain is the node with **defaultFocus** set.
481
482- If no **defaultFocus** is configured, the focus remains on the page's root container.
483
4842. Subsequent page focus: Focus is gained by the node that last held focus.
485
4863. Focus chain with priority configuration:
487
488- If a container has a component with a focus priority higher than **PREVIOUS**, the component with the highest priority gains focus.
489
490- If no component with a priority higher than **PREVIOUS** exists, the last focused node regains focus, such as when a window refocuses after being out of focus.
491
492
493## Focus Style
494
495
496```ts
497focusBox(style: FocusBoxStyle)
498```
499
500Sets the system focus box style for the component.
501
502```ts
503import { ColorMetrics, LengthMetrics } from '@kit.ArkUI'
504
505@Entry
506@Component
507struct RequestFocusExample {
508  build() {
509    Column({ space: 30 }) {
510      Button("small black focus box")
511        .focusBox({
512          margin: new LengthMetrics(0),
513          strokeColor: ColorMetrics.rgba(0, 0, 0),
514        })
515      Button("large red focus box")
516        .focusBox({
517          margin: LengthMetrics.px(20),
518          strokeColor: ColorMetrics.rgba(255, 0, 0),
519          strokeWidth: LengthMetrics.px(10)
520        })
521    }
522    .alignItems(HorizontalAlign.Center)
523    .width('100%')
524  }
525}
526```
527
528![focusBox](figures/focusBox.gif)
529
530
531The preceding example includes two steps:
532
533- After the page opens, pressing the Tab key initiates focus traversal. The first **Button** gains focus, displaying a small, black focus box that is closely fitted to the edge.
534- Pressing the Tab key again shifts focus to the second **Button**, which features a large, red focus box with a thicker stroke and a more significant margin from the edge.
535
536## Active Focus Acquisition/Loss
537
538- Using **FocusController** APIs
539
540  You are advised to use **requestFocus** from **FocusController** for actively acquiring focus. It provides the following benefits:
541  - Takes effect in the current frame, preventing interference from subsequent component tree changes.
542  - Provides exception handling, aiding in troubleshooting focus acquisition issues.
543  - Prevents errors in multi-instance scenarios by avoiding incorrect instance retrieval.
544
545  You must first obtain an instance using the [getFocusController()](../reference/apis-arkui/js-apis-arkui-UIContext.md#getfocuscontroller12) API in **UIContext** and then use this instance to call the corresponding methods.
546
547  ```ts
548  requestFocus(key: string): void
549  ```
550  Transfers focus to a component node by the component ID, which is effective immediately.
551
552  ```ts
553  clearFocus(): void
554  ```
555  Clears the focus and forcibly moves the focus to the root container node of the page, causing other nodes in the focus chain to lose focus.
556
557- Using **focusControl** APIs
558  ```ts
559  requestFocus(value: string): boolean
560  ```
561
562  Moves focus to a specified component, with the change taking effect in the next frame.
563
564
565```ts
566// focusTest.ets
567@Entry
568@Component
569struct RequestExample {
570  @State btColor: string = '#ff2787d9'
571  @State btColor2: string = '#ff2787d9'
572
573  build() {
574    Column({ space: 20 }) {
575      Column({ space: 5 }) {
576        Button('Button')
577          .width(200)
578          .height(70)
579          .fontColor(Color.White)
580          .focusOnTouch(true)
581          .backgroundColor(this.btColor)
582          .onFocus(() => {
583            this.btColor = '#ffd5d5d5'
584          })
585          .onBlur(() => {
586            this.btColor = '#ff2787d9'
587          })
588          .id("testButton")
589
590        Button('Button')
591          .width(200)
592          .height(70)
593          .fontColor(Color.White)
594          .focusOnTouch(true)
595          .backgroundColor(this.btColor2)
596          .onFocus(() => {
597            this.btColor2 = '#ffd5d5d5'
598          })
599          .onBlur(() => {
600            this.btColor2 = '#ff2787d9'
601          })
602          .id("testButton2")
603
604        Divider()
605          .vertical(false)
606          .width("80%")
607          .backgroundColor('#ff707070')
608          .height(10)
609
610        Button('FocusController.requestFocus')
611          .width(200).height(70).fontColor(Color.White)
612          .onClick(() => {
613            this.getUIContext().getFocusController().requestFocus("testButton")
614          })
615          .backgroundColor('#ff2787d9')
616
617        Button("focusControl.requestFocus")
618          .width(200).height(70).fontColor(Color.White)
619          .onClick(() => {
620            focusControl.requestFocus("testButton2")
621          })
622          .backgroundColor('#ff2787d9')
623
624        Button("clearFocus")
625          .width(200).height(70).fontColor(Color.White)
626          .onClick(() => {
627            this.getUIContext().getFocusController().clearFocus()
628          })
629          .backgroundColor('#ff2787d9')
630      }
631    }
632    .width('100%')
633    .height('100%')
634  }
635}
636```
637
638![focus-2](figures/focus-2.gif)
639
640The preceding example includes three steps:
641
642- When the **FocusController.requestFocus** button is clicked, the first button gains focus.
643- When the **focusControl.requestFocus** button is clicked, the second button gains focus.
644- When the **clearFocus** button is clicked, the second button loses focus.
645
646## Focus Group and Focus Priority
647
648```ts
649focusScopePriority(scopeId: string, priority?: FocusPriority)
650```
651
652Sets the focus priority of this component in a specified container. It must be used together with **focusScopeId**.
653
654
655```ts
656focusScopeId(id: string, isGroup?: boolean)
657```
658
659Assigns an ID to this container component and specifies whether the container is a focus group. Focus groups should not be mixed with **tabIndex** usage.
660
661```ts
662// focusTest.ets
663@Entry
664@Component
665struct FocusableExample {
666  @State inputValue: string = ''
667
668  build() {
669    Scroll() {
670      Row({ space: 20 }) {
671        Column({ space: 20 }) {  // Labeled as Column1.
672          Column({ space: 5 }) {
673            Button('Group1')
674              .width(165)
675              .height(40)
676              .fontColor(Color.White)
677            Row({ space: 5 }) {
678              Button()
679                .width(80)
680                .height(40)
681                .fontColor(Color.White)
682              Button()
683                .width(80)
684                .height(40)
685                .fontColor(Color.White)
686            }
687            Row({ space: 5 }) {
688              Button()
689                .width(80)
690                .height(40)
691                .fontColor(Color.White)
692              Button()
693                .width(80)
694                .height(40)
695                .fontColor(Color.White)
696            }
697          }.borderWidth(2).borderColor(Color.Red).borderStyle(BorderStyle.Dashed)
698          Column({ space: 5 }) {
699            Button('Group2')
700              .width(165)
701              .height(40)
702              .fontColor(Color.White)
703            Row({ space: 5 }) {
704              Button()
705                .width(80)
706                .height(40)
707                .fontColor(Color.White)
708              Button()
709                .width(80)
710                .height(40)
711                .fontColor(Color.White)
712                .focusScopePriority('ColumnScope1', FocusPriority.PRIOR) // Focuses when Column1 first gains focus.
713            }
714            Row({ space: 5 }) {
715              Button()
716                .width(80)
717                .height(40)
718                .fontColor(Color.White)
719              Button()
720                .width(80)
721                .height(40)
722                .fontColor(Color.White)
723            }
724          }.borderWidth(2).borderColor(Color.Green).borderStyle(BorderStyle.Dashed)
725        }
726        .focusScopeId('ColumnScope1')
727        Column({ space: 5 }) {  // Labeled as Column2.
728          TextInput({placeholder: 'input', text: this.inputValue})
729            .onChange((value: string) => {
730              this.inputValue = value
731            })
732            .width(156)
733          Button('Group3')
734            .width(165)
735            .height(40)
736            .fontColor(Color.White)
737          Row({ space: 5 }) {
738            Button()
739              .width(80)
740              .height(40)
741              .fontColor(Color.White)
742            Button()
743              .width(80)
744              .height(40)
745              .fontColor(Color.White)
746          }
747          Button()
748            .width(165)
749            .height(40)
750            .fontColor(Color.White)
751            .focusScopePriority('ColumnScope2', FocusPriority.PREVIOUS)  // Focuses when Column2 first gains focus.
752          Row({ space: 5 }) {
753            Button()
754              .width(80)
755              .height(40)
756              .fontColor(Color.White)
757            Button()
758              .width(80)
759              .height(40)
760              .fontColor(Color.White)
761          }
762          Button()
763            .width(165)
764            .height(40)
765            .fontColor(Color.White)
766          Row({ space: 5 }) {
767            Button()
768              .width(80)
769              .height(40)
770              .fontColor(Color.White)
771            Button()
772              .width(80)
773              .height(40)
774              .fontColor(Color.White)
775          }
776        }.borderWidth(2).borderColor(Color.Orange).borderStyle(BorderStyle.Dashed)
777        .focusScopeId('ColumnScope2', true) // Column2 is a focus group.
778      }.alignItems(VerticalAlign.Top)
779    }
780  }
781}
782```
783
784
785![focus-3](figures/focus-3.gif)
786
787
788
789The preceding example includes two steps:
790
791- The input box is set with a focus group, which means that when the **Tab** key is pressed, the focus quickly moves out from the input, and when arrow keys are used, the focus stays within the input.
792- The **Column** component in the upper left corner does not have a focus group set. Therefore, focus can only be traversed one by one with the **Tab** key.
793
794## Component Focusability
795
796
797  **Table 1** Focusability of basic components
798
799| Basic Component                                    | Focusable| Default Value of focusable|
800| ---------------------------------------- | ------- | ------------ |
801| [AlphabetIndexer](../reference/apis-arkui/arkui-ts/ts-container-alphabet-indexer.md) | Yes      | true         |
802| [Blank](../reference/apis-arkui/arkui-ts/ts-basic-components-blank.md) | No      | false        |
803| [Button](../reference/apis-arkui/arkui-ts/ts-basic-components-button.md) | Yes      | true         |
804| [CalendarPicker](../reference/apis-arkui/arkui-ts/ts-basic-components-calendarpicker.md) | Yes      | true         |
805| [Checkbox](../reference/apis-arkui/arkui-ts/ts-basic-components-checkbox.md) | Yes      | true         |
806| [CheckboxGroup](../reference/apis-arkui/arkui-ts/ts-basic-components-checkboxgroup.md) | Yes      | true         |
807| [ContainerSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-containerspan.md) | No      | false         |
808| [DataPanel](../reference/apis-arkui/arkui-ts/ts-basic-components-datapanel.md) | Yes      | false        |
809| [DatePicker](../reference/apis-arkui/arkui-ts/ts-basic-components-datepicker.md) | Yes      | true         |
810| [Divider](../reference/apis-arkui/arkui-ts/ts-basic-components-divider.md) | Yes      | false        |
811| [Gauge](../reference/apis-arkui/arkui-ts/ts-basic-components-gauge.md) | Yes      | false        |
812| [Image](../reference/apis-arkui/arkui-ts/ts-basic-components-image.md) | Yes      | false        |
813| [ImageAnimator](../reference/apis-arkui/arkui-ts/ts-basic-components-imageanimator.md) | No      | false        |
814| [ImageSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-imagespan.md)                 | No      | false        |
815| [LoadingProgress](../reference/apis-arkui/arkui-ts/ts-basic-components-loadingprogress.md) | Yes      | true        |
816| [Marquee](../reference/apis-arkui/arkui-ts/ts-basic-components-marquee.md) | No      | false        |
817| [Menu](../reference/apis-arkui/arkui-ts/ts-basic-components-menu.md) | Yes      | true         |
818| [MenuItem](../reference/apis-arkui/arkui-ts/ts-basic-components-menuitem.md) | Yes      | true         |
819| [MenuItemGroup](../reference/apis-arkui/arkui-ts/ts-basic-components-menuitemgroup.md) | No      | false         |
820| [Navigation](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md) | Yes      | true       |
821| [NavRouter](../reference/apis-arkui/arkui-ts/ts-basic-components-navrouter.md) | No      | false        |
822| [NavDestination](../reference/apis-arkui/arkui-ts/ts-basic-components-navdestination.md) | Yes      | true        |
823| [PatternLock](../reference/apis-arkui/arkui-ts/ts-basic-components-patternlock.md) | Yes      | true        |
824| [Progress](../reference/apis-arkui/arkui-ts/ts-basic-components-progress.md) | Yes      | true        |
825| [QRCode](../reference/apis-arkui/arkui-ts/ts-basic-components-qrcode.md) | Yes      | true        |
826| [Radio](../reference/apis-arkui/arkui-ts/ts-basic-components-radio.md) | Yes      | true         |
827| [Rating](../reference/apis-arkui/arkui-ts/ts-basic-components-rating.md) | Yes      | true         |
828| [RichEditor](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md) | Yes      | true         |
829| [RichText](../reference/apis-arkui/arkui-ts/ts-basic-components-richtext.md) | No      | false        |
830| [ScrollBar](../reference/apis-arkui/arkui-ts/ts-basic-components-scrollbar.md) | No      | false        |
831| [Search](../reference/apis-arkui/arkui-ts/ts-basic-components-search.md) | Yes      | true         |
832| [Select](../reference/apis-arkui/arkui-ts/ts-basic-components-select.md) | Yes      | true         |
833| [Slider](../reference/apis-arkui/arkui-ts/ts-basic-components-slider.md) | Yes      | true         |
834| [Span](../reference/apis-arkui/arkui-ts/ts-basic-components-span.md) | No      | false        |
835| [Stepper](../reference/apis-arkui/arkui-ts/ts-basic-components-stepper.md) | Yes      | true         |
836| [StepperItem](../reference/apis-arkui/arkui-ts/ts-basic-components-stepperitem.md) | Yes      | true         |
837| [SymbolSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-symbolSpan.md) | No      | false         |
838| [SymbolGlyph](../reference/apis-arkui/arkui-ts/ts-basic-components-symbolGlyph.md) | No      | false         |
839| [Text](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md) | Yes      | false        |
840| [TextArea](../reference/apis-arkui/arkui-ts/ts-basic-components-textarea.md) | No      | false         |
841| [TextClock](../reference/apis-arkui/arkui-ts/ts-basic-components-textclock.md) | No      | false        |
842| [TextInput](../reference/apis-arkui/arkui-ts/ts-basic-components-textinput.md) | Yes      | true         |
843| [TextPicker](../reference/apis-arkui/arkui-ts/ts-basic-components-textpicker.md) | Yes      | true         |
844| [TextTimer](../reference/apis-arkui/arkui-ts/ts-basic-components-texttimer.md) | No      | false        |
845| [TimePicker](../reference/apis-arkui/arkui-ts/ts-basic-components-timepicker.md) | No      | false         |
846| [Toggle](../reference/apis-arkui/arkui-ts/ts-basic-components-toggle.md) | Yes      | true         |
847| [XComponent](../reference/apis-arkui/arkui-ts/ts-basic-components-xcomponent.md) | Yes      | false        |
848
849  **Table 2** Focusability of container components
850
851| Container Component                                    | Focusable| Default Value of focusable|
852| ---------------------------------------- | ----- | ------------ |
853| [Badge](../reference/apis-arkui/arkui-ts/ts-container-badge.md) | No    | false        |
854| [Column](../reference/apis-arkui/arkui-ts/ts-container-column.md) | Yes    | true         |
855| [ColumnSplit](../reference/apis-arkui/arkui-ts/ts-container-columnsplit.md) | Yes    | true         |
856| [Counter](../reference/apis-arkui/arkui-ts/ts-container-counter.md) | Yes    | false         |
857| [EmbeddedComponent](../reference/apis-arkui/arkui-ts/ts-container-embedded-component.md)    | No    | false         |
858| [Flex](../reference/apis-arkui/arkui-ts/ts-container-flex.md) | Yes    | true         |
859| [FlowItem](../reference/apis-arkui/arkui-ts/ts-container-flowitem.md)             | Yes    | true         |
860| [FolderStack](../reference/apis-arkui/arkui-ts/ts-container-folderstack.md)             | Yes    | true         |
861| [FormLink](../reference/apis-arkui/arkui-ts/ts-container-formlink.md)               | No    | false         |
862| [GridCol](../reference/apis-arkui/arkui-ts/ts-container-gridcol.md) | Yes    | true         |
863| [GridRow](../reference/apis-arkui/arkui-ts/ts-container-gridrow.md) | Yes    | true         |
864| [Grid](../reference/apis-arkui/arkui-ts/ts-container-grid.md) | Yes    | true         |
865| [GridItem](../reference/apis-arkui/arkui-ts/ts-container-griditem.md) | Yes    | true         |
866| [Hyperlink](../reference/apis-arkui/arkui-ts/ts-container-hyperlink.md)         | Yes    | true         |
867| [List](../reference/apis-arkui/arkui-ts/ts-container-list.md) | Yes    | true         |
868| [ListItem](../reference/apis-arkui/arkui-ts/ts-container-listitem.md) | Yes    | true         |
869| [ListItemGroup](../reference/apis-arkui/arkui-ts/ts-container-listitemgroup.md) | Yes    | true         |
870| [Navigator](../reference/apis-arkui/arkui-ts/ts-container-navigator.md) | Yes    | true         |
871| [Refresh](../reference/apis-arkui/arkui-ts/ts-container-refresh.md) | Yes    | true        |
872| [RelativeContainer](../reference/apis-arkui/arkui-ts/ts-container-relativecontainer.md) | No    | false         |
873| [Row](../reference/apis-arkui/arkui-ts/ts-container-row.md) | Yes   | true         |
874| [RowSplit](../reference/apis-arkui/arkui-ts/ts-container-rowsplit.md) | Yes    | true         |
875| [Scroll](../reference/apis-arkui/arkui-ts/ts-container-scroll.md) | Yes    | true         |
876| [SideBarContainer](../reference/apis-arkui/arkui-ts/ts-container-sidebarcontainer.md) | Yes    | true         |
877| [Stack](../reference/apis-arkui/arkui-ts/ts-container-stack.md) | Yes    | true         |
878| [Swiper](../reference/apis-arkui/arkui-ts/ts-container-swiper.md) | Yes    | true         |
879| [Tabs](../reference/apis-arkui/arkui-ts/ts-container-tabs.md) | Yes    | true         |
880| [TabContent](../reference/apis-arkui/arkui-ts/ts-container-tabcontent.md) | Yes    | true         |
881| [WaterFlow](../reference/apis-arkui/arkui-ts/ts-container-waterflow.md)         | No    | false         |
882| [WithTheme](../reference/apis-arkui/arkui-ts/ts-container-with-theme.md)         | Yes    | true         |
883
884  **Table 3** Focusability of media components
885
886| Media Component                                    | Focusable| Default Value of focusable|
887| ---------------------------------------- | ----- | ------------ |
888| [Video](../reference/apis-arkui/arkui-ts/ts-media-components-video.md) | Yes    | true         |
889<!--no_check-->