DEV Community

Cover image for Focus event
liu yang
liu yang

Posted on

Focus event

Focus and Blur Events in ArkUI

Focus and Blur Event Callbacks

onFocus(event: () => void)

  • Description: The callback function for the focus event. It is triggered when the component that binds this interface gains focus.

onBlur(event: () => void)

  • Description: The callback function for the blur event. It is triggered when the component that binds this interface loses focus.

The onFocus and onBlur interfaces are typically used in pairs to monitor focus changes of components.

Example: Focus Event Handling

@Entry
@Component
struct FocusEventExample {
  @State oneButtonColor: Color = Color.Gray;
  @State twoButtonColor: Color = Color.Gray;
  @State threeButtonColor: Color = Color.Gray;

  build() {
    Column({ space: 20 }) {
      // Use the up and down keys on an external keyboard to move focus between the three buttons.
      // The button changes color when it gains focus and reverts to the original background color when it loses focus.
      Button('First Button')
        .width(260)
        .height(70)
        .backgroundColor(this.oneButtonColor)
        .fontColor(Color.Black)
        // Listen for the focus event of the first component and change the color when it gains focus.
        .onFocus(() => {
          this.oneButtonColor = Color.Green;
        })
        // Listen for the blur event of the first component and change the color when it loses focus.
        .onBlur(() => {
          this.oneButtonColor = Color.Gray;
        })

      Button('Second Button')
        .width(260)
        .height(70)
        .backgroundColor(this.twoButtonColor)
        .fontColor(Color.Black)
        // Listen for the focus event of the second component and change the color when it gains focus.
        .onFocus(() => {
          this.twoButtonColor = Color.Green;
        })
        // Listen for the blur event of the second component and change the color when it loses focus.
        .onBlur(() => {
          this.twoButtonColor = Color.Gray;
        })

      Button('Third Button')
        .width(260)
        .height(70)
        .backgroundColor(this.threeButtonColor)
        .fontColor(Color.Black)
        // Listen for the focus event of the third component and change the color when it gains focus.
        .onFocus(() => {
          this.threeButtonColor = Color.Green;
        })
        // Listen for the blur event of the third component and change the color when it loses focus.
        .onBlur(() => {
          this.threeButtonColor = Color.Gray;
        })
    }.width('100%').margin({ top: 20 })
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation

  1. Application Launch: Press the TAB key to activate focus. "First Button" displays the focused state style: a blue closed frame around the component, the onFocus callback is triggered, and the background color changes to green.
  2. Press TAB Key: Focus is moved to "Second Button", the onFocus callback is triggered, and the background color changes to green; "First Button" loses focus, the onBlur callback is triggered, and the background color reverts to gray.
  3. Press TAB Key: Focus is moved to "Third Button", the onFocus callback is triggered, and the background color changes to green; "Second Button" loses focus, the onBlur callback is triggered, and the background color reverts to gray.

Setting Component Focusability

focusable(value: boolean)

  • Description: Sets whether a component can gain focus.

Components can be categorized based on their focusability into three types:

  1. Default Focusable Components: These are typically interactive components, such as Button, Checkbox, and TextInput. These components can gain focus by default without setting any properties.
  2. Focusable but Default Non-Focusable Components: Typical examples include Text and Image components. These components cannot gain focus by default. To enable them to gain focus, use the general property focusable(true). For components that have focusability but are default non-focusable and do not have the focusable property configured, configuring an onClick event or a single-finger tap gesture will implicitly make the component focusable. If the focusable property is set to false, the component remains non-focusable even if the above events are configured.
  3. Non-Focusable Components: These are typically display components with no interactive behavior, such as Blank and Circle. These components cannot gain focus even if the focusable property is used.

enabled(value: boolean)

  • Description: Sets the component's interactivity. If enabled is set to false, the component is non-interactive and cannot gain focus.

visibility(value: Visibility)

  • Description: Sets the component's visibility. If visibility is set to Visibility.None or Visibility.Hidden, the component is invisible and cannot gain focus.

focusOnTouch(value: boolean)

  • Description: Sets whether the component supports gaining focus on touch.

Notes

  • When a component is in a focused state, setting its focusable or enabled property to false will automatically cause the component to lose focus. The focus will then be transferred to another component according to the focus movement rules.

Example: Focusable and Enabled Properties

@Entry
@Component
struct FocusableExample {
  @State textFocusable: boolean = true;
  @State textEnabled: boolean = true;
  @State color1: Color = Color.Yellow;
  @State color2: Color = Color.Yellow;
  @State color3: Color = Color.Yellow;

  build() {
    Column({ space: 5 }) {
      Text('Default Text')    // The first Text component does not set the focusable property and is non-focusable by default
        .borderColor(this.color1)
        .borderWidth(2)
        .width(300)
        .height(70)
        .onFocus(() => {
          this.color1 = Color.Blue;
        })
        .onBlur(() => {
          this.color1 = Color.Yellow;
        })
      Divider()

      Text('focusable: ' + this.textFocusable)    // The second Text sets focusable to true initially and focusableOnTouch to true
        .borderColor(this.color2)
        .borderWidth(2)
        .width(300)
        .height(70)
        .focusable(this.textFocusable)
        .focusOnTouch(true)
        .onFocus(() => {
          this.color2 = Color.Blue;
        })
        .onBlur(() => {
          this.color2 = Color.Yellow;
        })

      Text('enabled: ' + this.textEnabled)    // The third Text sets focusable to true and enabled to true initially
        .borderColor(this.color3)
        .borderWidth(2)
        .width(300)
        .height(70)
        .focusable(true)
        .enabled(this.textEnabled)
        .focusOnTouch(true)
        .onFocus(() => {
          this.color3 = Color.Blue;
        })
        .onBlur(() => {
          this.color3 = Color.Yellow;
        })

      Divider()

      Row() {
        Button('Button1')
          .width(140).height(70)
        Button('Button2')
          .width(160).height(70)
      }

      Divider()
      Button('Button3')
        .width(300).height(70)

      Divider()
    }.width('100%').justifyContent(FlexAlign.Center)
    .onKeyEvent((e) => {
      // Bind onKeyEvent to toggle the focusable property of the second Text when the 'F' key is pressed
      if (e.keyCode === 2022 && e.type === KeyType.Down) {
        this.textFocusable = !this.textFocusable;
      }
      // Bind onKeyEvent to toggle the enabled property of the third Text when the 'G' key is pressed
      if (e.keyCode === 2023 && e.type === KeyType.Down) {
        this.textEnabled = !this.textEnabled;
      }
    })
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)