TreeView

The TreeView component represents a tree view used to display a hierarchical list of items. Each item can contain subitems, which may be expanded or collapsed.

This component is applicable in productivity applications, such as side navigation bars in notepad, email, and Gallery applications.

NOTE

  • This component is supported since API version 10. Updates will be marked with a superscript to indicate their earliest API version.

  • If the TreeView component has universal attributes and universal events configured, the compiler toolchain automatically generates an additional Common node and mounts the universal attributes and universal events on this node rather than the TreeView component itself. As a result, the configured universal attributes and universal events may fail to take effect or behave as intended. For this reason, avoid using universal attributes and events with the TreeView component.

Modules to Import

import { TreeView } from "@kit.ArkUI";

Child Components

Not supported

TreeView

TreeView({ treeController: TreeController })

Decorator: @Component

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

Name Type Mandatory Description
treeController TreeController Yes Node information of the tree view.

TreeController

Implements a TreeController object, which can be bound to a tree view component to control the node information of the component. One TreeController object can be bound to only one tree view component.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

addNode

addNode(nodeParam?: NodeParam): TreeController

Adds a child node to the selected node.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

Parameters

Name Type Mandatory Description
nodeParam NodeParam No Node information.

Return value

Type Description
TreeController Controller of the TreeView component.

removeNode

removeNode(): void

Removes the selected node.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

modifyNode

modifyNode(): void

Modifies the selected node.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

buildDone

buildDone(): void

Builds a tree view. After a node is added, this API must be called to save the tree information.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

refreshNode

refreshNode(parentId: number, parentSubTitle: ResourceStr, currentSubtitle: ResourceStr): void

Refreshes the tree view. You can call this API to update the information about the current node.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

Parameters

Name Type Mandatory Description
parentId number Yes ID of the parent node.
The value must be greater than or equal to -1.
parentSubTitle ResourceStr Yes Secondary text of the parent node.
currentSubtitle ResourceStr Yes Secondary text of the current node.

NodeParam

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

Name Type Read-Only Optional Description
parentNodeId number No Yes ID of the parent node.
The value must be greater than or equal to -1.
Default value: -1. The root node ID is -1. If the value is less than -1, the setting does not take effect.
Atomic service API: This API can be used in atomic services since API version 11.
currentNodeId number No Yes Current child node ID.
The value must be greater than or equal to -1.
The value cannot be the root node ID or null. Otherwise, an exception is thrown. In addition, duplicate currentNodeId values are not allowed.
Default value: -1
Atomic service API: This API can be used in atomic services since API version 11.
isFolder boolean No Yes Whether the node is a directory.
Default value: false.
true: The node is a directory. false: The node is not a directory.
Atomic service API: This API can be used in atomic services since API version 11.
icon ResourceStr No Yes Icon.
The default value is an empty string.
Atomic service API: This API can be used in atomic services since API version 11.
symbolIconStyle18+ SymbolGlyphModifier No Yes Symbol icon, which has higher priority than icon.
Default value: undefined
Atomic service API: This API can be used in atomic services since API version 18.
selectedIcon ResourceStr No Yes Icon of the selected node.
The default value is an empty string.
Atomic service API: This API can be used in atomic services since API version 11.
symbolSelectedIconStyle18+ SymbolGlyphModifier No Yes Symbol icon of the selected node., which has higher priority than selectedIcon.
Default value: undefined
Atomic service API: This API can be used in atomic services since API version 18.
editIcon ResourceStr No Yes Edit icon.
The default value is an empty string.
Atomic service API: This API can be used in atomic services since API version 11.
symbolEditIconStyle18+ SymbolGlyphModifier No Yes Symbol edit icon, which has a higher priority than editIcon.
Default value: undefined
Atomic service API: This API can be used in atomic services since API version 18.
primaryTitle ResourceStr No Yes Primary title.
The default value is an empty string.
Atomic service API: This API can be used in atomic services since API version 11.
secondaryTitle ResourceStr No Yes Secondary title.
The default value is an empty string.
Atomic service API: This API can be used in atomic services since API version 11.
container () => void No Yes Right-click child component bound to the node. The child component is decorated with @Builder.
Default value: () => void.
Atomic service API: This API can be used in atomic services since API version 11.

TreeListenerManager

Implements a TreeListenerManager object, which can be bound to a TreeView component to listen for changes of tree nodes. One TreeListenerManager object can be bound to only one tree view component.

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

getInstance

static getInstance(): TreeListenerManager

Obtains a TreeListenerManager singleton object.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

Return value

Type Description
TreeListenerManager TreeListenerManager singleton object.

getTreeListener

getTreeListener(): TreeListener

Obtains a listener.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

Return value

Type Description
TreeListener Obtained listener.

TreeListener

Listener of the tree view component. You can bind it to the TreeView component and use it to listen for changes of tree nodes. One listener can be bound to only one TreeView component.

on

on(type: TreeListenType, callback: (callbackParam: CallbackParam) => void): void;

Register a listener.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

Parameters

Name Type Mandatory Description
type TreeListenType Yes Listening type.
callback (callbackParam: CallbackParam) => void Yes Node information.

once

once(type: TreeListenType, callback: (callbackParam: CallbackParam) => void): void;

Registers a one-off listener.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

Parameters

Name Type Mandatory Description
type TreeListenType Yes Listening type.
callback (callbackParam: CallbackParam) => void Yes Node information.

off

off(type: TreeListenType, callback?: (callbackParam: CallbackParam) => void): void;

Unregisters a listener.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

Parameters

Name Type Mandatory Description
type TreeListenType Yes Listening type.
callback (callbackParam: CallbackParam) => void No Node information.

TreeListenType

Enumerates the listening types of tree view nodes.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

Name Value Description
NODE_CLICK "NodeClick" Listens for click events of nodes.
NODE_ADD "NodeAdd" Listens for add events of nodes.
NODE_DELETE "NodeDelete" Listens for delete events of nodes.
NODE_MODIFY "NodeModify" Listens for modify events of nodes.
NODE_MOVE "NodeMove" Listens for move events of nodes.

CallbackParam

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Device behavior differences: On wearables, calling this API results in a runtime exception indicating that the API is undefined. On other devices, the API works correctly.

Name Type Read-Only Optional Description
currentNodeId number No No ID of the current child node.
The value must be greater than or equal to 0.
parentNodeId number No Yes ID of the current parent node.
The value must be greater than or equal to -1.
Default value: -1
childIndex number No Yes Child index.
The value must be greater than or equal to -1.
Default value: -1

Events

The universal events are not supported.

Example

Example 1: Configuring a Simple Tree View

This example showcases how to use TreeController to perform operations on tree nodes, such as adding, deleting, and renaming. It also demonstrates the effects of adding nodes with different parameters.

import { TreeController, TreeListener, TreeListenerManager, TreeListenType, NodeParam, TreeView, CallbackParam } from '@kit.ArkUI';

@Entry
@Component
struct TreeViewDemo {
  private treeController: TreeController = new TreeController();
  private treeListener: TreeListener = TreeListenerManager.getInstance().getTreeListener();
  @State clickId: number = 0;

  aboutToDisappear(): void {
    this.treeListener.off(TreeListenType.NODE_CLICK, undefined);
    this.treeListener.off(TreeListenType.NODE_ADD, undefined);
    this.treeListener.off(TreeListenType.NODE_DELETE, undefined);
    this.treeListener.off(TreeListenType.NODE_MOVE, undefined);
  }

  @Builder menuBuilder1() {
    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
      Text('Add').fontSize(16).width(100).height(30).textAlign(TextAlign.Center)
        .onClick((event: ClickEvent) => {
          this.treeController.addNode();
        })
      Divider()
      Text('Delete').fontSize(16).width(100).height(30).textAlign(TextAlign.Center)
        .onClick((event: ClickEvent) => {
          this.treeController.removeNode();
        })
      Divider()
      Text('Rename').fontSize(16).width(100).height(30).textAlign(TextAlign.Center)
        .onClick((event: ClickEvent) => {
          this.treeController.modifyNode();
        })
    }.width(100).border({width: 1, color: 0x80808a, radius: '16dp'})
  }

  aboutToAppear(): void {
    this.treeListener.on(TreeListenType.NODE_CLICK, (callbackParam: CallbackParam) => {
      this.clickId = callbackParam.currentNodeId;
    })
    this.treeListener.on(TreeListenType.NODE_ADD, (callbackParam: CallbackParam) => {
      this.clickId = callbackParam.currentNodeId;
    })
    this.treeListener.on(TreeListenType.NODE_DELETE, (callbackParam: CallbackParam) => {
      this.clickId = callbackParam.currentNodeId;
    })
    this.treeListener.once(TreeListenType.NODE_MOVE, (callbackParam: CallbackParam) => {
      this.clickId = callbackParam.currentNodeId;
    })

    let normalResource: Resource = $r('sys.media.ohos_ic_normal_white_grid_folder');
    let selectedResource: Resource = $r('sys.media.ohos_ic_public_select_all');
    let editResource: Resource = $r('sys.media.ohos_ic_public_edit');
    let nodeParam: NodeParam = { parentNodeId:-1, currentNodeId: 1, isFolder: true, icon: normalResource, selectedIcon: selectedResource,
      editIcon: editResource, primaryTitle: "Directory 1 to verify the adaptive effect",
      secondaryTitle: "6" };
    this.treeController
      .addNode(nodeParam)
      .addNode({parentNodeId:1, currentNodeId: 2, isFolder: false, primaryTitle: "Project 1_1" })
      .addNode({ parentNodeId:-1, currentNodeId: 7, isFolder: true, primaryTitle: "Directory 2" })
      .addNode({ parentNodeId:-1, currentNodeId: 23, isFolder: true, icon: normalResource, selectedIcon: selectedResource,
        editIcon: editResource, primaryTitle: "Directory 3" })
      .addNode({ parentNodeId:-1, currentNodeId: 24, isFolder: false, primaryTitle: "Project 4" })
      .addNode({ parentNodeId:-1, currentNodeId: 31, isFolder: true, icon: normalResource, selectedIcon: selectedResource,
        editIcon: editResource, primaryTitle: "Directory 5", secondaryTitle: "0" })
      .addNode({ parentNodeId:-1, currentNodeId: 32, isFolder: true, icon: normalResource, selectedIcon: selectedResource,
        editIcon: editResource, primaryTitle: "Directory 6", secondaryTitle: "0" })
      .addNode({ parentNodeId:32, currentNodeId: 35, isFolder: true, icon: normalResource, selectedIcon: selectedResource,
        editIcon: editResource, primaryTitle: "Directory 6-1", secondaryTitle: "0" })
      .addNode({ parentNodeId:-1, currentNodeId: 33, isFolder: true, icon: normalResource, selectedIcon: selectedResource,
        editIcon: editResource, primaryTitle: "Directory 7", secondaryTitle: "0" })
      .addNode({ parentNodeId:33, currentNodeId: 34, isFolder: false, primaryTitle: "Project 8" })
      .addNode({ parentNodeId:-1, currentNodeId: 36, isFolder: false, primaryTitle: "Project 9" })
      .buildDone();
    this.treeController.refreshNode (-1, "Parent", "Child");
  }

  build() {
    Column(){
      SideBarContainer(SideBarContainerType.Embed)
      {
        TreeView({ treeController: this.treeController })
        Row() {
          Divider().vertical(true).strokeWidth(2).color(0x000000).lineCap(LineCapStyle.Round)
          Column({ space: 30 }) {
            Text('ClickId=' + this.clickId).fontSize('16fp')
            Button('Add', { type: ButtonType.Normal, stateEffect: true })
              .borderRadius(8).backgroundColor(0x317aff).width(90)
              .onClick((event: ClickEvent) => {
                this.treeController.addNode();
              })
            Button('Modify', { type: ButtonType.Normal, stateEffect: true })
              .borderRadius(8).backgroundColor(0x317aff).width(90)
              .onClick((event: ClickEvent) => {
                this.treeController.modifyNode();
              })
            Button('Remove', { type: ButtonType.Normal, stateEffect: true })
              .borderRadius(8).backgroundColor(0x317aff).width(120)
              .onClick((event: ClickEvent) => {
                this.treeController.removeNode();
              })
          }.height('100%').width('70%').alignItems(HorizontalAlign.Start).margin(10)
        }
      }
      .focusable(true)
      .showControlButton(false)
      .showSideBar(true)
    }
  }}

en-us_image_0000001664822257

Example 2: Setting the Symbol Icon

This example demonstrates how to use symbolIconStyle, symbolEditIconStyle, and symbolSelectedIconStyle in NodeParam to set custom symbol icons. This functionality is supported since API version 18.

import { TreeController, TreeListener, TreeListenerManager, TreeListenType, NodeParam, TreeView, CallbackParam,
  SymbolGlyphModifier } from '@kit.ArkUI';

@Entry
@Component
struct TreeViewDemo {
  private treeController: TreeController = new TreeController();
  private treeListener: TreeListener = TreeListenerManager.getInstance().getTreeListener();
  @State clickNodeId: number = 0;

  aboutToDisappear(): void {
    this.treeListener.off(TreeListenType.NODE_CLICK, undefined);
    this.treeListener.off(TreeListenType.NODE_ADD, undefined);
    this.treeListener.off(TreeListenType.NODE_DELETE, undefined);
    this.treeListener.off(TreeListenType.NODE_MOVE, undefined);
  }

  @Builder menuBuilder1() {
    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
      Text('Add').fontSize(16).width(100).height(30).textAlign(TextAlign.Center)
        .onClick((event: ClickEvent) => {
          this.treeController.addNode();
        })
      Divider()
      Text('Delete').fontSize(16).width(100).height(30).textAlign(TextAlign.Center)
        .onClick((event: ClickEvent) => {
          this.treeController.removeNode();
        })
      Divider()
      Text('Rename').fontSize(16).width(100).height(30).textAlign(TextAlign.Center)
        .onClick((event: ClickEvent) => {
          this.treeController.modifyNode();
        })
    }.width(100).border({width: 1, color: 0x80808a, radius: '16dp'})
  }

  aboutToAppear(): void {
    this.treeListener.on(TreeListenType.NODE_CLICK, (callbackParam: CallbackParam) => {
      this.clickNodeId = callbackParam.currentNodeId;
    })
    this.treeListener.on(TreeListenType.NODE_ADD, (callbackParam: CallbackParam) => {
      this.clickNodeId = callbackParam.currentNodeId;
    })
    this.treeListener.on(TreeListenType.NODE_DELETE, (callbackParam: CallbackParam) => {
      this.clickNodeId = callbackParam.currentNodeId;
    })
    this.treeListener.once(TreeListenType.NODE_MOVE, (callbackParam: CallbackParam) => {
      this.clickNodeId = callbackParam.currentNodeId;
    })

    let normalResource: Resource = $r('sys.symbol.house');
    let selectedResource: Resource = $r('sys.symbol.car');
    let editResource: Resource = $r('sys.symbol.calendar');
    let normalSymbolResource: SymbolGlyphModifier = new SymbolGlyphModifier($r('sys.symbol.bell')).fontColor([Color.Red]);
    let selectedSymbolResource: SymbolGlyphModifier = new SymbolGlyphModifier($r('sys.symbol.heart')).fontColor([Color.Blue]);
    let editSymbolResource: SymbolGlyphModifier = new SymbolGlyphModifier($r('sys.symbol.cake')).fontColor([Color.Pink]);
    let nodeParam: NodeParam = { parentNodeId:-1, currentNodeId: 1, isFolder: true, icon: normalResource, selectedIcon: selectedResource,
      editIcon: editResource, primaryTitle: "Directory 1",
      secondaryTitle: "6" };
    this.treeController
      .addNode(nodeParam)
      .addNode({parentNodeId:1, currentNodeId: 2, isFolder: false, primaryTitle: "Project 1_1" })
      .addNode({ parentNodeId:-1, currentNodeId: 7, isFolder: true, primaryTitle: "Directory 2" })
      .addNode({ parentNodeId:-1, currentNodeId: 23, isFolder: true, icon: normalResource, symbolIconStyle: normalSymbolResource,
        selectedIcon: selectedResource, symbolSelectedIconStyle: selectedSymbolResource, editIcon: editResource,
        symbolEditIconStyle: editSymbolResource, primaryTitle: "Directory 3" })
      .addNode({ parentNodeId:-1, currentNodeId: 24, isFolder: false, primaryTitle: "Project 4" })
      .addNode({ parentNodeId:-1, currentNodeId: 31, isFolder: true, icon: normalResource, symbolIconStyle: normalSymbolResource,
        selectedIcon: selectedResource, symbolSelectedIconStyle: selectedSymbolResource, editIcon: editResource,
        symbolEditIconStyle: editSymbolResource, primaryTitle: "Directory 5", secondaryTitle: "0" })
      .addNode({ parentNodeId:-1, currentNodeId: 32, isFolder: true, icon: normalResource, symbolIconStyle: normalSymbolResource,
        selectedIcon: selectedResource, symbolSelectedIconStyle: selectedSymbolResource, editIcon: editResource,
        symbolEditIconStyle: editSymbolResource, primaryTitle: "Directory 6", secondaryTitle: "0" })
      .addNode({ parentNodeId:32, currentNodeId: 35, isFolder: true, icon: normalResource, symbolIconStyle: normalSymbolResource,
        selectedIcon: selectedResource, symbolSelectedIconStyle: selectedSymbolResource, editIcon: editResource,
        symbolEditIconStyle: editSymbolResource, primaryTitle: "Directory 6-1", secondaryTitle: "0" })
      .addNode({ parentNodeId:-1, currentNodeId: 33, isFolder: true, icon: normalResource, symbolIconStyle: normalSymbolResource,
        selectedIcon: selectedResource, symbolSelectedIconStyle: selectedSymbolResource, editIcon: editResource,
        symbolEditIconStyle: editSymbolResource, primaryTitle: "Directory 7", secondaryTitle: "0" })
      .addNode({ parentNodeId:33, currentNodeId: 34, isFolder: false, primaryTitle: "Project 8" })
      .addNode({ parentNodeId:-1, currentNodeId: 36, isFolder: false, primaryTitle: "Project 9" })
      .buildDone();
    this.treeController.refreshNode (-1, "Parent", "Child");
  }

  build() {
    Column(){
      SideBarContainer(SideBarContainerType.Embed)
      {
        TreeView({ treeController: this.treeController })
        Row() {
          Divider().vertical(true).strokeWidth(2).color(0x000000).lineCap(LineCapStyle.Round)
          Column({ space: 30 }) {
            Text('ClickNodeId=' + this.clickNodeId).fontSize('16fp')
            Button('Add', { type: ButtonType.Normal, stateEffect: true })
              .borderRadius(8).backgroundColor(0x317aff).width(90)
              .onClick((event: ClickEvent) => {
                this.treeController.addNode();
              })
            Button('Modify', { type: ButtonType.Normal, stateEffect: true })
              .borderRadius(8).backgroundColor(0x317aff).width(90)
              .onClick((event: ClickEvent) => {
                this.treeController.modifyNode();
              })
            Button('Remove', { type: ButtonType.Normal, stateEffect: true })
              .borderRadius(8).backgroundColor(0x317aff).width(120)
              .onClick((event: ClickEvent) => {
                this.treeController.removeNode();
              })
          }.height('100%').width('80%').alignItems(HorizontalAlign.Start).margin(10)
        }
      }
      .focusable(true)
      .showControlButton(false)
      .showSideBar(true)
    }
  }}

Example 2-Setting the Symbol Icon