@@ -80,7 +80,7 @@ As shown above, the **app.json5** file contains several tags.
| label | Application name. The value is the index to a string resource with a maximum of 63 bytes, supporting multiple languages. For details, see [Configuring Layered Icons](layered-image.md).| String| No|
| description | Description of an application. The value is a string of a maximum of 255 bytes, indicating the description string or the string resource index of the description. This tag can be used to display application information on, for example, the **About** page.| String| Yes (initial value: left empty)|
| vendor | Vendor of the application. The value is a string with a maximum of 255 bytes. This tag can be used to display the vendor information on, for example, the **About** page.| String| Yes (initial value: left empty)|
| versionCode | Version number of an application. The value ranges from 0 to 2147483647. It is used only to determine whether a version is later than another version. A larger value indicates a later version.<br>You can set the value to any positive integer, but you must ensure that the new version of the application uses a value greater than any of its predecessors.| Number| No|
| versionCode | Version number of an application. The value ranges from 0 to 2147483647. It is used only to determine whether a version is later than another version. A larger value indicates a later version.<br>Ensure that a new version of the application uses a value greater than any of its predecessors.| Number| No|
| versionName | Version number of the application displayed to users.<br>The value contains a maximum of 127 bytes and consists of only digits and dots. The four-part format *A.B.C.D* is recommended, wherein:<br>Part 1 (*A*): major version number. A major version consists of major new features or large changes.<br>Part 2 (*B*): minor version number. A minor version consists of some new features and large bug fixes.<br>Part 3 (*C*): feature version number. A feature version consists of scheduled new features.<br>Part 4 (*D*): patch version number. A patch version consists of some bug fixes.| String| No|
| minCompatibleVersionCode | Minimum historical version compatible with the application. It is used for collaboration across devices, data migration, and cross-device compatibility determination. This tag is reserved and the value ranges from 0 to 2147483647.| Number| Yes (initial value: value of **versionCode**)|
| minAPIVersion | Minimum SDK API version required for running an application. The value ranges from 0 to 2147483647.| Number| Yes (This tag is automatically generated during application build and cannot be manually configured. It corresponds to the **compatibleSdkVersion** tag in the [project-level build-profile.json5 file](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-hvigor-build-profile-app#section45865492619)). <!--RP1--><!--RP1End--> |
@@ -98,7 +98,7 @@ As shown above, the **app.json5** file contains several tags.
|targetPriority|Priority of the application. The value ranges from 1 to 100. This tag can be configured only after the **targetBundleName** tag is configured.|Number|Yes (initial value: **1**)|
|generateBuildHash |Whether to generate hash values for all HAP and HSP files of the application by using the packaging tool.<br>If this tag is set to **true**, the packaging tool generates hash values for all HAP and HSP files of the application. The hash values (if any) are used to determine whether the application needs to be updated when the system is updated in OTA mode but the **versionCode** value of the application remains unchanged.<br>- **true**: The packaging tool generates hash values for all HAPs and HSPs of the current application.<br>- **false**: The packaging tool does not generate hash values for all HAPs and HSPs of the current application.<br>**NOTE**<br>This tag takes effect only for pre-installed applications.|Boolean|Yes (initial value: **false**)|
| GWPAsanEnabled | Whether to enable GWP-ASan for detecting memory safety violations, including use-after-free and out-of-bounds memory read/write operations.<br>- **true**: The GWP-asan detection is enabled for the application.<br>- **false**: The GWP-asan detection is disabled for the application.| Boolean| Yes (initial value: **false**)|
| [appEnvironments](#appenvironments)| Application environment variables configured for the current application.| Object array| Yes (initial value: left empty)|
| [appEnvironments](#appenvironments)| Application environment variables configured for the current application.| Object array| Yes (initial value: left empty)|
| maxChildProcess | Maximum number of child processes that can be created by the current application. The value ranges from 0 to 512. The value **0** indicates that the number is not limited. If the application has multiple modules, use the configuration of the **entry** module.| Number| Yes (initial value: <!--RP2-->**1**<!--RP2End-->)|
| [multiAppMode](#multiappmode)| Multi-app mode of the application. This tag takes effect only for the entry or feature module of the application whose **bundleType** is **app**. If there are multiple modules, use the configuration of the **entry** module.| Object| Yes (initial value: left empty)|
| hwasanEnabled | Whether [Hardware-assisted Address Sanitizer (HWASan)](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-hwasan) is enabled for an application. HWAsan is an enhanced Asan improved by the Top-Byte-Ignore feature. Compared with Asan, HWAsan has a lower memory overhead and a larger range of detection for memory errors.<br>- **true**: HWAsan is enabled.<br>- **false**: HWAsan is disabled.<br>**NOTE**<br>This tag is supported since API version 14.| Boolean| Yes (initial value: **false**)|
@@ -39,13 +39,13 @@ A Harmony Shared Package (HSP) is a dynamic shared package that can contain code
## Creating an HSP
Create an HSP module for calling C++ code on DevEco Studio and turn on **Enable native** on the **Configure New Module** page. For details, see [Creating an HSP Module](https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-hsp#section7717162312546). The following uses the **library** module as an example. The basic project directory structure is as follows:
```
```txt
MyApplication
├── library
│ ├── src
│ │ └── main
| | ├── cpp
| | | ├── CMakeLists.txt // Configuration file for compiling native C++ code
| | | ├── CMakeLists.txt // Configuration file for compiling C++ code
| | | └── napi_init.cpp // C++ file for initializing the NAPI module
│ │ ├── ets
│ │ │ └── pages
@@ -408,7 +408,7 @@ export struct Library_Menu {
```
Add the **route_map.json** file (**library/src/main/resources/base/profile/route_map.json**) to the **library** module.
An Object type is a base type for all reference types. Any value, including values of primitive types (they will be automatically boxed), can be directly assigned to variables of the type Object. The Object type is used to represent types other than the primitive types.
An Object type is a base type for all reference types. Any value, including values of primitive types (they will be automatically boxed), can be directly assigned to variables of the type Object.
The Object type is used to represent types other than the primitive types.
```typescript
let o1: Object = 'Alice';
let o2: Object = ['a', 'b'];
let o3: Object = 1;
let o4: object = [1, 2, 3];
```
**Array type**
@@ -270,7 +274,7 @@ let emptyData: NullableObject = null;
### Operators
Assignment operators
**Assignment operators**
Simple assignment operator **=** is used as in **x = y**.
@@ -368,7 +372,7 @@ if (bird instanceof Animal) {
### Statements
**If statement**
**if statement**
An **if** statement is used to execute a sequence of statements when a logical condition is true, or another set of statements (if provided) otherwise.
The **else** part can also contain more **if** statements.
@@ -399,7 +403,7 @@ if (s2.length != 0) {
}
```
**Switch statement**
**switch statement**
A **switch** statement is used to execute a sequence of statements that match the value of a **switch** expression.
The **for** statement is executed repeatedly until the specified loop exit condition result is **false**.
@@ -491,7 +495,7 @@ for (let i = 0; i < 10; i += 2) {
}
```
**For-of statement**
**for-of statement**
You can use the **for-of** statement to iterate over iterable types such as array, Set, Map, and string. A **for-of** statement looks as follows:
@@ -509,7 +513,7 @@ for (let ch of 'a string object') {
}
```
**While statement**
**while statement**
The **while** statement executes **statements** as long as the value of **condition** is **true**. A **while** statement looks as follows:
@@ -530,7 +534,7 @@ while (n < 3) {
}
```
**Do-while statement**
**do-while statement**
If the value of **condition** is truthy (a value that is considered **true**), the **statements** is executed repeatedly. A **do-while** statement looks as follows:
@@ -549,7 +553,7 @@ do {
} while (i < 10)
```
**Break statement**
**break statement**
A **break** statement is used to terminate any loop statement or the **switch** statement.
@@ -580,7 +584,7 @@ label: while (true) {
}
```
**Continue statement**
**continue statement**
A **continue** statement stops the execution of the current loop iteration and passes control to the next iteration.
@@ -596,7 +600,7 @@ for (let x = 0; x < 100; x++) {
}
```
**Throw and Try statements**
**throw and try statements**
A **throw** statement is used to throw an exception or an error:
The last parameter of a function can be a rest parameter in the format of **...restArgs**. It allows functions to take unlimited number of arguments of any specified type.
The last parameter of a function can be a rest parameter in the format of **...restName: Type[]**. It allows a function to receive a variable-length array for processing variable-quantity parameter inputs.
```typescript
function sum(...numbers: number[]): number {
@@ -1136,7 +1140,7 @@ class MyDate implements DateInterface {
**Access to super**
The keyword **super** can be used to access instance fields, instance methods and constructors from the super class. It is often used to extend basic functionality of child class with the required behavior taken from the super class:
The **super** keyword can be used to access the methods and constructors of the super class. It is often used to extend basic functionality of child class with the required behavior taken from the super class:
```typescript
class RectangleSize {
@@ -1161,7 +1165,6 @@ class FilledRectangle extends RectangleSize {
@@ -49,14 +49,12 @@ The display effects are as follows.
This configuration takes effect only when the **module.json5** configuration file does not contain any UIAbility or **icon** and **label** under the **abilities** tag of the UIAbility are not set. (You can manually delete the icon and label configurations).
"label": "$string:app_name" // Configure the resource whose name is app_name in AppScope/resources/base/element/string.json. If the resource already exists, skip this step.
// ...
}
}
```
@@ -65,18 +63,14 @@ The display effects are as follows.
In addition to configuring the **icon** and **label** fields, you need to add **entity.system.home** under **entities** and **ohos.want.action.home** under **actions**.
// Configure the resource whose name is EntryAbility_label in entry/src/main/resources/base/element/string.json. If the resource already exists, skip this step.
"label": "$string:EntryAbility_label",
"label": "$string:EntryAbility_label", // Configure the resource whose name is EntryAbility_label in entry/src/main/resources/base/element/string.json. If the resource already exists, skip this step.
"skills": [
{
"entities": [
@@ -86,10 +80,9 @@ The display effects are as follows.
"ohos.want.action.home"
]
}
]
],
}
],
// ...
]
}
}
```
@@ -116,17 +109,14 @@ The display effects are as follows.
}
```
3. Reference the layered icon resource file in the [app.json5](app-configuration-file.md) file. Example:
"label": "$string:app_name" // Configure the resource whose name is app_name in AppScope/resources/base/element/string.json. If the resource already exists, skip this step.
}
}
```json
{
"app": {
"icon": "$media:app_layered_image",
"label": "$string:app_name" // Configure the resource whose name is app_name in AppScope/resources/base/element/string.json. If the resource already exists, skip this step.
// ...
}
}
```
- **Method 2: Configuring module.json5**
@@ -149,19 +139,15 @@ The display effects are as follows.
3. To display a UIAbility icon on the home screen, you must configure the **icon** and **label** fields, and under the **skills** tag, add **entity.system.home** to **entities** and **ohos.want.action.home** to **actions**.
// Set icon to the index of the layered icon resource file.
"icon": "$media:layered_image",
// Configure the resource whose name is EntryAbility_label in entry/src/main/resources/base/element/string.json. If the resource already exists, skip this step.
"label": "$string:EntryAbility_label",
"icon": "$media:layered_image", // Set icon to the index of the layered icon resource file.
"label": "$string:EntryAbility_label", // Configure the resource whose name is EntryAbility_label in entry/src/main/resources/base/element/string.json. If the resource already exists, skip this step.
"skills": [
{
"entities": [
@@ -171,9 +157,10 @@ The display effects are as follows.
@@ -241,7 +241,7 @@ Application icons cannot be hidden from the home screen:
The system strictly controls applications without icons to prevent malicious applications from deliberately configuring no icon to block uninstall attempts.
Setting the application icon to be displayed on the home screen:<br>Set **icon**, **label**, and **skills** under **abilities** in the **config.json** file. Make sure the **skills** configuration contains **action.system.home** and **entity.system.home**.
@@ -17,7 +17,7 @@ Resources are classified into the following types based on their sources:
Resource files used during application development must be stored in specified directories for management. There are two types of resource directories, namely, resource directories and resource group directories. The resource directories are the **base**, qualifiers, **rawfile**, and **resfile** directories. The resource group directories are the **element**, **media**, and **profile** directories.
```
```text
resources
|---base // Default directory.
| |---element
@@ -249,7 +249,7 @@ If the **attr** attribute is not configured, a string is translated by default.
### Constraints
The **attr** attribute applies to the string, strarray, and plural resources in the **base** directory.
```
```text
resources
|---base
| |---element
@@ -645,6 +645,6 @@ The **module.json5** file in the cross-application overlay resource package supp
If the **module.json5** file of a module contains the **targetModuleName** and **targetPriority fields** during project creation on DevEco Studio, the module is identified as a module with the overlay feature in the installation phase. Modules with the overlay feature generally provide an overlay resource file for other modules on the device, so that the module specified by **targetModuleName** can display different colors, labels, themes, and the like by using the overlay resource file in a running phase.
@@ -25,7 +25,7 @@ For more details, see [Introduction to ArkUI](../ui/arkui-overview.md).
### Application Model
The application model is the abstraction of capabilities required by an application. It provides components and mechanisms required for running the application. By adhering to a unified model, you can streamline application development, making it more efficient and straightforward. For details, see [Elements of the Application Model](../application-models/application-models.md#elements-of-the-application-model).
The application model abstracts the capabilities required by an application and provides components and mechanisms required for running the application. By adhering to a unified model, you can streamline application development, making it more efficient and straightforward. For details, see [Elements of the Application Model](../application-models/application-models.md#elements-of-the-application-model).
Along its evolution, OpenHarmony has provided two application models:
The duration required for a long-press gesture is 600 ms for **bindSelectionMenu** and 800 ms for **bindContextMenu**. When both **bindSelectionMenu** and **bindContextMenu** are set and both are configured to be triggered by a long-press gesture, **bindSelectionMenu** is triggered first.
The duration required for a longpress gesture is 600 ms for **bindSelectionMenu** and 800 ms for **bindContextMenu**. When both **bindSelectionMenu** and **bindContextMenu** are set and both are configured to be triggered by a longpress gesture, **bindSelectionMenu** is triggered first.
If the custom menu is too long, embed a [Scroll](./ts-container-scroll.md) component to prevent the keyboard from being blocked.
@@ -79,7 +79,7 @@ Declares the APIs for accessing Native Accessibility features.
| [int32_t OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused(ArkUI_AccessibilityElementInfo* elementInfo, bool accessibilityFocused)](#oh_arkui_accessibilityelementinfosetaccessibilityfocused) | Sets the accessibility focus state of an **ArkUI_AccessibilityElementInfo** object.|
| [int32_t OH_ArkUI_AccessibilityElementInfoSetSelected(ArkUI_AccessibilityElementInfo* elementInfo, bool selected)](#oh_arkui_accessibilityelementinfosetselected) | Sets whether the **ArkUI_AccessibilityElementInfo** object is selected.|
| [int32_t OH_ArkUI_AccessibilityElementInfoSetClickable(ArkUI_AccessibilityElementInfo* elementInfo, bool clickable)](#oh_arkui_accessibilityelementinfosetclickable) | Sets whether the **ArkUI_AccessibilityElementInfo** object is clickable.|
| [int32_t OH_ArkUI_AccessibilityElementInfoSetEnabled(ArkUI_AccessibilityElementInfo* elementInfo, bool isEnabled)](#oh_arkui_accessibilityelementinfosetenabled) | Sets whether the **ArkUI_AccessibilityElementInfo** object is enabled.|
| [int32_t OH_ArkUI_AccessibilityElementInfoSetIsPassword(ArkUI_AccessibilityElementInfo* elementInfo, bool isPassword)](#oh_arkui_accessibilityelementinfosetispassword) | Sets whether the **ArkUI_AccessibilityElementInfo** object is a password.|
| [int32_t OH_ArkUI_AccessibilityElementInfoSetScrollable(ArkUI_AccessibilityElementInfo* elementInfo, bool scrollable)](#oh_arkui_accessibilityelementinfosetscrollable) | Sets whether the **ArkUI_AccessibilityElementInfo** object is scrollable.|
Sets whether the **ArkUI_AccessibilityElementInfo** object supports long-press gestures.
Sets whether the **ArkUI_AccessibilityElementInfo** object supports longpress gestures.
**Since**: 13
@@ -870,7 +870,7 @@ Sets whether the **ArkUI_AccessibilityElementInfo** object supports long-press g
| Name| Description|
| -- | -- |
| [ArkUI_AccessibilityElementInfo](capi-arkui-accessibility-arkui-accessibilityelementinfo.md)* elementInfo | Pointer to the target **ArkUI_AccessibilityElementInfo** object.|
| bool longClickable | Whether long-press gestures are supported. **true**: supported; **false**: not supported. The default value is **false**.|
| bool longClickable | Whether longpress gestures are supported. **true**: supported; **false**: not supported. The default value is **false**.|
| brand | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Brand color.<br>Affected components: [TextInput](./arkui-ts/ts-basic-components-textinput.md), [Search](./arkui-ts/ts-basic-components-search.md) |
| brand | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Brand color.<br>**Affected components**: [TextInput](./arkui-ts/ts-basic-components-textinput.md), [Search](./arkui-ts/ts-basic-components-search.md) |
| warning | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Warning color.<br>Affected components: [TipsDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#tipsdialog), [AlertDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#alertdialog), [CustomContentDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#customcontentdialog12),<br>[Badge](./arkui-ts/ts-container-badge.md), [Button](./arkui-ts/ts-basic-components-button.md) |
| alert | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Alert color.<br>Affected components: None |
| confirm | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Confirmation color.<br>Affected components: None |
| fontPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Primary font color.<br>Affected components: [EditableTitleBar](./arkui-ts/ohos-arkui-advanced-EditableTitleBar.md), [LoadingDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#loadingdialog) and [TipsDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#tipsdialog)<br>[ConfirmDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#confirmdialog), [AlertDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#alertdialog), [SelectDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#selectdialog),<br>[CustomContentDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#customcontentdialog12), [Swiper](./arkui-ts/ts-container-swiper.md), [Text](./arkui-ts/ts-basic-components-text.md),<br>[SubHeader](./arkui-ts/ohos-arkui-advanced-SubHeader.md), [ProgressButton](./arkui-ts/ohos-arkui-advanced-ProgressButton.md), [AlphabetIndexer](./arkui-ts/ts-container-alphabet-indexer.md),<br>[Popup](./arkui-ts/ohos-arkui-advanced-Popup.md), [Select](./arkui-ts/ts-basic-components-select.md), [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md),<br>[ToolBar](./arkui-ts/ohos-arkui-advanced-ToolBar.md), [Menu](./arkui-ts/ts-basic-components-menu.md), [TextInput](./arkui-ts/ts-basic-components-textinput.md),<br>[Search](./arkui-ts/ts-basic-components-search.md), [Counter](./arkui-ts/ts-container-counter.md), [TimePicker](./arkui-ts/ts-basic-components-timepicker.md), [DatePicker](./arkui-ts/ts-basic-components-datepicker.md),<br>[TextPicker](./arkui-ts/ts-basic-components-textpicker.md), [ComposeListItem](./arkui-ts/ohos-arkui-advanced-ComposeListItem.md), [TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| fontSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Secondary font color.<br>Affected components: [EditableTitleBar](./arkui-ts/ohos-arkui-advanced-EditableTitleBar.md), [AlertDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#alertdialog), [CustomContentDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#customcontentdialog12),<br>[SubHeader](./arkui-ts/ohos-arkui-advanced-SubHeader.md), [AlphabetIndexer](./arkui-ts/ts-container-alphabet-indexer.md), [Popup](./arkui-ts/ohos-arkui-advanced-Popup.md),<br>[TextInput](./arkui-ts/ts-basic-components-textinput.md), [Search](./arkui-ts/ts-basic-components-search.md), [ComposeListItem](./arkui-ts/ohos-arkui-advanced-ComposeListItem.md),<br>[TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| fontTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Tertiary font color.<br>Affected components: [ComposeListItem](./arkui-ts/ohos-arkui-advanced-ComposeListItem.md) |
| fontFourth | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Fourth-level font color.<br>Affected components: None |
| fontEmphasize | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Emphasis font color.<br>Affected components: [TipsDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#tipsdialog), [ConfirmDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#confirmdialog) and [AlertDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#alertdialog)<br>[SelectDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#selectdialog), [CustomContentDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#customcontentdialog12), [SubHeader](./arkui-ts/ohos-arkui-advanced-SubHeader.md),<br>[AlphabetIndexer](./arkui-ts/ts-container-alphabet-indexer.md), [Popup](./arkui-ts/ohos-arkui-advanced-Popup.md), [Button](./arkui-ts/ts-basic-components-button.md),<br>[Select](./arkui-ts/ts-basic-components-select.md), [ToolBar](./arkui-ts/ohos-arkui-advanced-ToolBar.md), [Search](./arkui-ts/ts-basic-components-search.md),<br>[TimePicker](./arkui-ts/ts-basic-components-timepicker.md), [DatePicker](./arkui-ts/ts-basic-components-datepicker.md), [TextPicker](./arkui-ts/ts-basic-components-textpicker.md) |
| fontOnPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Primary inverted font color used on color background.<br>Affected components: [Badge](./arkui-ts/ts-container-badge.md), [Button](./arkui-ts/ts-basic-components-button.md) and [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md)|
| fontOnSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Secondary inverted font color used on color background.<br>Affected components: None|
| fontOnTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Tertiary inverted font color used on color background.<br>Affected components: None|
| fontOnFourth | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Fourth-level inverted font color used on color background.<br>Affected components: None|
| iconPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Primary icon color.<br>Affected components: [EditableTitleBar](./arkui-ts/ohos-arkui-advanced-EditableTitleBar.md), [Swiper](./arkui-ts/ts-container-swiper.md) and [ToolBar](./arkui-ts/ohos-arkui-advanced-ToolBar.md)<br>[TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| iconSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Secondary icon color.<br>Affected components: [LoadingDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#loadingdialog), [SubHeader](./arkui-ts/ohos-arkui-advanced-SubHeader.md) and [LoadingProgress](./arkui-ts/ts-basic-components-loadingprogress.md)<br>[Popup](./arkui-ts/ohos-arkui-advanced-Popup.md), [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md), [Search](./arkui-ts/ts-basic-components-search.md),<br>[TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| iconTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Tertiary icon color.<br>Affected components: [SubHeader](./arkui-ts/ohos-arkui-advanced-SubHeader.md) |
| iconFourth | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Fourth-level icon color.<br>Affected components: [Checkbox](./arkui-ts/ts-basic-components-checkbox.md), [CheckboxGroup](arkui-ts/ts-basic-components-checkboxgroup.md) and [Radio](./arkui-ts/ts-basic-components-radio.md) |
| iconEmphasize | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Emphasis icon color.<br>Affected components: [ToolBar](./arkui-ts/ohos-arkui-advanced-ToolBar.md) |
| iconSubEmphasize | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Color of the emphasis auxiliary icon.<br>Affected components: None |
| iconOnPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Primary inverted icon color used on color background.<br>Affected components: [Checkbox](./arkui-ts/ts-basic-components-checkbox.md), [CheckboxGroup](arkui-ts/ts-basic-components-checkboxgroup.md), [Radio](./arkui-ts/ts-basic-components-radio.md)|
| iconOnSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Secondary inverted icon color used on color background.<br>Affected components: [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md)|
| iconOnTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Tertiary inverted icon color used on color background.<br>Affected components: None|
| iconOnFourth | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Fourth-level inverted icon color used on color background.<br>Affected components: [ProgressButton](./arkui-ts/ohos-arkui-advanced-ProgressButton.md)|
| backgroundPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Primary background color (solid, opaque).<br>Affected components: [TextInput](./arkui-ts/ts-basic-components-textinput.md), [QRCode](./arkui-ts/ts-basic-components-qrcode.md) |
| backgroundSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Secondary background color (solid, opaque).<br>Affected components: None |
| backgroundTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Tertiary background color (solid, opaque).<br>Affected components: None |
| backgroundFourth | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Fourth-level background color (solid, opaque).<br>Affected components: None |
| backgroundEmphasize | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Emphasis background color (solid, opaque).<br>Affected components: [Progress](./arkui-ts/ts-basic-components-progress.md), [Button](./arkui-ts/ts-basic-components-button.md) and [Slider](./arkui-ts/ts-basic-components-slider.md) |
| compForegroundPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Foreground.<br>Affected components: [QRCode](./arkui-ts/ts-basic-components-qrcode.md) |
| compBackgroundPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | White background.<br>Affected components: none |
| compBackgroundPrimaryTran | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | White transparent background.<br>Affected components: none |
| compBackgroundPrimaryContrary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Always-on background.<br>Affected components: [Toggle](./arkui-ts/ts-basic-components-toggle.md) and [Slider](./arkui-ts/ts-basic-components-slider.md) |
| compBackgroundGray | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Gray background.<br>Affected components: none |
| compBackgroundSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Secondary background.<br>Affected components: [Swiper](./arkui-ts/ts-container-swiper.md) and [Slider](./arkui-ts/ts-basic-components-slider.md) |
| compBackgroundTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Tertiary background.<br>Affected components: [EditableTitleBar](./arkui-ts/ohos-arkui-advanced-EditableTitleBar.md), [Progress](./arkui-ts/ts-basic-components-progress.md) and [AlphabetIndexer](./arkui-ts/ts-container-alphabet-indexer.md)<br>[Button](./arkui-ts/ts-basic-components-button.md), [Select](./arkui-ts/ts-basic-components-select.md), [Toggle](./arkui-ts/ts-basic-components-toggle.md),<br>[Chip](./arkui-ts/ohos-arkui-advanced-Chip.md), [TextInput](./arkui-ts/ts-basic-components-textinput.md), [Search](./arkui-ts/ts-basic-components-search.md) |
| compBackgroundEmphasize | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Emphasis background.<br>Affected components: [Swiper](./arkui-ts/ts-container-swiper.md), [Toggle](./arkui-ts/ts-basic-components-toggle.md) and [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md)<br>[Checkbox](./arkui-ts/ts-basic-components-checkbox.md), [CheckboxGroup](arkui-ts/ts-basic-components-checkboxgroup.md), [Radio](./arkui-ts/ts-basic-components-radio.md) |
| compBackgroundNeutral | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Black, neutral, emphasis background.<br>Affected components: [PatternLock](./arkui-ts/ts-basic-components-patternlock.md) |
| compEmphasizeSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | 20% emphasis background color.<br>Affected components: [Progress](./arkui-ts/ts-basic-components-progress.md), [ProgressButton](./arkui-ts/ohos-arkui-advanced-ProgressButton.md) and [AlphabetIndexer](./arkui-ts/ts-container-alphabet-indexer.md)<br>[Select](./arkui-ts/ts-basic-components-select.md), [Toggle](./arkui-ts/ts-basic-components-toggle.md) |
| compEmphasizeTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | 10% emphasis background color.<br>Affected components: None |
| compDivider | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common divider color.<br>Affected components: [SelectDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#selectdialog), [PatternLock](./arkui-ts/ts-basic-components-patternlock.md) and [Divider](./arkui-ts/ts-basic-components-divider.md) |
| compCommonContrary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common inverted color.<br>Affected components: None |
| compBackgroundFocus | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Background color in the focused state.<br>Affected components: None |
| compFocusedPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Primary inverted color in the focused state.<br>Affected components: None |
| compFocusedSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Secondary inverted color in the focused state.<br>Affected components: None |
| compFocusedTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Tertiary inverted color in the focused state.<br>Affected components: [Scroll](arkui-ts/ts-container-scroll.md) |
| interactiveHover | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common interactive color for the hover state.<br>Affected components: [EditableTitleBar](./arkui-ts/ohos-arkui-advanced-EditableTitleBar.md), [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md) and [TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| interactivePressed | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common interactive color for the pressed state.<br>Affected components: [EditableTitleBar](./arkui-ts/ohos-arkui-advanced-EditableTitleBar.md), [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md) and [TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| interactiveFocus | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common interactive color for the focused state.<br>Affected components: [EditableTitleBar](./arkui-ts/ohos-arkui-advanced-EditableTitleBar.md), [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md) and [TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| interactiveActive | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common interactive color for the active state.<br>Affected components: [TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| interactiveSelect | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common interactive color for the selected state.<br>Affected components: [TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| interactiveClick | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common interactive color for the clicked state.<br>Affected components: None |
| alert | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Alert color.<br>**Affected components**: N/A |
| confirm | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Confirmation color.<br>**Affected components**: N/A |
| fontSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Secondary font color.<br>**Affected components**: [EditableTitleBar](./arkui-ts/ohos-arkui-advanced-EditableTitleBar.md), [AlertDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#alertdialog), [CustomContentDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#customcontentdialog12),<br>[SubHeader](./arkui-ts/ohos-arkui-advanced-SubHeader.md), [AlphabetIndexer](./arkui-ts/ts-container-alphabet-indexer.md), [Popup](./arkui-ts/ohos-arkui-advanced-Popup.md),<br>[TextInput](./arkui-ts/ts-basic-components-textinput.md), [Search](./arkui-ts/ts-basic-components-search.md), [ComposeListItem](./arkui-ts/ohos-arkui-advanced-ComposeListItem.md),<br>[TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| fontTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Tertiary font color.<br>**Affected components**: [ComposeListItem](./arkui-ts/ohos-arkui-advanced-ComposeListItem.md) |
| fontFourth | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Fourth-level font color.<br>**Affected components**: N/A |
| fontEmphasize | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Emphasis font color.<br>**Affected components**: [TipsDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#tipsdialog), [ConfirmDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#confirmdialog), [AlertDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#alertdialog)<br>[SelectDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#selectdialog), [CustomContentDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#customcontentdialog12), [SubHeader](./arkui-ts/ohos-arkui-advanced-SubHeader.md),<br>[AlphabetIndexer](./arkui-ts/ts-container-alphabet-indexer.md), [Popup](./arkui-ts/ohos-arkui-advanced-Popup.md), [Button](./arkui-ts/ts-basic-components-button.md),<br>[Select](./arkui-ts/ts-basic-components-select.md), [ToolBar](./arkui-ts/ohos-arkui-advanced-ToolBar.md), [Search](./arkui-ts/ts-basic-components-search.md),<br>[TimePicker](./arkui-ts/ts-basic-components-timepicker.md), [DatePicker](./arkui-ts/ts-basic-components-datepicker.md), [TextPicker](./arkui-ts/ts-basic-components-textpicker.md) |
| fontOnPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Primary inverted font color used on color background.<br>**Affected components**: [Badge](./arkui-ts/ts-container-badge.md), [Button](./arkui-ts/ts-basic-components-button.md), [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md)|
| fontOnSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Secondary inverted font color used on color background.<br>**Affected components**: N/A|
| fontOnTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Tertiary inverted font color used on color background.<br>**Affected components**: N/A|
| fontOnFourth | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Fourth-level inverted font color used on color background.<br>**Affected components**: N/A|
| iconPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Primary icon color.<br>**Affected components**: [EditableTitleBar](./arkui-ts/ohos-arkui-advanced-EditableTitleBar.md), [Swiper](./arkui-ts/ts-container-swiper.md), [ToolBar](./arkui-ts/ohos-arkui-advanced-ToolBar.md)<br>[TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| iconSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Secondary icon color.<br>**Affected components**: [LoadingDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#loadingdialog), [SubHeader](./arkui-ts/ohos-arkui-advanced-SubHeader.md), [LoadingProgress](./arkui-ts/ts-basic-components-loadingprogress.md)<br>[Popup](./arkui-ts/ohos-arkui-advanced-Popup.md), [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md), [Search](./arkui-ts/ts-basic-components-search.md),<br>[TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| iconTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Tertiary icon color.<br>**Affected components**: [SubHeader](./arkui-ts/ohos-arkui-advanced-SubHeader.md) |
| iconFourth | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Fourth-level icon color.<br>**Affected components**: [Checkbox](./arkui-ts/ts-basic-components-checkbox.md), [CheckboxGroup](arkui-ts/ts-basic-components-checkboxgroup.md), [Radio](./arkui-ts/ts-basic-components-radio.md) |
| iconEmphasize | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Emphasis icon color.<br>**Affected components**: [ToolBar](./arkui-ts/ohos-arkui-advanced-ToolBar.md) |
| iconSubEmphasize | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Color of the emphasis auxiliary icon.<br>**Affected components**: N/A |
| iconOnPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Primary inverted icon color used on color background.<br>**Affected components**: [Checkbox](./arkui-ts/ts-basic-components-checkbox.md), [CheckboxGroup](arkui-ts/ts-basic-components-checkboxgroup.md), [Radio](./arkui-ts/ts-basic-components-radio.md)|
| iconOnSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Secondary inverted icon color used on color background.<br>**Affected components**: [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md)|
| iconOnTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Tertiary inverted icon color used on color background.<br>**Affected components**: N/A|
| iconOnFourth | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Fourth-level inverted icon color used on color background.<br>**Affected components**: [ProgressButton](./arkui-ts/ohos-arkui-advanced-ProgressButton.md)|
| backgroundPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Primary background color (solid, opaque).<br>**Affected components**: [TextInput](./arkui-ts/ts-basic-components-textinput.md), [QRCode](./arkui-ts/ts-basic-components-qrcode.md) |
| backgroundSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Secondary background color (solid, opaque).<br>**Affected components**: N/A |
| backgroundTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Tertiary background color (solid, opaque).<br>**Affected components**: N/A |
| backgroundFourth | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Fourth-level background color (solid, opaque).<br>**Affected components**: N/A |
| backgroundEmphasize | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Emphasis background color (solid, opaque).<br>**Affected components**: [Progress](./arkui-ts/ts-basic-components-progress.md), [Button](./arkui-ts/ts-basic-components-button.md), [Slider](./arkui-ts/ts-basic-components-slider.md) |
| compForegroundPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Foreground.<br>**Affected components**: [QRCode](./arkui-ts/ts-basic-components-qrcode.md) |
| compBackgroundPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | White background.<br>**Affected components**: N/A |
| compBackgroundPrimaryTran | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | White transparent background.<br>**Affected components**: N/A |
| compBackgroundPrimaryContrary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Always-on background.<br>**Affected components**: [Toggle](./arkui-ts/ts-basic-components-toggle.md), [Slider](./arkui-ts/ts-basic-components-slider.md) |
| compBackgroundGray | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Gray background.<br>**Affected components**: N/A |
| compBackgroundSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Secondary background.<br>**Affected components**: [Swiper](./arkui-ts/ts-container-swiper.md), [Slider](./arkui-ts/ts-basic-components-slider.md) |
| compBackgroundTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Tertiary background.<br>**Affected components**: [EditableTitleBar](./arkui-ts/ohos-arkui-advanced-EditableTitleBar.md), [Progress](./arkui-ts/ts-basic-components-progress.md), [AlphabetIndexer](./arkui-ts/ts-container-alphabet-indexer.md)<br>[Button](./arkui-ts/ts-basic-components-button.md), [Select](./arkui-ts/ts-basic-components-select.md), [Toggle](./arkui-ts/ts-basic-components-toggle.md),<br>[Chip](./arkui-ts/ohos-arkui-advanced-Chip.md), [TextInput](./arkui-ts/ts-basic-components-textinput.md), [Search](./arkui-ts/ts-basic-components-search.md) |
| compBackgroundEmphasize | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Emphasis background.<br>**Affected components**: [Swiper](./arkui-ts/ts-container-swiper.md), [Toggle](./arkui-ts/ts-basic-components-toggle.md), [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md)<br>[Checkbox](./arkui-ts/ts-basic-components-checkbox.md), [CheckboxGroup](arkui-ts/ts-basic-components-checkboxgroup.md), [Radio](./arkui-ts/ts-basic-components-radio.md) |
| compBackgroundNeutral | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Black, neutral, emphasis background.<br>**Affected components**: [PatternLock](./arkui-ts/ts-basic-components-patternlock.md) |
| compEmphasizeSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | 20% emphasis background color.<br>**Affected components**: [Progress](./arkui-ts/ts-basic-components-progress.md), [ProgressButton](./arkui-ts/ohos-arkui-advanced-ProgressButton.md), [AlphabetIndexer](./arkui-ts/ts-container-alphabet-indexer.md)<br>[Select](./arkui-ts/ts-basic-components-select.md), [Toggle](./arkui-ts/ts-basic-components-toggle.md) |
| compEmphasizeTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | 10% emphasis background color.<br>**Affected components**: N/A |
| compDivider | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common divider color.<br>**Affected components**: [SelectDialog](./arkui-ts/ohos-arkui-advanced-Dialog.md#selectdialog), [PatternLock](./arkui-ts/ts-basic-components-patternlock.md), [Divider](./arkui-ts/ts-basic-components-divider.md) |
| compCommonContrary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common inverted color.<br>**Affected components**: N/A |
| compBackgroundFocus | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Background color in the focused state.<br>**Affected components**: N/A |
| compFocusedPrimary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Primary inverted color in the focused state.<br>**Affected components**: N/A |
| compFocusedSecondary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Secondary inverted color in the focused state.<br>**Affected components**: N/A |
| compFocusedTertiary | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Tertiary inverted color in the focused state.<br>**Affected components**: [Scroll](arkui-ts/ts-container-scroll.md) |
| interactiveHover | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common interactive color for the hover state.<br>**Affected components**: [EditableTitleBar](./arkui-ts/ohos-arkui-advanced-EditableTitleBar.md), [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md), [TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| interactivePressed | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common interactive color for the pressed state.<br>**Affected components**: [EditableTitleBar](./arkui-ts/ohos-arkui-advanced-EditableTitleBar.md), [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md), [TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| interactiveFocus | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common interactive color for the focused state.<br>**Affected components**: [EditableTitleBar](./arkui-ts/ohos-arkui-advanced-EditableTitleBar.md), [Chip](./arkui-ts/ohos-arkui-advanced-Chip.md), [TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| interactiveActive | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common interactive color for the active state.<br>**Affected components**: [TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| interactiveSelect | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common interactive color for the selected state.<br>**Affected components**: [TreeView](./arkui-ts/ohos-arkui-advanced-TreeView.md) |
| interactiveClick | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | No | No | Common interactive color for the clicked state.<br>**Affected components**: N/A |
## CustomTheme
@@ -100,7 +100,7 @@ Defines a custom theme object.
| colors | [CustomColors](#customcolors) | No | Yes | Color resources of the custom theme.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
| darkColors<sup>20+</sup> | [CustomDarkColors](#customdarkcolors20) | No | Yes | Custom dark theme color resources.<br>Note: If **darkColors** is not configured, the color values will default to those specified in the **colors** configuration for light mode and will not adapt to dark mode changes, unless the colors are defined using resources from the **dark** directory.<br>**Atomic service API**: This API can be used in atomic services since API version 20.|
@@ -131,7 +131,7 @@ Defines the type for dark theme color resources.
| Type | Description |
|-----|--------------|
| Partial<[Colors](#colors)> | Customizes dark theme color resources.|
| Partial<[Colors](#colors)> | Type representing customizable dark theme color resources.|
## ThemeControl
@@ -145,7 +145,7 @@ Implements a **ThemeControl** object to apply the custom theme to the components
Applies a custom theme to an app to implement theme-based style switching. If this API is used to set the application-level default theme on a page, ensure that this API is executed before the page is built. If this API is used to set the application-level default theme in UIAbility, ensure that this API is executed in the callback function after the windowStage.[loadContent](./arkts-apis-window-Window.md#loadcontent9) API is called in the onWindowStageCreate phase. For details, see [Setting Custom Theme Colors for Application Components](../../ui/theme_skinning.md#setting-custom-theme-colors-for-application-components).
Sets a custom theme as the default, application-level theme, applying it to all components within the application. When using this API within a page, ensure that the API is called before the page's **build** API executes. When using this API within a UIAbility, ensure that the API is called in the callback after windowStage.[loadContent](./arkts-apis-window-WindowStage.md#loadcontent9) during the **onWindowStageCreate** lifecycle phase. For a complete implementation example, see [Setting Custom Theme Colors for Application Components](../../ui/theme_skinning.md#setting-custom-theme-colors-for-application-components).
**Atomic service API**: This API can be used in atomic services since API version 12.
@@ -163,8 +163,8 @@ Applies a custom theme to an app to implement theme-based style switching. If th
import { CustomTheme, CustomColors, ThemeControl } from '@kit.ArkUI';
// Custom theme color
class BlueColors implements CustomColors {
fontPrimary = Color.Red;
backgroundPrimary = Color.Blue;
fontPrimary = "#FF707070";
backgroundPrimary = "#FF2787D9";
brand = "#FFEEAAFF"; // Brand color.
}
@@ -196,8 +196,8 @@ struct Index {
QRCode('Hello')
.width(100)
.height(100)
// Apply brand to the cursor color of the text box.
Obtains the authorization list of the specified authentication type for an application account. The authorization list contains all authorized bundles. The token authorization list is set by setOAuthTokenVisibility(#setoauthtokenvisibilitydeprecated). This API uses an asynchronous callback to return the result.
Obtains the authorization list of the specified authentication type for an application account. The authorization list contains all authorized bundles. The token authorization list is set by [setOAuthTokenVisibility](#setoauthtokenvisibilitydeprecated). This API uses an asynchronous callback to return the result.
> **NOTE**
>
@@ -4834,7 +4834,7 @@ Obtains the authorization list of the specified authentication type for an appli
Obtains the authorization list of the specified authentication type for an application account. The authorization list contains all authorized bundles. The token authorization list is set by setOAuthTokenVisibility(#setoauthtokenvisibilitydeprecated). This API uses a promise to return the result.
Obtains the authorization list of the specified authentication type for an application account. The authorization list contains all authorized bundles. The token authorization list is set by [setOAuthTokenVisibility](#setoauthtokenvisibilitydeprecated). This API uses a promise to return the result.
The **ArcButton** component represents an arc button specifically designed for circular screens. It offers various button styles, such as emphasized, normal, and warning, tailored for watch UIs. For details, see [ArcButton](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-ArcButton.md).
The **ArcButton** component is supported since API version 18. The **ArcButton** component represents an arc button specifically designed for circular screens. It offers various button styles, such as emphasized, normal, and warning, tailored for watch UIs. For details, see [ArcButton](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-ArcButton.md).
## Creating a Button
@@ -145,7 +151,23 @@ The **ArcButton** component offers two types: top arc button and bottom arc butt
This example demonstrates a brightness settings screen where a slider displays the current brightness level at 30%. When the reset button is clicked, the brightness value is reset to the default value of 50%.
```ts
To run this sample code, wearable device support is required. In the project configuration file [module.json5](../quick-start/module-configuration-file.md) located in the **src/main** directory, configure **wearable** under [devicetypes](../quick-start/module-configuration-file.md#devicetypes).
```json
// module.json5
{
"module": {
// ...
"deviceTypes": [
"wearable",
"phone"
]
// ...
}
}
```
```ts
import { LengthMetrics, LengthUnit, ArcButton, ArcButtonOptions, ArcButtonStyleMode } from '@kit.ArkUI';
Continuous visual effects on the UI resulting from changes to animatable properties are called property animations. As the most fundamental and intuitive type of animation, property animations form the core of UI animation systems. ArkUI provides three animation APIs to create these effects: [animateTo](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#animateto), [animation](../reference/apis-arkui/arkui-ts/ts-animatorproperty.md), and [keyframeAnimateTo](../reference/apis-arkui/arkui-ts/ts-keyframeAnimateTo.md).
> **NOTE**
@@ -15,21 +14,21 @@ Continuous visual effects on the UI resulting from changes to animatable propert
| Animation API| Scope| Principle| Use Scenario|
| -------- | -------- | -------- | -------- |
| animateTo | UI changes caused by property changes in closures.<br>Transition for appearance and disappearance.| This API is a common function. It animates the differences between the UIs before and after state variables in the closure change.<br>This API supports multiple calls and nesting.| A single set of animation parameters is used to animate multiple properties.<br>Animations need to be nested.|
| animateTo | UI changes caused by property changes in closures.<br>Transition for appearance and disappearance.| This API is a common function. It animates the differences between the UIs before and after state variables in the closure change.<br>This API supports multiple calls and nesting.| A single set of animation parameters is used to animate multiple properties.<br>Animations need to be nested.<br>Note: To achieve multiple animation cycles, it is recommended that you set the **playMode** and **iterations** properties of [AnimateParam](../reference/apis-arkui/arkui-ts/ts-explicit-animation.md#animateparam) or use **keyframeAnimateTo**.|
| animation | UI changes caused by property changes bound to components through property APIs.| This API automatically detects changes to animatable properties and applies animations.<br>As the API call sequence of the component is from bottom to top, this API applies only to the properties declared above it in the component chain.<br>In a component, you can set **animation** for individual properties based on the API call sequence.| Different animation parameters are used for different properties.|
| keyframeAnimateTo | Segmented property animation caused by property changes in multiple closures.| This API is a common function. It animates the difference between state variables in each closure and the previous state.<br>This API supports multiple calls, but nesting is not recommended.| Multiple animations are applied to the same property sequentially.|
The [animateTo](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#animateto) API takes an [AnimateParam](../reference/apis-arkui/arkui-ts/ts-explicit-animation.md#animateparam) object (specifying the duration and [Curve](../reference/apis-arkui/js-apis-curve.md#curve)) and an **event** closure function. Property animations generated by variable changes within the closure follow the same animation parameters.
> **NOTE**
>
>
> Directly using **animateTo** can lead to the issue of [ambiguous UI context](./arkts-global-interface.md). To avoid this, obtain the [UIContext](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md) object using the [getUIContext()](../reference/apis-arkui/arkui-ts/ts-custom-component-api.md#getuicontext) API and then call the [animateTo](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#animateto) API through this object.
> - When an animation is applied to the position or size change of a component, as layout measurement is involved, performance overheads are high. To reduce performance overheads, use the [scale](../reference/apis-arkui/arkui-ts/ts-universal-attributes-transformation.md#scale) attribute instead, whose value change does not involve layout re-measurement. This practice is applicable where the component position and size change continuously, for example, where the component size changes as a response to gestures.
>
>
> - Apply property animations only to consistently visible components. For those components whose visibility may change, use the [transition animation](arkts-transition-overview.md).
>
>
> - Avoid using end callbacks with property animations. Property animations are applied to states that have occurred. As such, you do not need to process the end logic. If end callbacks are needed, be sure to correctly handle the data management for continuous operations.
>
> - If transition animations are disabled in Developer options, or if the UIAbility switches from the foreground to the background, the end callback will be triggered immediately. You are advised to verify your scenario and avoid placing time‑dependent logic in this callback.
**RichEditor** is a component that supports interactive text editing and mixing of text and images. It's commonly used in scenarios requiring mixed-content user input, such as comment sections that accept both images and text. For details, see [RichEditor](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md).
**RichEditor** is a component that supports interactive text editing and mixture of text and images. It is typically used in scenarios where mixed-content user input is expected, such as comment sections that accept both image and text submissions. For details, see [RichEditor](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md).
For displaying only images and text, use the [Text](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md) component.
If you only need to display images and text, the [Text](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md) component is recommended.
For displaying large amounts of HTML content, use the [RichText](../reference/apis-arkui/arkui-ts/ts-basic-components-richtext.md) component.
If you need to display a large amount of HTML content, the [RichText](../reference/apis-arkui/arkui-ts/ts-basic-components-richtext.md) component is recommended.
## Component Structure
## Component Composition
The following diagram shows the component's element structure.
The following figure illustrates the component's elements.
| Content area | Area where content is displayed. |
| Cursor | Current input position. |
| Handle | Left and right handles that can be dragged separately to adjust the text selection range. |
| Menu | Displayed after content selection, containing operation buttons like copy and paste. |
The component's elements are described as follows.
| Element | Description |
| --- | ------------------------------- |
| Content area| Area where content is displayed. |
| Cursor | Indicates the current insertion position. |
| Handles | Left and right handles that can be dragged separately to adjust the text selection range.|
| Menu | Appears after content is selected, containing operation buttons such as copy and paste. |
## Creating a RichEditor Component
Create a RichEditor component using styled strings or spans. See [Creating a RichEditor Component with Styled Strings](#creating-a-richeditor-component-with-styled-strings) or [Creating a RichEditor Component with Spans](#creating-a-richeditor-component-with-spans).
You can create a **RichEditor** component either from a styled string or from spans. For details, see [Creating a RichEditor Component from a Styled String](#creating-a-richeditor-component-from-a-styled-string) or [Creating a RichEditor Component from Spans](#creating-a-richeditor-component-from-spans).
### Creating a RichEditor Component with Styled Strings
### Creating a RichEditor Component from a Styled String
Use the RichEditor(options: [RichEditorStyledStringOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorstyledstringoptions12)) API to create a RichEditor component that manages content using styled strings ([StyledString/MutableStyledString](arkts-styled-string.md)). This approach allows you to manage data by maintaining styled string objects on the application side, modifying their content and style, then passing the updated objects to the component to refresh the rich text content.
Use the RichEditor(options: [RichEditorStyledStringOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorstyledstringoptions12)) API to create a **RichEditor** component that manages content through styled strings ([StyledString/MutableStyledString](arkts-styled-string.md)). This approach allows you to manage data by holding styled string objects on the application side, modify the content and style of those objects, and then pass the updated objects to the component to refresh the rich text content.
Compared to using controller APIs for content style updates, this method offers greater flexibility and convenience. Additionally, styled string objects can be applied to various text components that support styled strings for quick content migration.
Compared with using controller APIs for content style updates, this approach offers greater flexibility and convenience. In addition, styled string objects can be assigned to various text components that support styled strings, enabling quick content migration.
Use the RichEditor(value: [RichEditorOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditoroptions)) API to create a RichEditor component that manages content using spans. This component is typically used in complex content scenarios. Developers can use the APIs provided by RichEditorController to manage content and styles.
Use the RichEditor(value: [RichEditorOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditoroptions)) API to create a **RichEditor** component that manages content via spans. This component is typically used in complex content scenarios. You can use the APIs provided by **RichEditorController** to manage content and styles.
```ts
@Entry
@@ -94,15 +96,15 @@ struct create_rich_editor {
## Adding Content
The rich text component can add various types of content through different APIs.
The **RichEditor** component supports adding content in different forms through various APIs.
### Adding Text Spans
### Adding a Text Span
In addition to direct input, you can add text spans using the [addTextSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addtextspan) API.
In addition to directly entering content into the component, you can add a text span using the [addTextSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addtextspan) API.
This API enables diverse text styling, such as creating mixed-format text.
This API enables diverse text styling, such as creating mixed-style text.
If the component is focused and the cursor is blinking, the cursor position updates after adding text via addTextSpan, and the cursor blinks to the right of the newly added text.
If the component is focused and the cursor is blinking, adding text via **addTextSpan** updates the cursor position, and the cursor blinks to the right of the newly added text.
Use the [addImageSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addimagespan) API to add image spans.
Use the [addImageSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addimagespan) API to add an image span.
This API enriches and visualizes content. For example, you can add images to news articles or data visualization graphics in documents.
This API is useful in enriching and visualizing content. For example, you can use it to add images to news or data visualization graphics to documents.
If the component is focused and the cursor is blinking, the cursor position updates after adding an image via addImageSpan, and the cursor blinks to the right of the newly added image.
If the component is focused and the cursor is blinking, adding image content via **addImageSpan** updates the cursor position, and the cursor blinks to the right of the newly added image.
```ts
controller: RichEditorController = new RichEditorController();
Use [addBuilderSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addbuilderspan11) to add content decorated with @Builder.
Use [addBuilderSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addbuilderspan11) to add the content decorated by the @Builder decorator.
This approach is suitable for integrating custom complex components, such as custom charts.
This approach applies when you need to integrate custom complex components, such as custom charts.
Use [RichEditorBuilderSpanOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorbuilderspanoptions11) to specify the insertion position. If no position is specified or an invalid value is provided, the builder content is appended to the end.
With this API, you can specify the addition position using [RichEditorBuilderSpanOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorbuilderspanoptions11). If no position is specified or an invalid value is provided, the builder content is appended to the end.
Use the [addSymbolSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addsymbolspan11) API to add symbol content. This API can add special symbols, such as mathematical symbols when editing academic papers.
Use the [addSymbolSpan](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#addsymbolspan11) API to add symbol content. This API enables addition of special characters, such as mathematical symbols in academic papers.
When adding a symbol while the component is focused and the cursor is blinking, the cursor moves to the right of the newly inserted symbol.
When a symbol is added while the component is focused and the cursor is blinking, the cursor moves to the right of the newly inserted symbol.
Currently, gestures, copying, and dragging are not supported for symbol content.
Currently, gestures, copying, and dragging are not supported for the symbol content.
```ts
controller: RichEditorController = new RichEditorController();
The rich text component provides APIs for content management, such as retrieving image and text information (see [Retrieving Image and Text Information](#retrieving-image-and-text-information)), setting placeholder text (see [Setting Placeholder Text](#setting-placeholder-text)), or limiting content length (see [Setting Maximum Length](#setting-maximum-length)).
The **RichEditor** component provides APIs for content management, for example, [obtaining image and text information within the component](#obtaining-the-image-and-text-information), [setting placeholder text when no input is present](#setting-placeholder-text), or [limiting the maximum character](#setting-the-maximum-length).
### Retrieving Image and Text Information
### Obtaining the Image and Text Information
Use the [getSpans](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#getspans) API to retrieve information about all images and text in the component, including content, ID, style, and position. After obtaining position information, you can update the style of content within a specified range.
Use the [getSpans](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#getspans) API to obtain information about all images and text in the component, including content, ID, style, and position. After obtaining the position information, you can update the style of the content in the specified range.
This API is useful for inspecting existing content styles, such as in template use cases, and for content parsing and processing, such as in text analysis applications.
This API is useful for obtaining and checking existing content styles, such as in template use cases, and for content parsing and processing, such as in text analysis applications.
```ts
controller: RichEditorController = new RichEditorController();
@@ -314,9 +316,9 @@ Button('getSpans', {
### Setting Placeholder Text
Use the [placeholder](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#placeholder12) API to set hint text displayed when there is no input.
You can set the placeholder text, which is displayed when there is no input, using the [placeholder](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#placeholder12) API.
Placeholder text provides useful guidance, helping users navigate the application UI, especially in scenarios requiring specific input, such as login screens. For example, in a text editor, placeholder text can specify input requirements like "Enter up to 100 characters" to guide user actions.
Placeholder text provides useful guidance, helping users navigate the application UI, especially in scenarios requiring specific input, such as login screens. For example, in a text editing box, placeholder text can specify input requirements, such as "Enter up to 100 characters."
```ts
controller: RichEditorController = new RichEditorController();
Use [maxLength](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#maxlength18) to set the maximum number of characters allowed in the rich text component.
You can set the maximum number of characters allowed in the **RichEditor** component using [maxLength](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#maxlength18).
```ts
controller: RichEditorController = new RichEditorController();
@@ -354,17 +356,17 @@ RichEditor(this.options)
## Event Callbacks
## Adding Event Callbacks
Register event callbacks to monitor component events.
You can register callbacks to listen for component events.
### Callbacks for Before and After Content Changes
### Adding Callbacks for Before and After Text and Image Changes
Use the [onWillChange](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onwillchange12) API to add a callback invoked before text or image changes. This callback is suitable for real-time data validation and notifications. For example, it can enable features like sensitive word detection with immediate alert dialogs, or real-time character counting and limiting.
Use the [onWillChange](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onwillchange12) API to add a callback invoked before text or image changes. This callback is applicable to real-time data verification and notification. For example, it can be used to enable features such as detecting sensitive words and displaying an alert dialog box immediately, as well as real-time character count statistics and limitation.
Use the [onDidChange](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#ondidchange12) API to add a callback invoked after text or image changes. This callback is suitable for content saving and synchronization. For example, it can automatically save the latest content locally or sync it to a server, and update content status and rendering.
Use the [onDidChange](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#ondidchange12) API to add a callback invoked after text or image changes. This callback applies to content saving and synchronization. For example, it can be used to automatically save the latest content to the local host or synchronizing it to the server. The callback can also be used to update and re‑render content status. For example, in a to‑do list application, after a user edits a task description in rich‑text format, the callback can update the display style of that task in the list.
Note: The **RichEditor** component constructed with [RichEditorStyledStringOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorstyledstringoptions12) does not support these callbacks.
Note: The **RichEditor** component constructed with [RichEditorStyledStringOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorstyledstringoptions12) does not support these two types of callbacks.
```ts
controller: RichEditorController = new RichEditorController();
@@ -383,7 +385,7 @@ RichEditor(this.options)
})
})
.onWillChange((value: RichEditorChangeValue) => {
this.infoShowController.addTextSpan('Triggered before content change: \n' + JSON.stringify(value), {
this.infoShowController.addTextSpan('Callback invoked before text or image changes: \n' + JSON.stringify(value), {
### Adding Callbacks Triggered Before and After Content Input in the Input Method
Callbacks can be triggered before and after input method content is added.
For intelligent input assistance, use [aboutToIMEInput](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#abouttoimeinput) to trigger a callback before adding input content, and [onDidIMEInput](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#ondidimeinput12) to trigger a callback after input method content is added.
To facilitate intelligent input assistance, use [aboutToIMEInput](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#abouttoimeinput) to trigger a callback before adding input content, and [onDidIMEInput](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#ondidimeinput12) to trigger a callback after the input is complete.
These callbacks are suitable for business logic processing during text display. For example, before user-entered text appears on screen, the callback can provide word suggestions. After input completion, automatic error correction or format conversion can be performed. The callback sequence is aboutToIMEInput followed by onDidIMEInput.
These two callbacks are useful for handling service logic during text display, for example, providing word suggestions or predictive text before display and performing auto‑correction or format conversion after input completes. The callbacks are triggered in this order: **aboutToIMEInput** -> **onDidIMEInput**.
Components constructed using [RichEditorStyledStringOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorstyledstringoptions12) do not support these callbacks.
Components constructed with [RichEditorStyledStringOptions](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#richeditorstyledstringoptions12) do not support these two callbacks.
```ts
controller: RichEditorController = new RichEditorController();
### Adding a Callback Triggered Before Paste Completion
The [onPaste](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onpaste11) callback is used to add processing logic before pasting.
The [onPaste](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onpaste11) callback is used to add custom processing before pasting completes.
This is useful for content format processing, such as converting HTML-tagged text to a format supported by the **RichEditor** component, removing unnecessary tags, or retaining only plain text.
This is useful for content format handling, such as converting HTML-tagged text to a format supported by the **RichEditor** component and removing unnecessary tags or retaining only plain text content.
You can use this API to override the default paste behavior (limited to plain text) to support pasting both images and text.
You can use this API to override the default paste behavior, which is limited to plain text, so that both images and text can be pasted.
```ts
import { BusinessError, pasteboard } from '@kit.BasicServicesKit';
@@ -521,11 +523,11 @@ struct on_cut_copy_paste {
Column({ space: 3 }) {
RichEditor(this.options)
.onReady(() => {
this.controller.addTextSpan('Copy and paste text to trigger corresponding callbacks.',
this.controller.addTextSpan('Copy and paste operations on this text trigger the corresponding callbacks.',
### Adding a Callback Triggered Before Cut Completion
Add a callback to process data before the [onCut](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#oncut12) operation completes.
The [onCut](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#oncut12) callback is used to add custom processing before a cut operation completes.
This callback is suitable for data processing and storage. For example, when a user cuts content from the rich text component, the callback can temporarily store the cut content to ensure accurate restoration during subsequent pasting.
This callback is useful for data processing and storage. For example, when a user cuts content from the **RichEditor** component, the callback can temporarily store the cut content to ensure it can be accurately restored during a subsequent paste.
You can use this API to override the default cut behavior (limited to plain text) to support cutting both images and text.
You can use this API to override the default cut behavior, which is limited to plain text, so that both images and text can be cut.
```ts
controller: RichEditorController = new RichEditorController();
### Adding a Callback Triggered Before Copy Completion
Use the [onCopy](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#oncopy12) callback to add processing logic before copying.
Use the [onCopy](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#oncopy12) callback to add processing logic before copying.
This callback is suitable for content backup and sharing. For example, the callback can save the copied content and its format information to a local backup folder, or automatically generate copy including the copied content and a product purchase link for users to paste and share.
This callback applies to content backup and sharing. For example, the following operations can be performed in the callback: saving the copied content and its format information to a local backup folder, or automatically generating copywriting that includes the copied content and a product purchase link for users to paste and share.
The component's default copy behavior is limited to plain text and cannot process images. Use this method to implement copying both images and text, replacing the component's default behavior.
The component's default copy behavior is limited to plain text and cannot handle images. You can use this callback to implement a custom copy feature that supports both images and text, replacing the component's default behavior.
```ts
controller: RichEditorController = new RichEditorController();
For all available events, see [RichEditor Events](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#events).
For details about all available events, see [RichEditor Events](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#events).
## Component Interaction
## Implementing Component Interaction
Configure interactive element attributes through APIs to detect changes.
You can configure interaction element properties through APIs to respond to changes in those elements.
### Setting Cursor and Handle Color
### Setting the Caret and Selection Handle Colors
Use [caretColor](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#caretcolor12) to set the cursor and handle color.
You can set the caret and selection handle colors in the text box using the [caretColor](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#caretcolor12) API.
Setting distinct cursor and handle colors enhances visual recognition, especially in interfaces with multiple input areas. Unique cursor colors help quickly locate the active input area. This feature also improves user experience by coordinating the cursor color with the application's overall style.
This feature allows for a more distinct visual representation of the caret and text selection, which can significantly aid users in navigating through complex UI that incorporate various input fields. It also improves the user experience by allowing the caret color to match the overall style of the application page.
```ts
controller: RichEditorController = new RichEditorController();
### Adding a Callback for Caret Position and Selection Changes
[onSelectionChange](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onselectionchange12) adds a callback triggered when the cursor position changes in the content selection area or during editing.
The [onSelectionChange](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#onselectionchange12) callback is triggered whenever the caret position or text selection range changes in the component's content area during editing.
This callback monitors selection area changes in real time. For example, you can use it to update toolbar status (displaying font and paragraph formats), count selected content length, or generate summaries. Real-time response to selection status and dynamic association of interactive elements improve the rich text editing experience and functionality.
This callback enables real‑time listening of selection changes. Typical use cases include: updating toolbar state dynamically (for example, reflecting the font and paragraph formatting of the currently selected text), measuring length of the selected content, and generating a summary of the selected content. By responding immediately to selection changes and dynamically linking interactive elements, this callback enhances the feedback experience and functional flexibility of rich text editing.
```ts
controller: RichEditorController = new RichEditorController();
Use the [setSelection](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#setselection11) API to highlight the selected portion of the content.
Use the [setSelection](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#setselection11) API to configure the component to highlight the background of the selected portion.
This API implements text focus effects. For example, when a user taps a text paragraph title or summary, this API can automatically select and highlight the corresponding text content.
This API is useful for implementing text focus effects. For example, when a user taps a paragraph title or summary, you can call this API to automatically select and highlight the corresponding text segment.
If this API is called when the text box is not focused, the selection effect is not displayed.
You can configure the text selection menu through APIs.
### Managing Selected Menu Items
The [onPrepareMenu](../reference/apis-arkui/arkui-ts/ts-text-common.md#properties-1) callback is triggered before the menu is displayed after the rich text selection area changes. You can set menu data in this callback.
The [onPrepareMenu](../reference/apis-arkui/arkui-ts/ts-text-common.md#properties-1) callback is triggered before the menu is displayed when the rich text selection range changes. You can configure menu data within this callback.
```ts
// xxx.ets
@@ -832,9 +834,9 @@ struct RichEditorExample {
### Disabling System Service Menu Items
Use [disableSystemServiceMenuItems](../reference/apis-arkui/arkts-apis-uicontext-textmenucontroller.md#disablesystemservicemenuitems20) to disable all system service menu items in the rich text selection menu.
Use [disableSystemServiceMenuItems](../reference/apis-arkui/arkts-apis-uicontext-textmenucontroller.md#disablesystemservicemenuitems20) to hide all system-provided service menu items from the text selection menu.
This API protects content security and is suitable for scenarios with restricted text operations, such as displaying confidential content or copyrighted text that cannot be copied. Disabling system service menu items prevents users from copying and sharing text through these menus, reducing content leakage risks.
This API protects content security and is suitable for scenarios with restricted text operations, for example, when displaying confidential content or copyrighted text that should not be copied. By disabling system menu items, you prevent users from copying or sharing text through the system menu, reducing the risk of content leakage.
```ts
@@ -848,12 +850,12 @@ This API protects content security and is suitable for scenarios with restricted
@@ -888,9 +890,9 @@ This API protects content security and is suitable for scenarios with restricted
Use [disableMenuItems](../reference/apis-arkui/arkts-apis-uicontext-textmenucontroller.md#disablemenuitems20) to disable specific system service menu items in the rich text selection menu.
Use [disableMenuItems](../reference/apis-arkui/arkts-apis-uicontext-textmenucontroller.md#disablemenuitems20) to hide specified system-provided service menu items from the text selection menu.
This interface precisely disables specified system service menu items while retaining required system menu functions, making the menus more suitable for actual interaction design.
This API allows you to precisely disable only the system menu items you specify, while preserving other system menu functions needed by your application. This makes the menu better suited to your actual interaction design.
```ts
import { TextMenuController } from '@kit.ArkUI';
@@ -903,12 +905,12 @@ This interface precisely disables specified system service menu items while reta
@@ -943,11 +945,11 @@ This interface precisely disables specified system service menu items while reta
### Setting Custom Context Menu on Text Selection
### Setting the Custom Context Menu on Text Selection
Use the [bindSelectionMenu](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#bindselectionmenu) API to set a custom context menu on text selection.
You can set custom context menu on text selection using the [bindSelectionMenu](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#bindselectionmenu) API.
By default, the context menu includes copy, cut, and select all options. You can add more options for enhanced interactions, such as translate for multilingual support or bold for emphasizing selected text.
By default, the context menu on text selection includes copy, cut, and select-all options. You can add custom items to provide enhanced interactions, for example, a Translate option for multilingual support, or a Bold option to emphasize the selected text.
If the custom menu is too long, consider embedding a **Scroll** component to prevent the keyboard from being blocked.
Configure component layout rules through APIs. Customize layout rules based on business scenarios.
You can configure layout rules for the component through APIs, customizing its behavior based on your application's requirements.
### Setting Maximum Line Count
### Setting the Maximum Number of Lines
Use [maxLines](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#maxlines18) to set the maximum number of lines displayed in the rich text component.
Use [maxLines](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#maxlines18) to set the maximum number of lines that can be displayed in the **RichEditor** component.
This API controls the text display range to prevent excessively long text from affecting page layout. It ensures consistent text display across different devices and scenarios, improving interface compatibility and aesthetics.
This API controls the text display area to prevent overly long content from disrupting the page layout. It ensures a consistent text presentation across different devices and scenarios, improving UI compatibility and visual appeal.
```ts
controller: RichEditorController = new RichEditorController();
this.controller.addTextSpan('Maximum line count is set.\nContent exceeding the limit will scroll.\nExceeds 1 line.\nExceeds 2 lines.\nExceeds 3 lines.\nExceeds 4 lines.', {
this.controller.addTextSpan('The maximum number of lines is set.\nExcess content will be displayed in scrolling mode.\nExceeds 1 line\nExceeds 2 lines\nExceeds 3 lines\nExceeds 4 lines', {
style: {
fontColor: Color.Black,
fontSize: 15
@@ -1036,15 +1038,15 @@ RichEditor(this.options)
## Style Settings
## Setting the Style
Set complex styles for content.
You can apply complex styles to content in the component.
### Setting Preset Text Style
### Setting the Active Typing Style
Use [setTypingStyle](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#settypingstyle11) to set the preset text style.
Use the [setTypingStyle](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#settypingstyle11) API to define the style that will be automatically applied to newly typed text.
This enables personalized writing experiences. For example, you can use this API to automatically apply corresponding formats to different heading levels (like level-1 and level-2 headings) as users type.
This allows you to deliver a personalized writing experience. For example, you might want to use this API to automatically apply corresponding formats to different levels of headings (such as level-1 and level-2 headings) as users type.
```ts
controller: RichEditorController = new RichEditorController();
[decoration](../reference/apis-arkui/arkui-ts/ts-basic-components-span.md#decoration) sets the style, color, and thickness of text decoration lines.
Use [decoration](../reference/apis-arkui/arkui-ts/ts-basic-components-span.md#decoration) to set the style, color, and thickness of text decoration lines.
Text decoration highlights key information, distinguishes text status, and enhances visual hierarchy. For example, add decoration to important titles or keywords to help users quickly identify information.
Applying text decoration can highlight key information, indicate text status, and improve visual hierarchy. For example, you can add a decoration line to important titles or keywords to help users quickly locate essential content.
```ts
private controller: RichEditorController = new RichEditorController();
RichEditor({ controller: this.controller })
.onReady(() => {
this.controller.addTextSpan('Preset text', {
this.controller.addTextSpan('Example text', {
style: {
fontSize: 25,
decoration: {
type: TextDecorationType.LineThrough,
color: Color.Blue,
// Set decoration line thickness ratio to 6.
// Set the thickness of the decoration line to 6 times the default.
thicknessScale: 6
}
}
@@ -1108,16 +1110,16 @@ Text decoration highlights key information, distinguishes text status, and enhan
Use enableMultiType in [DecorationOptions](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#decorationoptions20) to set multiple decoration lines, such as underlines and strikethroughs.
Use the **enableMultiType** property in [DecorationOptions](../reference/apis-arkui/arkui-ts/ts-universal-styled-string.md#decorationoptions20) to apply multiple decoration lines simultaneously, such as an underline and a strikethrough.
This API suits complex business scenarios and meets diverse text decoration needs. During document collaboration, different decoration combinations can distinguish text status, improving collaboration efficiency.
This API is useful in complex scenarios that require diverse text decoration. For example, in collaborative document editing, different combinations of decoration lines can be used to distinguish text states contributed by various users, improving collaboration efficiency.
let mutString: MutableStyledString = new MutableStyledString('Set rich text multi-decoration', [
let mutString: MutableStyledString = new MutableStyledString('Rich text with multiple decorations', [
{
start: 0,
length: 9,
@@ -1161,9 +1163,9 @@ This API suits complex business scenarios and meets diverse text decoration need
### Setting Vertical Alignment
Use [textVerticalAlign](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#textverticalalign20) to set the vertical alignment of text paragraphs.
Use [textVerticalAlign](../reference/apis-arkui/arkui-ts/ts-basic-components-text.md#textverticalalign20) to set the vertical alignment of text within a paragraph.
This API optimizes multi-element layout, making the overall layout more coordinated when component content is vertically aligned with images and icons.
This API optimizes layouts containing multiple elements. When component content needs to be aligned vertically with images or icons, it ensures a more harmonious overall layout.
```ts
controller: RichEditorController = new RichEditorController();
@@ -1177,7 +1179,7 @@ This API optimizes multi-element layout, making the overall layout more coordina
size: [100, 100]
}
})
this.controller.addTextSpan("This rich text demonstrates vertical text alignment.", {
this.controller.addTextSpan("This text demonstrates vertical centering.", {
style: {
fontColor: Color.Pink,
fontSize: "32"
@@ -1194,11 +1196,11 @@ This API optimizes multi-element layout, making the overall layout more coordina
### Setting Automatic Spacing Between Chinese and Western Characters
### Enabling Automatic Spacing Between Chinese and Western Characters
Use [enableAutoSpacing](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#enableautospacing20) to enable automatic spacing between Chinese and Western characters.
Use [enableAutoSpacing](../reference/apis-arkui/arkui-ts/ts-basic-components-richeditor.md#enableautospacing20) to control whether automatic spacing is inserted between Chinese and Western characters.
This interface optimizes text layout and improves readability. When enabled, appropriate gaps are inserted between Chinese and Western characters, facilitating language differentiation and reducing visual interference.
This API optimizes text layout and improves readability within the component. When automatic spacing is enabled, an appropriate gap is automatically added between Chinese and Western characters, making it easier to distinguish between languages and reducing visual interference.
- **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 input methods.
- **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.
- **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 focused.
- **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).
**Focus Activation State**
The focus activation state is used to display the visual style of the focus box of the component that obtains focus.
- **Presentation rules**:
- **Default state**: The focus activation state is hidden by default.
- **Activation condition**: The focus activation state is displayed only when the application enters the activated state.
- **Key relationships**:
- The component that obtains focus may not display the activation state (depending on whether the application is in the activated state).
- The component that displays the activation state must be the component that obtains focus.
- **Style customization**: Components usually have built-in activation state styles. Developers can customize the styles through style APIs. Customized styles override default styles.
- **Display priority**: When multiple components have focus simultaneously, the system preferentially displays the activation state of the child component, and displays only one activation state at a time.
- **How to enter the activated state**:
- Press the Tab key on an external keyboard. (Note: The Tab key is used only for activation when the application is activated for the first time and does not trigger focus movement.)
- Call the activate(true) method of [FocusController](../reference/apis-arkui/arkts-apis-uicontext-focuscontroller.md).
- **How to exit the activated state**:
- Call the activate(false) method of FocusController.
- A click event occurs (including a touchscreen click or left mouse button click).
The focus activation state determines the visual style (focus indicator) of the component that currently holds focus.
- **Presentation rules**
- Default state: The focus activation state is hidden by default.
- Activation condition: The activation style is displayed only when the application is in the activated state.
- Key relationships:
- A component that obtains focus may not show its activation style (if the application is not in the activated state).
- A component that displays the activation style must be the component that currently holds focus.
- Style customization: Components usually have built-in activation styles. You can override these default styles using style-related APIs.
- Display priority: When multiple components are focused simultaneously, the system preferentially shows the activation style of the deepest child component, and only one activation style is visible at a time.
- **Methods to enter the activated state**
- Press the **Tab** key on an external keyboard. (Note: The **Tab** key is used only for the initial activation of the application and does not move focus at that moment.)
- Call the **activate(true)** method of [FocusController](../reference/apis-arkui/arkts-apis-uicontext-focuscontroller.md).
- **Methods to exit the activated state**
- Call the **activate(false)** method of **FocusController**.
- A click event occurs (including a touchscreen tap or a left-mouse-button click).
```ts
@Entry
@@ -59,48 +56,48 @@ struct FocusActiveExample {
```
Focus is activated when you press Tab. Clicking the mouse button exits the focus activation state.
Focus activation is triggered when the **Tab** key is pressed. Clicking the mouse button exits the focus activation state.

You can call the [activate](../reference/apis-arkui/arkts-apis-uicontext-focuscontroller.md#activate14) API to enter and exit the focus activation state.
You can call the [activate](../reference/apis-arkui/arkts-apis-uicontext-focuscontroller.md#activate14) API to programmatically enter and exit the focus activation state.

Example steps:
1. Click **Set Active** to call the [activate](../reference/apis-arkui/arkts-apis-uicontext-focuscontroller.md#activate14) API to enter the focus activation state.
2. Press Tab to move focus to the **Set Not Active** button, press Enter to trigger a key event, and call the [activate](../reference/apis-arkui/arkts-apis-uicontext-focuscontroller.md#activate14) API to exit the focus activation state.
Example flow:
1. Click the **Set Active** button, which calls [activate](../reference/apis-arkui/arkts-apis-uicontext-focuscontroller.md#activate14) to enter the focus activation state.
2. Press **Tab** to move focus to the **Set Not Active** button, and then press **Enter** to trigger its click event. This calls [activate](../reference/apis-arkui/arkts-apis-uicontext-focuscontroller.md#activate14) to exit the focus activation state.
**Hierarchical Pages**
Hierarchical 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:
- **Visual layering**: They appear on top of other content, creating a distinct visual hierarchy.
- **Focus capture**: They automatically take focus when first displayed.
- **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.
- Visual layering: They appear on top of other content, creating a distinct visual hierarchy.
- Focus capture: They automatically take focus when first displayed.
- 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.
An application always has at least one hierarchical page in focus. When this hierarchical page is closed or no longer visible, focus shifts to another, ensuring smooth user interaction.
An 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.
> **NOTE**
>
> The **Popup** component does not capture focus if it has **focusable** set to **false**.
>
> The **NavBar** and **NavDestination** components do not restrict focus movement and share the focus scope of their immediate parent hierarchical page.
> The **NavBar** and **NavDestination** components share the focus scope of their immediate parent hierarchical page and do not restrict focus movement.
**Root Container**
The root container is a concept in [hierarchical pages](#basic-concepts). When a [hierarchical page](#basic-concepts) is created and displayed for the first time, focus is immediately captured by the page based on the [hierarchical page](#basic-concepts) characteristics. In this case, the end node of the focus chain where the [hierarchical page](#basic-concepts) is located becomes the default focus, and the default focus is usually located on the root container of the [hierarchical page](#basic-concepts).
The root container is a concept in [hierarchical pages](#basic-concepts). When a [hierarchical page](#basic-concepts) is created and displayed for the first time, it immediately captures focus due to the inherent characteristics of hierarchical pages. In this case, the end node of the focus chain where the hierarchical page resides becomes the default focus, which is typically the page's root container.
You can change the default focus using the **defaultFocus** attribute.
When focus is on the root container, pressing the Tab key for the first time not only activates focus but also transfers focus according to the [focus transfer rules](#focus-transfer-rules).
When focus resides on the root container, pressing the **Tab** key for the first time not only activates the focus but also transfers focus according to the [focus transfer rules](#focus-transfer-rules).
### Focus Transfer Rules
Focus transfer refers to the process of transferring focus from the root node to a specific component level by level when a user activates the application focus system for the first time.
Focus transfer refers to the process where focus is transferred level by level from the root node to a specific component when a user activates the application's focus system for the first time.
Components on the focus chain are in the focus state. When a component is focused, the focus state is recursively passed downwards to the first child component until the leaf node.
Components in the focus chain are in a focusable state. When a component gains focus, the focus state is recursively propagated down to its first child component until a leaf node is reached.
```ts
@Entry
@@ -163,7 +160,7 @@ struct Index {
}
```
After the app runs, click **Button1** to request focus for the Row component. The first focusable child node **Button2** of the Row component is focused.
After the application runs, click **Button 1** to request focus for the **Row** component. The Row component's first focusable child node, **Button 2**, will gain focus.

@@ -177,25 +174,25 @@ Focus traversal can be divided into active and passive based on how it is trigge
Active 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**.
- **Keyboard traversal**:
1. **Prerequisite**: The application is in the focus activation state.
2. **Scope**: Limited to the currently focused hierarchical page, as detailed in the "Focus limitation" section under "Hierarchical Pages."
3. **Key types**:
- **Tab** key: Follows a Z-shaped logic to traverse all leaf nodes within the scope, looping back to the first after the last.
- **Shift+Tab**: Reverses the direction of the **Tab** key.
- **Arrow 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.
4. **Traversal algorithm**: Each focusable container has a unique algorithm defining how focus moves.
5. **Priority**: Child components take precedence in handling keyboard events over parents.
- **Keyboard traversal**
1. Prerequisite: The application is in the focus activation state.
2. Scope: limited to the currently focused hierarchical page, as detailed in the "Focus limitation" section under "Hierarchical Pages."
3. Key types:
- **Tab** key: follows a Z-shaped logic to traverse all leaf nodes within the scope, looping back to the first after the last.
- **Shift+Tab**: reverses the direction of the **Tab** key.
- Arrow 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.
4. Traversal algorithm: Each focusable container has a unique algorithm defining how focus moves.
5. Priority: Child components take precedence in handling keyboard events over parents.
- **requestFocus**:
Moves focus to a specific component, which is allowed across hierarchical pages but not across windows or different ArkUI instances.
For details, see [Active Focus Acquisition/Loss](#active-focus-acquisitionloss).
- **requestFocus**
Moves focus to a specific component, which is allowed across hierarchical pages but not across windows or different ArkUI instances.
For details, see [Active Focus Acquisition/Loss](#active-focus-acquisitionloss).
- **clearFocus**:
Clears focus within the current hierarchical page, with focus reverting to the root container. For details, see [clearFocus](../reference/apis-arkui/arkts-apis-uicontext-focuscontroller.md#clearfocus12).
- **clearFocus**
Clears the focus within the current hierarchical page, with focus reverting to the root container. For details, see [clearFocus](../reference/apis-arkui/arkts-apis-uicontext-focuscontroller.md#clearfocus12).
- **focusOnTouch**:
Enables 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).
- **focusOnTouch**
Enables a component to gain focus on touch. For details, see [focusOnTouch](../reference/apis-arkui/arkui-ts/ts-universal-attributes-focus.md#focusontouch9). This API is ineffective on non-focusable components. For container components, focus goes to the last focused child or the first focusable child upon touch.
**Passive Focus Traversal**
@@ -205,10 +202,10 @@ Passive focus traversal occurs when focus automatically shifts due to system act
Mechanisms that trigger passive focus traversal include:
- **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.
- **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.
- [**Hierarchical page**](#basic-concepts) **switching**: During [hierarchical page](#basic-concepts) switching, for example, from one [hierarchical page](#basic-concepts) to another, focus of the current [hierarchical page](#basic-concepts) is automatically released, and the new [hierarchical page](#basic-concepts) may automatically gain focus based on preset logic.
- **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.
- 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.
- 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.
- [Hierarchical page](#basic-concepts) switching: During switching between hierarchical pages (for example, from one hierarchical page to another), the focus of the current hierarchical page is automatically released, and the new hierarchical page may automatically gain focus based on preset logic.
- **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.
### Focus Traversal Algorithms
@@ -222,10 +219,10 @@ The algorithm used by a container is based on its UX design and is implemented b
The 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:
- **Order dependency**: Focus order is based solely on the mounting sequence of child nodes in the node tree, independent of their visual layout.
- **Tab key focus traversal**: The **Tab** key moves focus through focusable elements in the order they are mounted in the component tree.
- **Arrow key focus 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.
- **Boundary handling**: The container rejects focus requests in the opposite direction from the current focus edge. For example, if focus is on the first child of a horizontal **Row** container, it won't process leftward focus requests.
- Order dependency: The focus order is based solely on the mounting sequence of child nodes in the node tree, independent of their visual layout.
- **Tab** key focus traversal: The **Tab** key moves focus through focusable elements in the order they are mounted in the component tree.
- Arrow key focus 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.
- Boundary handling: The container rejects focus requests in the opposite direction from the current focus edge. For example, if focus is on the first child of a horizontal **Row** container, it won't process leftward focus requests.
```ts
@Entry
@@ -279,12 +276,12 @@ In a horizontal **Row** container, use the left and right arrow keys to navigate
**Projection-based Focus Traversal Algorithm**
The projection-based 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. This algorithm applies to containers with child components of different sizes. Currently, only the Flex component with the wrap attribute configured is supported. Its operation rules are as follows:
The projection-based 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. This algorithm is designed for containers whose children vary in size. Currently, it is supported only by the **Flex** component when its **wrap** attribute is set. Its operation rules are as follows:
- When arrow keys are used to move focus, the overlapping area between the projection and the child component area is determined. Among all child components whose area is not 0, the straight-line distance between the child components and the center point of the current focused component is calculated, and the child component with the shortest distance is selected. If there are multiple candidate child components, the child component that is closer to the node tree is selected. If no child component overlaps with the projection, the container cannot process the focus movement request of the arrow key.
- When the Tab key is used to move focus, specification 1 is used first. If the focus movement request is found, the process exits. If the focus movement request is not found, the position of the currently focused child component is simulated to move downwards by the height of the focused child component, and then the projection is determined according to the left arrow key. The child component with the overlapping projection and the shortest straight-line distance between the center points wins. If no child component overlaps with the projection, the container cannot process the focus movement request of the Tab key.
- **Shift+Tab** key: It mimics a leftward shift to find the next focus; If the focus movement request is not found, the position of the currently focused child component is simulated to move upwards by the height of the focused child component, and then the projection is determined according to the right arrow key. The child component with the overlapping projection and the shortest straight-line distance between the center points wins. If no child component overlaps with the projection, the container cannot process the focus movement request of the Shift+Tab key.
- **Arrow key navigation**: When an arrow key is pressed, the algorithm first checks for any overlap between the projection and the areas of child components. Among all child components whose overlapping area is greater than zero, the straight‑line distance from each child's center to the center of the currently focused component is calculated. The child with the shortest distance is selected. If multiple candidates have the same minimal distance, the child that appears earlier in the node tree is chosen. If no child overlaps with the projection, the container cannot process the arrow key focus movement request.
- **Tab key navigation**: For **Tab** key presses, the algorithm first applies the preceding arrow key navigation rule. If a valid focus target is found, the process ends. If not, the algorithm simulates shifting the position of the currently focused child component downward by its own height, then calculates the projection as if the left arrow key were pressed. The child component that overlaps with this projection and has the shortest center-to-center distance is selected. If no child overlaps, the container cannot process the **Tab** key focus movement request.
- **Shift+Tab key navigation**: For **Shift+Tab** key presses, the algorithm mimics a leftward shift to locate the next focus. If no target is found, it simulates moving the currently focused child component upward by its own height, then calculates the projection as if the right arrow key were pressed. The child component that overlaps with this projection and has the shortest center-to-center distance is selected. If no child overlaps, the container cannot process the **Shift+Tab **key focus movement request.
When components in a **Flex** multi-line layout have varying sizes and overlap vertically, the **Tab** key focus traversal fails to reach the buttons labeled **3**, **4**, and **5** in the lower row.
When components in a **Flex** multi-line layout have varying sizes and overlap vertically, the **Tab** key focus traversal fails to reach the buttons labeled **4** and **5** in the lower row.
@@ -509,12 +506,20 @@ Sets whether the component is focusable.
Components can be classified into the following types based on their focus capability:
- **Default focusable components**: These components are usually interactive components, such as **Button**, **Checkbox**, and **TextInput**.
- **Inherently focusable components**: These components are usually interactive components, such as **Button**, **Checkbox**, and **TextInput**. They can receive focus without any explicit configuration.
- **Conditionally focusable components**: Typical examples are **Text** and **Image**, which are not focusable by default. To make them focusable, you must explicitly set **focusable(true)**. Container components that contain no focusable children are also non-focusable by default. However, if you bind an **onClick** event or a single-tap gesture to such a container, it implicitly gains focusability. Note that if the container's **focusable** attribute is explicitly set to **false**, it remains non-focusable even if an event or gesture is attached.
- **Non-focusable components**: Components that do not allow for interactions, such as **Blank** and **Circle**, cannot be made focusable, regardless of whether the **focusable** attribute is applied.
Setting a container component as focusable:
- **Components with focus capability but not focusable by default**: Typical examples are **Text** and **Image**. To enable them to be focusable, set **focusable(true)**. Components that can be focused but cannot be focused by default if the focusable attribute is not configured, such as container components without focusable child components. If you configure the onClick or single-finger tap gesture for these components, the components become focusable components implicitly. However, when these components have the **focusable** attribute set to **false**, they are still not focusable even if you bind the aforementioned event or gesture to them.
The primary purpose of gaining focus is to enable interaction. If a component inherently lacks interactive capabilities, it cannot be made focusable. Container components (such as **Stack** and **Column**) are typically not interactive by themselves. Therefore, even if a container component is a leaf node in the view tree, it cannot be made focusable simply by calling **.focusable(true)**. Note that this same rule applies to [FrameNode](../reference/apis-arkui/js-apis-arkui-frameNode.md) objects created dynamically.
To make a leaf node container focusable, you can use one of these approaches:
- **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.
- Place a component that natively supports focus, such as a **Button** component, inside the container.
- Bind a gesture (such as **onClick** or a tap gesture) to the container.
```ts
enabled(value: boolean)
@@ -526,7 +531,7 @@ Sets the component's interactivity. If [enabled](../reference/apis-arkui/arkui-t
visibility(value: Visibility)
```
Sets the component's visibility. If [visibility](../reference/apis-arkui/arkui-ts/ts-universal-attributes-visibility.md#visibility) is set to **Visibility.None** or **Visibility.Hidden**, the component becomes invisible and cannot gain focus.
Sets 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.
```ts
focusOnTouch(value: boolean)
@@ -536,7 +541,7 @@ Sets whether the component is focusable on touch.
> **NOTE**
>
>When a component that is currently focused has its **focusable** or **enabled** attribute set to **false**, it automatically loses focus. Focus then shifts to another component according to the [Focus Traversal Guidelines](#focus-traversal-guidelines).
>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).
```ts
// xxx.ets
@@ -631,8 +636,8 @@ Operation result:
The preceding example includes three steps:
- As the first **Text** component does not have **focusable(true)** set, it is not focusable.
- The second **Text** component is set with **focusOnTouch(true)**, allowing it to gain focus on touch. Pressing the **Tab** key triggers focus traversal, but focus remains on the second component. When the **F** key is pressed, the **onKeyEvent** callback toggles **focusable** to **false**, making the second **Text** component not focusable, and focus shifts to the next available focusable component, which is the third **Text** component.
- Pressing the **G** key triggers the **onKeyEvent** callback, which sets **enabled** to **false**, making the third **Text** component not focusable. Focus then automatically moves to the **Row** container, where the default configuration causes focus to shift to **Button1**.
- 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 not focusable, and the focus shifts to the next available focusable component, which is the third **Text** component.
- Pressing the **G** key triggers the **onKeyEvent** callback, which sets **enabled** to **false**, making the third **Text** component not focusable. The focus then automatically moves to the **Row** container, where the default configuration causes the focus to shift to **Button1**.
## Setting the Focus Box for a Container
@@ -743,7 +748,7 @@ Set whether the current component is the default focus on the current [hierarchi
// xxx.ets
@Entry
@Component
struct morenjiaodian {
struct DefaultFocus {
@State oneButtonColor: Color = Color.Gray;
@State twoButtonColor: Color = Color.Gray;
@State threeButtonColor: Color = Color.Gray;
@@ -803,8 +808,8 @@ struct morenjiaodian {
The preceding example includes two steps:
- defaultFocus(true) is set on the third button. After the [Hierarchical Page](#basic-concepts) is displayed, the third button is focused by default and displayed in green.
- Pressing the **Tab** key triggers focus traversal, and since the third **Button** component is in focus, a focus frame appears around it.
- **defaultFocus(true)** is set on the third button. When the hierarchical page is displayed, the third button automatically receives focus and turns green.
- Pressing the **Tab** key triggers focus traversal, and since the third **Button** component is in focus, a focus indicator appears around it.
### Default Focus for Containers
@@ -835,32 +840,32 @@ struct Index {
**Overall Focus and Non-Overall Focus**
- **Overall focus**: The entire [hierarchical page](#basic-concepts) or container gains focus first, and then focus shifts to its child components. Examples include [hierarchical page](#basic-concepts) transitions, route switches within **Navigation** components, focus group traversal, and when a container component proactively calls **requestFocusById**.
- Overall focus: The entire [hierarchical page](#basic-concepts) or container gains focus first, and then focus shifts to its child components. Examples include [hierarchical page](#basic-concepts) transitions, route switches within **Navigation** components, focus group traversal, and when a container component proactively calls **requestFocusById**.
- **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.
- 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.
**Formation of the Focus Chain in Overall Focus**
1. When the [hierarchical page](#basic-concepts) is focused for the first time:
1. When a hierarchical page first receives focus:
- The leaf node of the focus chain is the node with **defaultFocus** set.
- The leaf node of the focus chain is the node with **defaultFocus** set.
- If defaultFocus is not configured, focus stays on the root container of the [hierarchical page](#basic-concepts).
- If **defaultFocus** is not configured on any node, focus remains on the root container of the hierarchical page.
2. When the [hierarchical page](#basic-concepts) is not focused for the first time, the node that was focused last time is focused.
2. When a hierarchical page is not focused for the first time, the node that was focused the last time the page was active regains focus.
3. Focus chain with priority configuration:
- If a container has a component with a focus priority higher than **PREVIOUS**, the component with the highest priority gains focus.
- If a container has a component with a focus priority higher than **PREVIOUS**, the component with the highest priority gains focus.
- 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.
- 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.
## Focus Style
> **NOTE**
>
> When a component is in the focus activated state, its [zIndex](../reference/apis-arkui/arkui-ts/ts-universal-attributes-z-order.md#zindex) value is automatically elevated to **INT_MAX** to ensure that it is rendered above other components. If the component already has a specified **zIndex** value, this value will not be adjusted. When the component exits the focus activated state (for example, loses focus or leaves the focus chain), its **zIndex** value will revert to its original settings.
> When a component is in the focus activation state, its [zIndex](../reference/apis-arkui/arkui-ts/ts-universal-attributes-z-order.md#zindex) value is automatically elevated to **INT_MAX** to ensure that it is rendered above other components. If the component already has a specified **zIndex** value, this value will not be adjusted. When the component exits the focus activation state (for example, loses focus or leaves the focus chain), its **zIndex** value will revert to its original settings.
- After the [hierarchical page](#basic-concepts) 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.
- After the [hierarchical page](#basic-concepts) 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.
- 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.
## Active Focus Acquisition/Loss
- **Using FocusController APIs**
- Using **FocusController** APIs
You are advised to use **requestFocus** from **FocusController** for actively acquiring focus. It provides the following benefits:
- Takes effect in the current frame, preventing interference from subsequent component tree changes.
@@ -924,7 +929,7 @@ The preceding example includes two steps:
```
Clears focus and forcibly moves focus to the root container node of the current [hierarchical page](#basic-concepts). Other nodes on the focus chain all lose focus.
- **Using focusControl APIs**
- Using **focusControl** APIs
```ts
requestFocus(value: string): boolean
```
@@ -1021,7 +1026,7 @@ The preceding example includes three steps:
nextFocus(nextStep: Optional<FocusMovement>): T
```
If a component is configured with nextFocus, focus is moved only according to the nextFocus sequence. If no component or container is configured with nextFocus, the default focus sequence is used.
When a component is configured with **nextFocus**, focus movement strictly follows the sequence defined by **nextFocus**. If no component or container has **nextFocus** configured, the default focus sequence applies.
> **NOTE**
>
@@ -1060,11 +1065,11 @@ struct NextFocusExample {
}
}
```
Focus sequence using the Tab key: If nextFocus is not configured, the focus sequence using the Tab key is A->B -> C->D -> E->F. After nextFocus is configured, the focus sequence of the Tab key is A->F -> B->C -> D->E -> A.
Focus navigation order for the **Tab** key: Without **nextFocus** configured: The focus navigation order is A -> B -> C -> D -> E -> F. With **nextFocus** configured: The focus navigation order is A ->F -> B ->C -> D ->E -> A.
Focus by pressing the down arrow key (for example): If nextFocus is not configured, after the Tab key is pressed to activate the focus state, the focus sequence of the down arrow key is A->D -> E->F. After nextFocus is configured, after the Tab key is pressed to activate the focus state, the focus sequence of the down arrow key is A->B -> C->D -> E->F -> A.
Focus navigation order for the down arrow key (example): Without **nextFocus** configured: After the focus activation state is triggered with the **Tab** key, the focus navigation order is A ->D -> E -> F. With **nextFocus** configured: After the focus activation state is triggered with the **Tab** key, the focus navigation order is is A -> B -> C->D -> E->F -> A.
@@ -1074,7 +1079,7 @@ Focus by pressing the down arrow key (for example): If nextFocus is not configur
tabIndex(index: number)
```
tabIndex customizes the focus sequence of the Tab key.
The **tabIndex** attribute customizes the focus navigation order for 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.
@@ -1082,9 +1087,9 @@ When components with positive **tabIndex** values are present, only these compon
>
> **tabIndex** and **focusScopeId** cannot be both set on the same component.
>
> You are advised not to set the tabIndex attribute of a component to a negative number on the [hierarchical page](#basic-concepts) to control the focus capability. You can use the focusable attribute instead.
> Avoid setting a component's **tabIndex** to a negative number on a hierarchical page to control its focusability. Use the **focusable** attribute for that purpose instead.
>
> tabIndex can only customize the focus of the Tab key. If you want to customize the focus capability of the arrow key, you are advised to use [nextfocus](#setting-the-focus-navigation-order-with-nextfocus).
> **tabIndex** only customizes **Tab** key navigation. For arrow key navigation customization, use [nextfocus](#setting-the-focus-navigation-order-with-nextfocus).
```ts
@Entry
@@ -1299,8 +1304,8 @@ struct FocusableExample {
The preceding example includes two steps:
- The **TextInput** component is part of a focus group. When the **Tab** key is pressed, focus quickly moves out of the **TextInput** component to the next focusable element outside the group. Arrow keys can be used to move focus within the **TextInput** component.
- 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.
- The **TextInput** component is part of a focus group. When the **Tab** key is pressed, the focus quickly moves out of the **TextInput** component to the next focusable element outside the group. Arrow keys can be used to move focus within the **TextInput** component.
- The two **Column** components on the left do not have a focus group set. Therefore, focus can only be traversed one by one with the **Tab** key.
In API version 14, you can use the **arrowStepOut** parameter on a focus group to specify whether focus can move out of the group using arrow keys.
@@ -31,7 +31,7 @@ You can use the [getPromptAction](../reference/apis-arkui/arkts-apis-uicontext-u
- Follow the default toast positioning guidelines.
By default, toasts appear from the bottom of the screen with appropriate safe area margins. Ensure they do not overlap with other popup components. In specific scenarios, consider adjusting content layout to prevent such conflicts.
By default, toasts appear from the bottom of the screen with a safe margin from the bottom edge. As an in-application notification mechanism, retain this default system behavior to avoid overlapping with other popup components. In specific scenarios, consider adjusting content layout to prevent such conflicts.
- Adhere to the maximum font scale for toasts.
@@ -52,6 +52,7 @@ Before displaying a TOP_MOST toast, a full-screen subwindow is created (the size
```ts
import { promptAction } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
@@ -60,19 +61,25 @@ struct Index {
Column({ space: 10 }) {
TextInput()
Button() {
Text("Toast of the DEFAULT type")
Text('Toast of the DEFAULT type')
.fontSize(20)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.onClick(() => {
this.getUIContext().getPromptAction().showToast({
message: "OK, I am DEFAULT toast.",
duration: 2000,
showMode: promptAction.ToastShowMode.DEFAULT,
bottom: 80
});
try {
this.getUIContext().getPromptAction().showToast({
message: 'OK, I am DEFAULT toast.',
duration: 2000,
showMode: promptAction.ToastShowMode.DEFAULT,
bottom: 80
});
} catch (error) {
let message = (error as BusinessError).message;
let code = (error as BusinessError).code;
console.error(`showToast args error code is ${code}, message is ${message}`);
}
})
Button() {
@@ -83,12 +90,18 @@ struct Index {
}
.width('100%')
.onClick(() => {
this.getUIContext().getPromptAction().showToast({
message: "OK, I am TOP_MOST toast.",
duration: 2000,
showMode: promptAction.ToastShowMode.TOP_MOST,
bottom: 85
});
try {
this.getUIContext().getPromptAction().showToast({
message: "OK, I am TOP_MOST toast.",
duration: 2000,
showMode: promptAction.ToastShowMode.TOP_MOST,
bottom: 85
});
} catch (error) {
let message = (error as BusinessError).message;
let code = (error as BusinessError).code;
console.error(`showToast args error code is ${code}, message is ${message}`);
}
})
}
}
@@ -131,7 +144,7 @@ struct toastExample {

## Creating a Toast with a Close Button
## Displaying and Closing a Toast
This mode is suitable for scenarios where the dialog box has a longer retention period and the user can close it manually.
@@ -59,7 +59,7 @@ You can draw custom graphics on the canvas in any of the following ways:
// Configure the parameters of the CanvasRenderingContext2D and OffscreenCanvasRenderingContext2D objects, including whether to enable anti-aliasing. The value true indicates that anti-aliasing is enabled.
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
// Create an OffscreenCanvas object. width indicates the width of the offscreen canvas, and height indicates the height of the offscreen canvas.
// Create an OffscreenCanvas object. width indicates the width of the offscreen canvas, and height indicates the height of the offscreen canvas. OffscreenCanvasRenderingContext2D handles offscreen graphics rendering.
private offCanvas: OffscreenCanvas = new OffscreenCanvas(600, 600);
build() {
@@ -120,7 +120,7 @@ Canvas(this.context)
After **onReady()** is invoked, you can use the **Canvas** component for drawing. Alternatively, you can separately define the **Path2d** object to build an ideal path without the **Canvas** component and **onReady()** lifecycle callback, and then use the **Canvas** component for drawing after **onReady()** is invoked.
- After the **onReady()** callback of the **Canvas** component is invoked, use the **CanvasRenderingContext2D** and **OffscreenCanvasRenderingContext2D** objects to call related APIs for drawing.
- Use the **CanvasRenderingContext2D** object to call related APIs for drawing.
```ts
Canvas(this.context)
@@ -398,7 +398,7 @@ To improve performance and avoid unnecessary rendering, you can listen for **Can
- Using the [setOnVisibleAreaApproximateChange](../reference/apis-arkui/arkui-ts/ts-uicommonevent.md#setonvisibleareaapproximatechange) API, available since API version 13
```ts
```ts
import { ColorMetrics } from '@kit.ArkUI';
@Entry
@@ -443,7 +443,7 @@ To improve performance and avoid unnecessary rendering, you can listen for **Can
if (this.timerId == -2) {
this.timerId = setInterval(() => {
this.drawRandomCircle()
}, 50)
}, 500)
}
}
})
@@ -453,7 +453,7 @@ To improve performance and avoid unnecessary rendering, you can listen for **Can
if (this.timerId < 0) {
this.timerId = setInterval(() => {
this.drawRandomCircle()
}, 50)
}, 500)
}
})
}
@@ -462,11 +462,11 @@ To improve performance and avoid unnecessary rendering, you can listen for **Can
- Using the [onVisibleAreaApproximateChange](../reference/apis-arkui/arkui-ts/ts-universal-component-visible-area-change-event.md#onvisibleareaapproximatechange17) API, available since API version 17
```ts
```ts
import { ColorMetrics } from '@kit.ArkUI';
@Entry
@@ -509,7 +509,7 @@ To improve performance and avoid unnecessary rendering, you can listen for **Can
if (this.timerId == -2) {
this.timerId = setInterval(() => {
this.drawRandomCircle()
}, 50)
}, 500)
}
}
})
@@ -518,7 +518,7 @@ To improve performance and avoid unnecessary rendering, you can listen for **Can
if (this.timerId < 0) {
this.timerId = setInterval(() => {
this.drawRandomCircle()
}, 50)
}, 500)
}
})
}
@@ -527,7 +527,7 @@ To improve performance and avoid unnecessary rendering, you can listen for **Can
A combined gesture is a combination of multiple single gestures. Its recognition mode is subject to **GestureMode** passed in **GestureGroup**. Three recognition modes are supported: [sequential recognition](#sequential-recognition), [parallel recognition](#parallel-recognition), and [exclusive recognition](#exclusive-recognition).
A combined gesture is a combination of multiple single gestures. Its recognition mode is subject to [GestureMode](../reference/apis-arkui/arkui-ts/ts-combined-gestures.md#gesturemode) passed in **GestureGroup**. Three recognition modes are supported: [sequential recognition](#sequential-recognition), [parallel recognition](#parallel-recognition), and [exclusive recognition](#exclusive-recognition).
- **mode**: recognition mode of combined gestures. The value belongs to the **GestureMode** enumeration class.
- **gesture**: array of multiple gestures.
- **gesture**: array of multiple gestures. .
## Sequential Recognition
@@ -19,7 +25,7 @@ For sequential recognition, the value of **GestureMode** is **Sequence**. In thi
In the following example, the combined gestures for continuous recognition are the long press gesture and pan gesture.
The **translate** attribute is bound to a **Column** component. You can set the attribute to translate the component. Then, bind **LongPressGesture** and **PanGesture** to the component in the **Sequence** gesture mode. When a long press gesture is recognized, the displayed number is updated. When the user drags the component after the long press gesture, the component is dragged based on the callback function of the pan gesture.
The [translate](../reference/apis-arkui/arkui-ts/ts-universal-attributes-transformation.md#translate) attribute is bound to a **Column** component. You can set the attribute to translate the component. Then, bind [LongPressGesture](../reference/apis-arkui/arkui-ts/ts-basic-gestures-longpressgesture.md) and [PanGesture](../reference/apis-arkui/arkui-ts/ts-basic-gestures-pangesture.md) to the component in the **Sequence** recognition mode. When a long press gesture is recognized, the displayed number is updated. When the user drags the component after the long press gesture, the component is dragged based on the callback function of the pan gesture.
For exclusive recognition, the value of **GestureMode** is **Exclusive**. In this gesture recognition mode, all registered gestures are recognized at once. Once any of the gestures is recognized successfully, the gesture recognition ends, and all other gestures fail to be recognized.
For example, when the tap gesture and the double-tap gesture are bound to the **Column** component in exclusive recognition mode, if you bind the tap gesture first, followed by the double-tap, the double-tap gesture won't be recognized because the tap consumes all touch events. However, if you bind the double-tap gesture first, it will be recognized without triggering the tap.
For example, when both the tap gesture and double-tap gesture are bound to a **Column** component in exclusive recognition mode, the order in which these gestures are bound matters. If you bind the tap gesture before the double-tap, the double-tap gesture won't be recognized because the tap consumes all touch events. Conversely, if you bind the double-tap gesture first, it will be recognized without being intercepted by the tap gesture.
```ts
// xxx.ets
@@ -200,3 +206,70 @@ struct Index {
>When there is only a single tap, the tap gesture is recognized, but the double-tap gesture fails to be recognized.
>
>When there are two taps, the gesture response depends on the order of gesture binding. If you bind the tap gesture first, followed by the double-tap gesture, the tap gesture will be recognized on the first tap, causing the double-tap gesture to fail. Even if the second tap is performed within the specified time, the double-tap gesture event is not responded to. Instead, another tap gesture event is triggered. Conversely, if you bind the double-tap gesture first, it will be recognized without triggering the tap gesture.
## Example Scenario
The following example implements a child component bound to long press and pan gestures. Although the long press and pan gestures can trigger simultaneously, the parent **Swiper** component's built‑in swipe gesture should take effect when the long press gesture is not successfully recognized. Since the child component's pan gesture competes with the parent component's built‑in swipe gesture, and the child's gesture has higher priority, dynamic control is needed to determine whether the child's pan gesture should trigger.
// Use a custom gesture judgment callback to reject the child's pan gesture when the long press gesture fails, allowing the parent Swiper component's swipe gesture to succeed.
Gesture conflicts occur when multiple gesture recognizers compete for recognition on the same component or overlapping areas, resulting in unexpected behavior. Common conflict scenarios include:
- Multiple gestures on the same component (for example, both tap and long-press gestures on a button)
- Multiple gestures on the same component (for example, both tap and longpress gestures on a button)
- Gesture recognizers of the same type on parent and child components
- Conflicts between system default gestures and custom gestures (for example, conflict between the scroll gesture and the click gesture of a child component)
@@ -28,7 +28,7 @@ Custom gesture judgment involves the following APIs.
|[onGestureJudgeBegin](../reference/apis-arkui/arkui-ts/ts-gesture-customize-judge.md#ongesturejudgebegin)|Used for gesture interception as a universal event. Called when the gesture meets system trigger thresholds, allowing the application to determine whether to intercept the gesture.|
|[onGestureRecognizerJudgeBegin](../reference/apis-arkui/arkui-ts/ts-gesture-blocking-enhancement.md#ongesturerecognizerjudgebegin)|Called to implement gesture judgment, obtain gesture recognizers, and set their enabled state. It is an extension of **onGestureJudgeBegin** and can serve as its substitute.<br>When obtaining gesture recognizers, this API obtains all gesture recognizers in the response chain of the current interaction, as well as the recognizer about to be triggered successfully, allowing the enabled state of the gesture to be set.|
In the following example, the **Image** and **Stack** components are located in the same area. Long-pressing the upper half of the **Stack** component triggers the long-press gesture bound to the **Stack** component, while long-pressing the lower half of the **Stack** component triggers the drag operation of the **Image** component.
In the following example, the **Image** and **Stack** components are located in the same area. Long-pressing the upper half of the **Stack** component triggers the longpress gesture bound to the **Stack** component, while long-pressing the lower half of the **Stack** component triggers the drag operation of the **Image** component.
**Figure 2** Example
@@ -80,61 +80,68 @@ In the following example, the **Image** and **Stack** components are located in
Text("There are two layers of components, the upper layer component bound to a long press gesture, and the lower layer component bound to a drag. The lower half of the upper layer component is bound to gesture judgment, making this area respond to the drag gesture of the lower layer.").width('100%').fontSize(20).fontColor('0xffdd00')
@@ -456,7 +463,7 @@ The parent container (**video_layer**) has multiple bound gestures:
- Vertical swipe: adjusts brightness.
- Horizontal swipe: seeks playback.
The inner **Slider** component (**progress_layer**) does not have a long-press gesture bound to it. This causes the parent container's fast-forward gesture to be triggered when the user long-presses the **Slider** component, which is unexpected behavior.
The inner **Slider** component (**progress_layer**) does not have a longpress gesture bound to it. This causes the parent container's fast-forward gesture to be triggered when the user long-presses the **Slider** component, which is unexpected behavior.
Solution: Register an **onTouchTestDone** callback on the **Slider** component. Use this callback to disable gesture recognizers not belonging to the **Slider** component, thereby resolving the conflict.
@@ -466,134 +473,157 @@ The following shows the complete sample code:
@Entry
@ComponentV2
struct Index {
@Local progress: number = 496000 // Initial progress, in seconds.
@Local total: number = 27490000 // Total duration, in seconds.
@Local currentWidth: string = '100%'
@Local currentHeight: string = '100%'
private currentPosX: number = 0
private currentPosY: number = 0
private currentFullScreenState: boolean = true
@Local progress: number = 496000; // Initial progress, in seconds.
@Local total: number = 27490000; // Total duration, in seconds.
Multi-level gesture events occur when both parent and child components receive a gesture or event bound to them. Handling such events can be tricky: The gesture and event detection is affected by a plurality of factors, with much transmission and competition involved, and an unexpected response easily occurs.
@@ -31,10 +31,11 @@ ComponentA() {
}.onTouch(() => {})
```
If components B and C are children of component A, then touching component B or component C also touches component A. The **onTouch** callback can be invoked by multiple components at the same time.
Therefore, when component B is touched, the **onTouch** callback is invoked by both component A and component B, but not by component C; when component C is touched, the **onTouch** callback is invoked by both component A and component C, but not by component B.
Therefore, when component B is touched, the **onTouch** callback is invoked by both component A and component B, but not by component C;
when component C is touched, the **onTouch** callback is invoked by both component A and component C, but not by component B.
For special container components, such as **Stack**, **onTouch** events can be received by parent and child components at the same time, but how they are received by child components depends on the stacking relationship.
```ts
Stack A() {
@@ -87,7 +88,7 @@ Specifically, use the **responseRegion** and **hitTestBehavior** attributes to c
### Using responseRegion
The **responseRegion** attribute sets the touch target of a component, which can be larger or smaller than the layout scope of the component.
The [responseRegion](../reference/apis-arkui/arkui-ts/ts-universal-attributes-touch-target.md#responseregion) attribute sets the touch target of a component, which can be larger or smaller than the layout scope of the component.
```ts
ComponentA() {
@@ -110,7 +111,7 @@ The **responseRegion** attribute accepts an array consisting of multiple **Rect*
### Using hitTestBehavior
The **hitTestBehavior** attribute sets which components can respond to specific gestures and events. It is especially useful under complex multi-level event scenarios.
The [hitTestBehavior](../reference/apis-arkui/arkui-ts/ts-universal-attributes-hit-test-behavior.md#hittestbehavior) attribute sets which components can respond to specific gestures and events. It is especially useful under complex multi-layer event scenarios.
```ts
ComponentA() {
@@ -154,7 +155,7 @@ With **HitTestMode.Transparent**, both the node and its child node respond to th
If **hitTestBehavior** is not set for component C, when the overlapping area of component B and component C is touched, the **onTouch** events of Stack A and component C are triggered, the touch event of component C is triggered, and neither the **onTouch** event nor tap gesture of component B is triggered.
If **hitTestBehavior** is set to **HitTestMode.Transparent** for component C, when the overlapping area of components B and C is touched, the **onTouch** events of Stack A and component C are still triggered, and the touch event of component C is also triggered; yet, because component B can receive the touch event in this case, its **onTouch** event and tap gesture are triggered.
If **hitTestBehavior** is set to **HitTestMode.Transparent** for component C, when the overlapping area of components B and C is touched, the **onTouch** events of Stack A and component C are still triggered, and the touch event of component C is also triggered; yet, because component B can receive the touch event in this case, its **onTouch** event is triggered.
```ts
ComponentA() {
@@ -172,6 +173,52 @@ If **hitTestBehavior** is not set for component A, a touch in the target touch o
When **hitTestBehavior** is set to **HitTestMode.None** for component A, a touch in the target touch of component B triggers the **onTouch** event and tap gesture of component B, but not the **onTouch** event of component A.
```ts
Stack A() {
ComponentB()
.onTouch(() => {})
.gesture(TapGesture({count: 1}))
ComponentC() {
ComponentD()
.onTouch(() => {})
.gesture(TapGesture({count: 1}))
}
.onTouch(() => {})
.gesture(TapGesture({count: 1}))
.hitTestBehavior(HitTestMode.BLOCK_HIERARCHY)
}
.onTouch(() => {})
.gesture(TapGesture({count: 1}))
```
Starting from API version 20, **HitTestMode.BLOCK_HIERARCHY** enables the node itself and its child nodes to respond to hit testing, while blocking all lower‑priority sibling nodes and parent nodes from participating in hit testing.
When component C does not have **hitTestBehavior** set, clicking the overlapping area of components B and D triggers the **onTouch** events of components A, C, and D, and also triggers the click gesture of component D.
When component C has **hitTestBehavior** set to **HitTestMode.BLOCK_HIERARCHY**, clicking the overlapping area of components B and D triggers the **onTouch** events of components C and D, while the **onTouch** events of components A and B are not triggered; the click gesture of component D is still triggered.
```ts
Stack A() {
ComponentB()
.onTouch(() => {})
.gesture(TapGesture({count: 1}))
ComponentC() {
ComponentD()
.onTouch(() => {})
.gesture(TapGesture({count: 1}))
}
.onTouch(() => {})
.gesture(TapGesture({count: 1}))
.hitTestBehavior(HitTestMode.BLOCK_DESCENDANTS)
}
.onTouch(() => {})
.gesture(TapGesture({count: 1}))
```
Starting from API version 20, [HitTestMode](../reference/apis-arkui/arkui-ts/ts-appendix-enums.md#hittestmode9).BLOCK_DESCENDANTS prevents the node itself and all its descendants (children, grandchildren, and more) from responding to hit testing, without affecting the hit‑testing behavior of ancestor nodes.
If component C does not have [hitTestBehavior](../reference/apis-arkui/arkui-ts/ts-universal-attributes-hit-test-behavior.md#hittestbehavior) set, clicking the overlapping area of components B and D triggers the **onTouch** events of components A, C, and D, and also triggers the click gesture of component D.
When component C has [hitTestBehavior](../reference/apis-arkui/arkui-ts/ts-universal-attributes-hit-test-behavior.md#hittestbehavior) set to **HitTestMode.BLOCK_DESCENDANTS**, clicking the overlapping area of components B and D triggers the [onTouch](../reference/apis-arkui/arkui-ts/ts-universal-events-touch.md#ontouch) events of components A and B, while the **onTouch** events of components C and D are not triggered; the click gesture of component B is triggered instead.
Under simple scenarios, you are advised to set **hitTestBehavior** for each single component.
Under complex scenarios, you are advised to set different **hitTestBehavior** values to multiple components to control the dispatching of touch events.
@@ -199,7 +246,7 @@ ComponentA() {
}
.priorityGesture(TapGesture({count: 1}))
```
In the preceding example, the **.priorityGesture** method is used to bind the parent component to the tap gesture, and the parent component responds prior to the child component.
When a parent component binds a gesture .[priorityGesture](../reference/apis-arkui/arkui-ts/ts-gesture-settings.md#prioritygesture), the gesture on the parent component takes precedence over gestures on its child components.
In this case, when component B is touched, the tap gesture of component A is triggered, but that of component B is not.
To enable both the parent and child components to respond to a same gesture, use the **.parallelGesture** method in the parent component.
@@ -211,11 +258,11 @@ ComponentA() {
}
.parallelGesture(TapGesture({count: 1}))
```
In the preceding example, the **.parallelGesture** method is used to bind the parent component to the tap gesture, and both the parent and child components can respond to the bound gesture.
When a parent component binds a gesture using .[parallelGesture](../reference/apis-arkui/arkui-ts/ts-gesture-settings.md#parallelgesture), both the parent's and the child's gestures can be triggered.
In this case, when component B is touched, both the tap gestures of components A and B are triggered.
### Implementing Event Passthrough in OverlayManager
In the event mechanism of **OverlayManager**, events are first received by components within **WrappedBuilder** by default and are not propagated downward.
In the event mechanism of [OverlayManager](../reference/apis-arkui/arkts-apis-uicontext-overlaymanager.md), events are first delivered to components inside the [WrappedBuilder](../reference/apis-arkui/arkui-ts/ts-universal-wrapBuilder.md#wrappedbuilder) and are not propagated downward by default.
To enable the underlying page below the **OverlayManager** to detect events, you can use **hitTestBehavior(HitTestMode.Transparent)** to pass through events. Refer to the following pseudocode:
When a user's action matches the predefined characteristics of a gesture, the system interprets it as a recognized gesture. This process is known as gesture recognition. To respond to gestures, you must bind the appropriate gesture object to a component. This enables the system to detect, interpret, and dispatch gesture events accordingly.
When a user action matches the predefined characteristics of a gesture, the system recognizes it as that gesture. This process is called gesture recognition. To respond to a gesture, you need to attach a gesture object to a component so the system can collect and process the gesture input.
## Overview of Basic Gestures
## Basic Gestures and Features
| Gesture | Operation Characteristics | Triggering Example |
| Gesture | Operation Feature | Triggering Example |
| [TapGesture](../reference/apis-arkui/arkui-ts/ts-basic-gestures-tapgesture.md) | A quick press and release (≤ 300 ms by default). | Tap with a finger or stylus on a touchscreen; left-click with a mouse; single tap on a touchpad. |
| [LongPressGesture](../reference/apis-arkui/arkui-ts/ts-basic-gestures-longpressgesture.md) | Long press for a sustained duration. | Long press with a finger or stylus; hold down the left mouse button; long press on a touchpad. |
| [TapGesture](../reference/apis-arkui/arkui-ts/ts-basic-gestures-tapgesture.md) | Quick press and release (≤ 300 ms by default). | Tap with a finger or stylus on a touchscreen; left-click with a mouse; single tap on a touchpad. |
| [LongPressGesture](../reference/apis-arkui/arkui-ts/ts-basic-gestures-longpressgesture.md) | Press and hold for a sustained duration. | Long press with a finger or stylus; hold down the left mouse button; long press on a touchpad. |
| [PanGesture](../reference/apis-arkui/arkui-ts/ts-basic-gestures-pangesture.md) | Press and drag (displacement-based movement). | Drag with a finger or stylus; move the mouse while holding the left button; swipe with two fingers on a touchpad; scroll the mouse wheel over a scrollable component.|
| [PinchGesture](../reference/apis-arkui/arkui-ts/ts-basic-gestures-pinchgesture.md) | Pinch inward or outward using two fingers. | Pinch gesture on touchscreen or touchpad; scroll the mouse wheel while holding **Ctrl** over a pinch-enabled component. |
| [RotationGesture](../reference/apis-arkui/arkui-ts/ts-basic-gestures-rotationgesture.md) | Rotate two fingers around a central point. | Rotate gesture using two fingers on a touchscreen. |
@@ -61,9 +61,9 @@ Gesture recognition is still initiated based on [hit testing](./arkts-interactio
| Custom gesture judgment | Allows applications to conditionally approve or reject a gesture before the system finalizes recognition. | [onGestureJudgeBegin](../reference/apis-arkui/arkui-ts/ts-gesture-customize-judge.md#ongesturejudgebegin) | Invoked when a gesture is about to be recognized as successful. The application can override the system's decision by returning a rejection, allowing other gestures to compete for recognition. |
| Enhanced gesture judgment| Provides higher-priority control over gesture recognition.| [onGestureRecognizerJudgeBegin](../reference/apis-arkui/arkui-ts/ts-gesture-blocking-enhancement.md#ongesturerecognizerjudgebegin13) | 1. Works similarly to **onGestureJudgeBegin**, but with higher priority.<br>2. If this API is bound, **onGestureJudgeBegin** becomes ineffective. |
| Parallel gesture control | Enables concurrent gesture recognition between parent and child components, which is useful for nested scrolling. | [shouldBuiltInRecognizerParallelWith](../reference/apis-arkui/arkui-ts/ts-gesture-blocking-enhancement.md#shouldbuiltinrecognizerparallelwith) | 1. Triggered when the user presses a component and the system begins collecting gesture objects.<br>2. Returns built-in gestures (currently only **PanGesture**) on the current component and previously collected gestures of the same type from child components. By default, child gestures have higher priority and override parent gestures.<br>3. This API allows you to force parallel recognition, enabling both parent and child gestures to respond.<br>4. The returned gesture object includes APIs for controlling response behavior, allowing you to implement nested scrolling (for example, the child scrolls first, and then the parent scrolls when the child reaches the boundary).<br>**NOTE**<br>This API only applies to components with built-in gestures (for example, **List** and **Swiper**). It has no effect otherwise.|
| Gesture recognition prevention | Prevents specific gestures from participating in recognition before they are processed. | [preventBegin](../reference/apis-arkui/arkui-ts/ts-gesture-common.md#preventbegin20) | 1. Triggered during the [onTouchTestDone](../reference/apis-arkui/arkui-ts/ts-gesture-blocking-enhancement.md#ontouchtestdone20) callback when the user presses the screen.<br>2. Returns all gesture recognizers eligible for processing at the current position.<br>3. You can selectively call **preventBegin** on recognizers to exclude them from recognition, helping avoid gesture conflicts.|
| Enhanced gesture judgment| Allows applications to conditionally approve or reject a gesture before the system finalizes recognition.| [onGestureRecognizerJudgeBegin](../reference/apis-arkui/arkui-ts/ts-gesture-blocking-enhancement.md#ongesturerecognizerjudgebegin13) | 1. Works similarly to **onGestureJudgeBegin**, but with higher priority.<br>2. If this API is bound, **onGestureJudgeBegin** becomes ineffective. |
| Parallel gesture control | Enables concurrent gesture recognition between parent and child components, which is useful for nested scrolling. | [shouldBuiltInRecognizerParallelWith](../reference/apis-arkui/arkui-ts/ts-gesture-blocking-enhancement.md#shouldbuiltinrecognizerparallelwith) | 1. Triggered when the user presses a component and the system begins collecting gesture objects.<br>2. Returns built-in gestures (currently only **PanGesture**) on the current component and previously collected gestures of the same type from child components. By default, child gestures have higher priority and override parent gestures.<br>3. Allows the application to forcibly specify that the low-priority gesture (for example, pan) on the current component runs in parallel with the high-priority gesture of the same type on the child component. That is, when the high-priority gesture on the child component is successfully recognized, the gesture of the same type on the current component can also be triggered and responded to successfully.<br>4. The returned gesture object provides an API to control the enabling of gesture responses. Therefore, after gestures are set to run in parallel, the application can control the response behavior of the two parallel gestures to achieve nested scrolling (e.g., one scrolls first, and the other triggers when the edge is reached).<br>**NOTE**<br>This method only takes effect when the bound component has built-in system gestures (e.g., **List** or **Swiper**). Otherwise, it has no effect.|
| Gesture recognition prevention | Prevents specific gestures from participating in recognition before they are processed. | [preventBegin](../reference/apis-arkui/arkui-ts/ts-gesture-common.md#preventbegin20) | 1. Triggered during the [onTouchTestDone](../reference/apis-arkui/arkui-ts/ts-gesture-blocking-enhancement.md#ontouchtestdone20) callback when the user presses the screen.<br>2. Returns all gesture recognizers eligible for processing at the current position.<br>3. You can selectively call **preventBegin** on recognizers to exclude them from recognition, helping avoid gesture conflicts.<br>This capability is supported since API version 20.|
For details, see [Gesture Conflict Handling](arkts-gesture-events-gesture-judge.md).
@@ -15,7 +15,7 @@ ArkUI provides the [Grid](../reference/apis-arkui/arkui-ts/ts-container-grid.md)
> **NOTE**
>
> This document only shows key code snippets. For the complete code that can run, see <!--RP2-->[Creating a Grid](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/DocsSample/ArkUISample/ScrollableComponent)<!--RP2End-->.
> This document provides key code excerpts for reference.<!--RP2--><!--RP2End-->
## Layout and Constraints
@@ -49,7 +49,7 @@ Depending on the settings of the quantity and proportion of rows and columns, th
### Setting the Number and Proportion of Rows and Columns
You can set the number and proportion of rows and columns to determine the overall arrangement mode of the grid layout. To do so, use the **rowsTemplate** and **columnsTemplate** attributes of the **Grid** component.
You can set the number and proportion of rows and columns to determine the overall arrangement mode of the grid layout. To do so, use the [rowsTemplate](../reference/apis-arkui/arkui-ts/ts-container-grid.md#rowstemplate) and [columnsTemplate](../reference/apis-arkui/arkui-ts/ts-container-grid.md#columnstemplate) attributes of the **Grid** component.
The values of **rowsTemplate** and **columnsTemplate** are a string consisting of 'number+fr' segments, separated by spaces. Wherein **fr** indicates the number of rows or columns in the grid layout, and the number in front of **fr** is used to calculate the proportion of the row or column in the grid width, thereby determining the width of the row or column.
@@ -88,7 +88,7 @@ A common application with an uneven grid layout is the calculator. As shown in t
In the grid, use the **onGetRectByIndex** callback to return the array [rowStart, columnStart, rowSpan, columnSpan] to achieve a layout that spans rows and columns, wherein **rowStart** and **rowEnd** indicate the start and end row numbers of the current element, and **columnStart** and **columnEnd** indicate the start and end column numbers of the current element.
In the grid, use the **onGetRectByIndex** callback to return the array [rowStart, columnStart, rowSpan, columnSpan] to achieve a layout that spans rows and columns, wherein **rowStart** and **columnStart** indicate the start row number and start column number of the current element, and **rowSpan** and **columnSpan** indicate the number of rows and columns occupied by the current element.
To make the **0** key span across the first and second columns, and the **=** key span across the fifth and sixth rows, set **onGetRectByIndex** for **0** and **=** as follows: for **0**, set **rowStart** and **columnStart** at **6** and **0**, and **rowSpan** and **columnSpan** at **1** and **2**; for **=**, set **rowStart** and **columnStart** at **5** and **3**, and **rowSpan** and **columnSpan** at **2** and **1**.
When neither the number nor proportion is set for rows and columns in a grid layout, you can use the **layoutDirection** attribute to set the main axis direction and thereby specify the arrangement mode of child components. In addition, you can use the **minCount** and **maxCount** attributes to restrict the number of grid cells along the main axis.
When neither the number nor proportion is set for rows and columns in a grid layout, you can use the [layoutDirection](../reference/apis-arkui/arkui-ts/ts-container-grid.md#layoutdirection8) attribute to set the main axis direction and thereby specify the arrangement mode of child components. In addition, you can use the [minCount](../reference/apis-arkui/arkui-ts/ts-container-grid.md#mincount8) and [maxCount](../reference/apis-arkui/arkui-ts/ts-container-grid.md#maxcount8) attributes to restrict the number of grid cells along the main axis.
**Figure 6** Main axis direction
@@ -206,13 +206,13 @@ struct OfficeService {
## Setting the Gap Between Rows and Columns
The horizontal spacing between two grid cells is called row spacing, and the vertical spacing is called column spacing, as shown in the following figure.
The horizontal spacing between grid cells is called row spacing, and the vertical spacing is called column spacing, as illustrated below.
You can use **rowsGap** and **columnsGap** to set the row spacing and column spacing of the grid layout. In the calculator shown in Figure 5, the row spacing is 15 vp, and the column spacing is 10vp.
To configure the row and column spacing of a grid layout, use the [rowsGap](../reference/apis-arkui/arkui-ts/ts-container-grid.md#rowsgap) and [columnsGap](../reference/apis-arkui/arkui-ts/ts-container-grid.md#columnsgap) attributes of the **Grid** component. In the calculator shown in Figure 5, the row spacing is 15 vp, and the column spacing is 10vp.
```ts
@@ -341,9 +341,9 @@ To add an external scrollbar to a [Grid](../reference/apis-arkui/arkui-ts/ts-con
Just as [LazyForEach](../ui/rendering-control/arkts-rendering-control-foreach.md) is recommended for [handling a long list](arkts-layout-development-create-list.md#handling-a-long-list), [LazyForEach](../ui/rendering-control/arkts-rendering-control-lazyforeach.md) is recommended for a scrolling grid layout when a large number of grid items is involved.
For details about the implementation of on-demand loading optimization, see the example in [LazyForEach: Lazy Data Loading](../ui/rendering-control/arkts-rendering-control-lazyforeach.md).
For details about the implementation of on-demand loading optimization, see the example in [LazyForEach](../ui/rendering-control/arkts-rendering-control-lazyforeach.md).
When the grid is rendered in lazy loading mode, to improve the grid scrolling experience and minimize white blocks during grid scrolling, you can use the **cachedCount** parameter of the **Grid** component. This parameter sets the number of grid items preloaded outside of the screen and is valid only in **LazyForEach**.
When the grid is rendered in lazy loading mode, to improve the grid scrolling experience and minimize white blocks during grid scrolling, you can use the [cachedCount](../reference/apis-arkui/arkui-ts/ts-container-grid.md#cachedcount) attribute of the **Grid** component. This attribute sets the number of grid items preloaded outside of the screen and is valid only in [LazyForEach](../ui/rendering-control/arkts-rendering-control-lazyforeach.md).
Specifically, the number of the grid items to cache before and after the currently displayed one equals the value of **cachedCount** multiplied by the number of columns. Grid items that exceed the display and cache range are released.
A list is a container that displays a collection of items. If the list items go beyond the screen, the list can scroll to reveal the content off the screen. The list is applicable for presenting similar data types or data type sets, such as images and text. Some common lists seen in applications are the contacts list, playlist, and shopping list.
You can use lists to easily and efficiently display structured, scrollable information. Specifically, you can provide a single view of rows or columns by arranging the [ListItemGroup](../reference/apis-arkui/arkui-ts/ts-container-listitemgroup.md) or [ListItem](../reference/apis-arkui/arkui-ts/ts-container-listitem.md) child components linearly in a vertical or horizontal direction in the [List](../reference/apis-arkui/arkui-ts/ts-container-list.md) component, or use [ForEach](../ui/rendering-control/arkts-rendering-control-foreach.md) to iterate over a group of rows or columns, or mix any number of single views and **ForEach** structures to build a list. The **List** component supports the generation of child components in various [rendering](../ui/rendering-control/arkts-rendering-control-overview.md) modes, including conditional rendering, iterative rendering, and lazy data loading.
You can use lists to easily and efficiently display structured, scrollable information. Specifically, you can provide a single view of rows or columns by arranging the [ListItemGroup](../reference/apis-arkui/arkui-ts/ts-container-listitemgroup.md) or [ListItem](../reference/apis-arkui/arkui-ts/ts-container-listitem.md) child components linearly in a vertical or horizontal direction in the [List](../reference/apis-arkui/arkui-ts/ts-container-list.md) component, or use [ForEach](../ui/rendering-control/arkts-rendering-control-foreach.md) to iterate over a group of rows or columns, or mix any number of single views and **ForEach** structures to build a list. The **List** component supports the generation of child components in various [rendering](../ui/rendering-control/arkts-rendering-control-overview.md) modes, including [conditional rendering](../ui/rendering-control/arkts-rendering-control-ifelse.md), rendering of repeated content, and [lazy data loading](../ui/rendering-control/arkts-rendering-control-lazyforeach.md).
On devices with circular screens, the [ArcList](../reference/apis-arkui/arkui-ts/ts-container-arclist.md) component is recommended. For details, see [Creating an Arc List (ArcList)](./arkts-layout-development-create-arclist.md).
@@ -102,7 +102,7 @@ List() {
### Setting the Cross Axis Layout
The cross axis layout of the **List** component can be set using the **lanes** and **alignListItem** attributes. The **lanes** attribute controls the number of list items along the cross axis, and the **alignListItem** attribute controls the alignment mode of child components along the cross axis.
The cross axis layout of the **List** component can be set using the [lanes](../reference/apis-arkui/arkui-ts/ts-container-list.md#lanes9) and [alignListItem](../reference/apis-arkui/arkui-ts/ts-container-list.md#alignlistitem9) attributes. The **lanes** attribute controls the number of list items along the cross axis, and the **alignListItem** attribute controls the alignment mode of child components along the cross axis.
The **lanes** attribute of the **List** component is usually used to adaptively construct lists with different numbers of rows or columns for devices of different sizes, enabling one-time development for multi-device deployment. Its value type is number or [LengthConstrain](../reference/apis-arkui/arkui-ts/ts-types.md#lengthconstrain). If you are building a two-column vertical list shown on the right in Figure 2, set the **lanes** attribute to **2**. The default value of **lanes** is **1**.
@@ -330,7 +330,7 @@ In the **List** component, **ForEach** can be used to render **ListItemGroup** i
### Setting the Spacing
When initializing a list, you can use the **space** parameter to add spacing between list items. In the following example, a 10 vp spacing is added between list items along the main axis:
When initializing the **List** component, use the **space** parameter of [ListOptions](../reference/apis-arkui/arkui-ts/ts-container-list.md#listoptions18) to configure spacing between list items. In the following example, a 10 vp spacing is added between list items along the main axis:
```ts
@@ -348,7 +348,7 @@ A divider separates UI items to make them easier to identify. In the following f
To add dividers between list items, you can use the **divider** attribute together with the following style attributes:
To add dividers between list items, use the [divider](../reference/apis-arkui/arkui-ts/ts-container-list.md#divider) attribute together with the following style attributes:
- **strokeWidth** and **color**: stroke width and color of the diver, respectively.
@@ -647,7 +647,7 @@ Another common example is a scrolling list working with a multi-level index bar,
As shown above, when the contacts list scrolls from group A to B, the alphabetical index bar on the right also changes from A to B. This scenario can be implemented by listening for the **onScrollIndex** event of the **List** component. The alphabet index bar is implemented using the [AlphabetIndexer](../reference/apis-arkui/arkui-ts/ts-container-alphabet-indexer.md) component.
As shown above, when the contacts list scrolls from group A to B, the alphabetical index bar on the right updates from A to B. This behavior can be implemented by listening for the [onScrollIndex](../reference/apis-arkui/arkui-ts/ts-container-list.md#onscrollindex) event of the **List** component. The alphabetical index bar is implemented using the [AlphabetIndexer](../reference/apis-arkui/arkui-ts/ts-container-alphabet-indexer.md) component.
When the list scrolls, the **selectedIndex** value of the letter to highlight in the alphabet index bar is recalculated based on the **firstIndex** value of the item to which the list has scrolled. In the **AlphabetIndexer** component, the index of the highlighted item is set through the **selected** attribute. When the value of **selectedIndex** changes, the **AlphabetIndexer** component is re-rendered to highlight the corresponding letter.
@@ -1193,7 +1193,7 @@ The process of implementing the collapsing and expanding effect of list items is
}
```
3. Control whether each list item is expanded by changing the state of **ListItem**, and achieve the animation effects during the expanding and collapsing process through **animation** and **animateTo**.
3. Control list item expansion by changing the state of **ListItem** components, and implement expand/collapse animations through [animation](../reference/apis-arkui/arkui-ts/ts-animatorproperty.md#animation) and [animateTo](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#animateto).
```ts
@Builder
@@ -1239,7 +1239,7 @@ In certain scenarios, you may want a list to automatically scroll upward when ne
}
```
2. Construct a list structure and set **stackFromEnd** to **true**. In this way, the list content automatically scrolls upward to reveal newly inserted data items.
2. Construct a list structure and set [stackFromEnd](../reference/apis-arkui/arkui-ts/ts-container-list.md#stackfromend19) to **true**. This configuration causes the list to automatically scroll upward when new items are inserted at the bottom.
```ts
@State messages: Message[] = [
@@ -1317,7 +1317,7 @@ Since API version 20, scrollable components ([Grid](../reference/apis-arkui/arku
})
```
- The current item's position information is obtained through the **getItemRect** API.
- The current item's position information is obtained through the [getItemRect](../reference/apis-arkui/arkui-ts/ts-container-scroll.md#getitemrect11) API.
@@ -25,44 +25,44 @@ When **loop** is set to **true**, the user can switch to the previous or next pa
- Example of setting **loop** to **true**:
```ts
Swiper() {
Text('0')
.width('90%')
.height('100%')
.backgroundColor(Color.Gray)
.textAlign(TextAlign.Center)
.fontSize(30)
Text('1')
.width('90%')
.height('100%')
.backgroundColor(Color.Green)
.textAlign(TextAlign.Center)
.fontSize(30)
Text('2')
.width('90%')
.height('100%')
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
.fontSize(30)
}
.loop(true)
```
```ts
Swiper() {
Text('0')
.width('90%')
.height('100%')
.backgroundColor(Color.Gray)
.textAlign(TextAlign.Center)
.fontSize(30)
Text('1')
.width('90%')
.height('100%')
.backgroundColor(Color.Green)
.textAlign(TextAlign.Center)
.fontSize(30)
Text('2')
.width('90%')
.height('100%')
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
.fontSize(30)
}
.loop(true)
```


- Example of setting **loop** to **false**:
```ts
Swiper() {
// ...
}
.loop(false)
```
```ts
Swiper() {
// ...
}
.loop(false)
```


## Automatic Playback
@@ -91,87 +91,87 @@ With the **indicator** attribute, you can set the position of the indicator rela
- Example of using the navigation indicator in its default style:
```ts
Swiper() {
Text('0')
.width('90%')
.height('100%')
.backgroundColor(Color.Gray)
.textAlign(TextAlign.Center)
.fontSize(30)
Text('1')
.width('90%')
.height('100%')
.backgroundColor(Color.Green)
.textAlign(TextAlign.Center)
.fontSize(30)
Text('2')
.width('90%')
.height('100%')
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
.fontSize(30)
}
```
```ts
Swiper() {
Text('0')
.width('90%')
.height('100%')
.backgroundColor(Color.Gray)
.textAlign(TextAlign.Center)
.fontSize(30)
Text('1')
.width('90%')
.height('100%')
.backgroundColor(Color.Green)
.textAlign(TextAlign.Center)
.fontSize(30)
Text('2')
.width('90%')
.height('100%')
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
.fontSize(30)
}
```


- Example of customizing the style of the navigation indicator
The selected navigation indicator has a diameter of 30 vp with blue color, while unselected indicators have a diameter of 15 vp with red color.
```ts
Swiper() {
// ...
}
.indicator(
Indicator.dot()
.left(0)
.itemWidth(15)
.itemHeight(15)
.selectedItemWidth(30)
.selectedItemHeight(15)
.color(Color.Red)
.selectedColor(Color.Blue)
)
```
The selected navigation indicator has a width of 30 vp, a height of 15 vp, and a blue color. The unselected indicators are 15 vp in both width and height, with a red color.

```ts
Swiper() {
// ...
}
.indicator(
Indicator.dot()
.left(0)
.itemWidth(15)
.itemHeight(15)
.selectedItemWidth(30)
.selectedItemHeight(15)
.color(Color.Red)
.selectedColor(Color.Blue)
)
```

You can set the [displayArrow](../reference/apis-arkui/arkui-ts/ts-container-swiper.md#displayarrow10) attribute of **Swiper** to control the size, position, color, and background of navigation point arrows, and whether to display arrows on mouse hover.
- Example of using the navigation point arrows in the default style:
```ts
Swiper() {
// ...
}
.displayArrow(true, false)
```
```ts
Swiper() {
// ...
}
.displayArrow(true, false)
```


- Example of customizing the style of navigation point arrows:
In this example, the arrows are displayed on both sides of the component, with a size of 18 vp and a color of blue.
In this example, the arrows are displayed on both sides of the component, with a size of 18 vp and a color of blue.
```ts
Swiper() {
// ...
}
.displayArrow({
showBackground: true,
isSidebarMiddle: true,
backgroundSize: 24,
backgroundColor: Color.White,
arrowSize: 18,
arrowColor: Color.Blue
}, false)
```

```ts
Swiper() {
// ...
}
.displayArrow({
showBackground: true,
isSidebarMiddle: true,
backgroundSize: 24,
backgroundColor: Color.White,
arrowSize: 18,
arrowColor: Color.Blue
}, false)
```

## Page Switching Mode
@@ -261,42 +261,42 @@ struct SwiperDemo {
}
```


## Playback Direction
You can set the playback direction for the Swiper component through its **vertical** attribute.
You can set the playback direction for the **Swiper** component through its **vertical** attribute.
When **vertical** is set to **true**, vertical swiping is used. The default value of **vertical** is **false**.
When **vertical** is set to **true**, vertical swiping is used. When **vertical** is set to **false**, horizontal swiping is used. The default value of **vertical** is **false**.
## Ignoring the Navigation Indicator Component Size
After the bottom of the navigation indicator is set to 0, there is still spacing between the indicator bottom and the **Swiper** bottom. To eliminate this spacing, invoke the **bottom(bottom, ignoreSize)** attribute. Set **ignoreSize** to **true** to ignore the navigation indicator component size.
After the bottom of the navigation indicator is set to 0, a gap may still exist between the indicator and the bottom of the **Swiper** component. To remove this gap, apply the **bottom(bottom, ignoreSize)** attribute. Set **ignoreSize** to **true** to ignore the navigation indicator component size.
- Ignoring the dot navigation indicator component size:
```ts
Swiper() {
// ...
}
.indicator(
new DotIndicator()
.bottom(LengthMetrics.vp(0), true)
)
```
```ts
Swiper() {
// ...
}
.indicator(
new DotIndicator()
.bottom(LengthMetrics.vp(0), true)
)
```
- Ignoring the digit navigation indicator component size:
```ts
Swiper() {
// ...
}
.indicator(
new DigitIndicator()
.bottom(LengthMetrics.vp(0), true)
)
```
```ts
Swiper() {
// ...
}
.indicator(
new DigitIndicator()
.bottom(LengthMetrics.vp(0), true)
)
```
Complete sample code for setting the dot spacing and ignoring the component size for a dot navigation indicator:
@@ -655,11 +655,11 @@ struct SwiperExample {
}
```


## Maintaining the Visible Content Position
When using **LazyForEach** to load data (for example, adding data through **onDataAdd**), set the [maintainVisibleContentPosition](../reference/apis-arkui/arkui-ts/ts-container-swiper.md#maintainvisiblecontentposition20) attribute to keep the visible content position stable, preventing view jumps caused by data addition or deletion. Its default value is **false**.
When using **LazyForEach** to load data (for example, adding data through **onDataAdd**), set the [maintainVisibleContentPosition](../reference/apis-arkui/arkui-ts/ts-container-swiper.md#maintainvisiblecontentposition20) attribute to keep the visible content position stable, preventing view jumps caused by data addition or deletion. The attribute's default value is **false**.
When **maintainVisibleContentPosition** is set to **true**, the visible content position remains unchanged when data is inserted or deleted above or before the display area.
@@ -735,11 +735,11 @@ struct SwiperExample {
Column({ space: 12 }) {
Text("index:" + this.index).fontSize(20)
Row() {
// Add data to the position whose LazyForEach index is 0.
// Insert data at index 0 of the LazyForEach data source.
Button('header data add').height(30).onClick(() => {
this.data.addData(0, 'header Data');
})
// Delete data from the position whose LazyForEach index is 0.
// Delete data at index 0 of the LazyForEach data source.
Button('header data delete').height(30).onClick(() => {
@@ -73,35 +73,46 @@ You can customize breakpoints using the [BreakPoints](../reference/apis-arkui/ar
For example, you can define breakpoints to divide the application width into six ranges, and configure **columns** to specify the number of columns in the container for each breakpoint range.
value: ['320vp', '600vp', '840vp', '1440vp', '1600vp'], // Add custom breakpoints '1440vp' and '1600vp' while retaining default breakpoints ['320vp', '600vp', '840vp']. In practice, set breakpoint values based on actual usage scenarios to achieve one-time development for multi-device deployment.
reference: BreakpointsReference.WindowSize
Column({ space: 6 }) {
Text(this.currentBp)
GridRow({
columns: {
xs: 2, // 2 columns for xs devices
sm: 4, // 4 columns for sm devices
md: 8, // 8 columns for md devices
lg: 12, // 12 columns for lg devices
xl: 12, // 12 columns for xl devices
xxl: 12 // 12 columns for xxl devices
},
breakpoints: {
value: ['320vp', '600vp', '840vp', '1440vp', '1600vp'], // Add custom breakpoints '1440vp' and '1600vp' while retaining default breakpoints ['320vp', '600vp', '840vp']. In practice, set breakpoint values based on actual usage scenarios to achieve one-time development for multi-device deployment.
reference: BreakpointsReference.WindowSize
}
}) {
ForEach(this.bgColors, (color: ResourceColor, index?: number | undefined) => {
GridCol({ span: 1 }) { // All child components occupy one column.
Row() {
Text(`${index}`)
}.width("100%").height('50vp')
}.backgroundColor(color)
.height(200)
.border({ color: 'rgb(39,135,217)', width: 2 })
.onBreakpointChange((breakPoint) => {
this.currentBp = breakPoint
})
}
}
@@ -153,60 +164,68 @@ The **columns** attribute defines the total number of columns in the **GridRow**
The **columns** attribute supports two data types: number and [GridRowColumnOption](../reference/apis-arkui/arkui-ts/ts-container-gridrow.md#gridrowcolumnoption). You can configure the total number of responsive grid columns using either approach:
- When **columns** is set to a number, the grid maintains the same number of columns across all device sizes. The following figures demonstrate the layout effects when the grid is configured with 4 and 8 columns respectively, with each child component spanning one column.
ForEach(this.bgColors, (item: ResourceColor, index?: number | undefined) => {
GridCol({ span: 1 }) {
Row() {
Text(`${index}`)
}.width('100%').height('50')
}.backgroundColor(item)
})
Column({ space: 6 }) {
Text('columns: 8').alignSelf(ItemAlign.Start)
Row() {
GridRow({ columns: 8 }) {
ForEach(this.bgColors, (item: ResourceColor, index?: number | undefined) => {
GridCol({ span: 1 }) {
Row() {
Text(`${index}`)
}.width('100%').height('50')
}.backgroundColor(item)
})
}
.width('100%').height('100%')
}
.width('100%').height('100%')
.height(160)
.border({ color: 'rgb(39,135,217)', width: 2 })
.width('90%')
}
.height(160)
.border({ color: 'rgb(39,135,217)', width: 2 })
.width('90%')
}
}
```
@@ -256,7 +275,7 @@ The **columns** attribute supports two data types: number and [GridRowColumnOpti
### Alignment
In the responsive grid layout, you can set the **direction** attribute of **GridRow** to define the direction in which child components are arranged. The options are **GridRowDirection.Row** (from left to right) or **GridRowDirection.RowReverse** (from right to left). An appropriate **direction** value can make the page layout more flexible and meet the design requirements.
In the responsive grid layout, you can set the **direction** attribute of **GridRow** to define the direction in which child components are arranged. The options are [GridRowDirection](../reference/apis-arkui/arkui-ts/ts-container-gridrow.md#gridrowdirection).Row (from left to right) or [GridRowDirection](../reference/apis-arkui/arkui-ts/ts-container-gridrow.md#gridrowdirection).RowReverse (from right to left). An appropriate **direction** value can make the page layout more flexible and meet the design requirements.
- When child components are arranged from left to right (default):
@@ -281,7 +300,7 @@ In the responsive grid layout, you can set the **direction** attribute of **Grid
In the **GridRow** component, **gutter** is used to set the spacing between adjacent child components in the horizontal and vertical directions.
- When **gutter** is set to a number, the number applies to both the horizontal and vertical directions. In the following example, the horizontal and vertical spacing between adjacent child components is set to **10**.
- When **gutter** is set to a number, both the horizontal and vertical spacing between grid child components are set to the same value. In the following example, the horizontal and vertical spacing between adjacent child components is set to **10**.
```ts
@@ -290,7 +309,7 @@ In the **GridRow** component, **gutter** is used to set the spacing between adja
- When **gutter** is set to a value of the **GutterOption** type, the **x** attribute of the value indicates the horizontal gutter, and the **y** attribute indicates the vertical gutter.
- When **gutter** is of type [GutterOption](../reference/apis-arkui/arkui-ts/ts-container-gridrow.md#gutteroption), horizontal and vertical spacing can be set independently: the **x** property defines horizontal spacing, and the **y** property defines vertical spacing.
```ts
@@ -345,16 +364,18 @@ The **span** attribute supports two data types: number and [GridColColumnOption]
- When **span** is set to a number, the child component occupies the same number of columns across all screen sizes.
In this example, the grid is divided into 12 columns. Each child component occupies one column with a two-column offset, resulting in each component and its spacing occupying three columns in total. Four child components fit within a single row.
On devices with lg and larger breakpoints, the grid is divided into 12 columns. Each child component occupies one column with a two-column offset, resulting in each component and its spacing occupying three columns in total. Four child components fit within a single row.
- When **offset** is set to the **GridColColumnOption** type, you can configure different offset values for specific screen sizes (xs, sm, md, lg, xl, xxl).
@@ -26,7 +26,7 @@ A child element does not necessarily adopt the dependency shown above to determi
- Reference boundary: boundary of the current component used for alignment with the anchor.
- Anchor: element relative to which an element's position is specified.
- Anchor: element used as a reference point for specifying another element's position.
- Alignment mode: how the current element is aligned with the anchor, which can be top-, center-, or bottom-aligned in the vertical direction or left-, center-, and right-aligned in the horizontal direction.
@@ -161,45 +161,60 @@ To properly define an anchor, each child element in **RelativeContainer** must h
You can set components in multiple layout components, such as **Row**, **Column**, **Flex**, and **Stack**, to be aligned based on the **RelativeContainer** rules.
You can set components in multiple layout components, such as **Row**, **Column**, **Flex**, and **Stack**, to be aligned based on the relative layout rules.
```ts
@Entry
@Component
struct Index {
@State value: number = 0
build() {
Row() {
@@ -391,7 +404,11 @@ struct Index {
.id("row3")
Stack({ alignContent: Alignment.Bottom }) {
Text('First child, show in bottom').width('90%').height('100%').backgroundColor('#a3cf62').align(Alignment.Top)
Text('First child, show in bottom')
.width('90%')
.height('100%')
.backgroundColor('#a3cf62')
.align(Alignment.Top)
Text('Second child, show in top').width('70%').height('60%').backgroundColor('#00ae9d').align(Alignment.Top)
}
.margin({ top: 5 })
@@ -524,6 +541,7 @@ Chain formation relies on associations between components. Consider a basic hori
* The chain direction and format are declared in the [chainMode](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#chainmode12) API of the chain header component. The **bias** attribute for all elements within the chain is ignored, with only the chain header element's **bias** attribute taking effect as the bias for the entire chain. The chain header is the first component that satisfies chain formation rules. It starts from the left in horizontal layouts (or from the right in mirrored language layouts), and from the top in vertical layouts.
* When the combined size of all chain elements exceeds the chain's anchor constraints, the excess space is evenly distributed to both ends of the chain. In [PACKED](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#chainstyle12) chains, you can use [Bias](../reference/apis-arkui/arkui-ts/ts-types.md#bias) to control how the excess space is distributed.
In the following example, nine **Row** components within the container are grouped into three horizontal chains using **alignRules** and **chainMode**. Components **row1**, **row2**, and **row3** are top-aligned and form a SPREAD chain horizontally; components within the chain are evenly distributed between anchors. Components **row4**, **row5**, and **row6** are centered vertically based on the container and form a SPREAD_INSIDE chain horizontally; the first and last components are aligned with anchors, and others are evenly distributed within the chain. Components **row7**, **row8**, and **row9** are bottom-aligned and form a PACKED chain horizontally; components within the chain have no gaps between them.
Component navigation, implemented using the [Navigation](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md) component, is instrumental for managing transitions between navigation pages (**NavDestination** components). It allows for the passing of parameters across various navigation pages and offers flexible navigation stack operations to simplify access to and reuse of pages. This documentation delves into the display modes, routing operations, subpage management, cross-package navigation, and navigation transition effects.
@@ -33,13 +33,13 @@ The **Navigation** component uses the **mode** attribute to set the page display
- Single-column mode
Single-column mode is designed for narrow-screen devices. When route navigation occurs, the entire page is replaced.
The single-column mode is designed for narrow-screen devices. When route navigation occurs, the entire page content is replaced.
let tooBar: ToolbarItem[] = [toolTmp,toolTmp,toolTmp];
// ...
Navigation(this.navPathStack) {
// ...
}
.toolbarConfiguration(tooBar)
```
## Routing Operations
@@ -329,7 +350,7 @@ Since API version 12, the navigation controller can be inherited. You can custom
@Entry
@Component
struct Index {
//Create a navigation controller object and pass it to the Navigation component.
//Create a navigation controller object and pass it to the Navigation component.
pageStack: NavPathStack = new NavPathStack();
build() {
@@ -342,7 +363,7 @@ struct Index {
### Page Navigation
**NavPathStack** implements the following types of page navigation through **Push** related APIs:
**NavPathStack** uses push-related APIs (such as [pushPath](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#pushpath10), [pushPathByName](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#pushpathbyname10), [pushDestination](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#pushdestination11), and [pushDestinationByName](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#pushdestinationbyname11)) to implement page redirection. Page redirection can be classified into the following types:
1. Normal navigation: Navigation is conducted by page name and allows for passing of **param**.
console.log('Pop page name is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result));
console.info('Pop page name is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result));
});
```
@@ -378,7 +399,7 @@ struct Index {
### Page Return
**NavPathStack** implements the page return feature through **Pop** related APIs.
**NavPathStack** implements the page return feature through pop-related APIs, including [pop](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#pop10), [popToName](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#poptoname10), [popToIndex](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#poptoindex10), and [clear](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#clear10).
```ts
// Return to the previous page.
@@ -393,7 +414,7 @@ this.pageStack.clear();
### Page Replacement
**NavPathStack** implements the page replacement feature through **Replace** related APIs.
**NavPathStack** provides replace-related APIs (such as [replacePath](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#replacepath11), [replacePathByName](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#replacepathbyname11), and [replaceDestination](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#replacedestination18)) to implement the page replacement functionality.
```ts
// Replace the top page of the stack with PageOne.
**NavPathStack** implements the page deletion feature through **Remove** related APIs.
**NavPathStack** provides remove-related APIs (such as [removeByName](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#removebyname11), [removeByIndexes](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#removebyindexes11), and [removeByNavDestinationId](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#removebynavdestinationid12)) to remove pages from the navigation stack.
```ts
// Remove all pages whose name is PageOne from the stack.
**NavPathStack** implements the page moving feature through **Move** related APIs.
**NavPathStack** provides move-related APIs (such as [moveToTop](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#movetotop10) and [moveIndexToTop](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#moveindextotop10)) to move a specific page to the top of the navigation stack.
```ts
// Move the page named PageOne to the top of the stack.
@@ -470,16 +491,16 @@ struct DemoNavDestination {
}
.onResult((param: Object) => {
if (param instanceof NavParam) {
console.log('TestTag', 'get NavParam, its desc: ' + (param as NavParam).desc);
console.info('TestTag', 'get NavParam, its desc: ' + (param as NavParam).desc);
return;
}
console.log('TestTag', 'param not instance of NavParam');
console.info('TestTag', 'param not instance of NavParam');
})
}
}
```
For other use cases, you can retrieve parameters from specific pages by actively calling the get-related APIs of **NavPathStack**.
For other service scenarios, you can proactively call the getter APIs of **NavPathStack** (such as [getAllPathName](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#getallpathname10), [getParamByIndex](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#getparambyindex10), [getParamByName](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#getparambyname10), and [getIndexByName](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#getindexbyname10)) to obtain parameters from specific pages.
The **Navigation** component provides default transition animations for switching between pages. These animations are activated when operations are performed using the navigation controller, producing different transition effects. Note that for pages in dialog mode, the default transition animations are available only since API version 13. The **Navigation** component also offers advanced features such as disabling the default transitions and implementing custom transitions as well as shared element transitions.
The **Navigation** component provides default transition animations for switching between pages. These animations are activated when operations are performed using the navigation controller, producing different transition effects. Note that for pages in dialog mode, the default transition animations are available only since API version 13. The **Navigation** component also offers advanced features such as disabling the default transitions and implementing custom transitions as well as shared element transitions. The default animation duration is determined by physical curve parameters and varies across different devices.
### Disabling Transitions
@@ -732,6 +753,11 @@ The **Navigation** component provides default transition animations for switchin
For details about the sample code, see [Example 2: Setting a Custom Transitions for the NavDestination Component](../reference/apis-arkui/arkui-ts/ts-basic-components-navdestination.md#example-2-setting-a-custom-transitions-for-the-navdestination-component).
- How to Use
1. [customNavContentTransition](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#customnavcontenttransition11) controls all pages within the **Navigation** component and provides unified transition animation effects.
2. [customTransition](../reference/apis-arkui/arkui-ts/ts-basic-components-navdestination.md#customtransition15) controls the transition effect for individual pages.
3. When both [customNavContentTransition](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#customnavcontenttransition11) and [customTransition](../reference/apis-arkui/arkui-ts/ts-basic-components-navdestination.md#customtransition15) are used, **customNavContentTransition** takes precedence.
### Defining a Shared Element Transition
You can implement shared element transitions between navigation destination pages using [geometryTransition](../reference/apis-arkui/arkui-ts/ts-transition-animation-geometrytransition.md#geometrytransition). Ensure that the default transition animations are disabled for pages configured with shared element transitions.
@@ -742,6 +768,7 @@ You can implement shared element transitions between navigation destination page
NavDestination() {
Column() {
// ...
// Replace $r('app.media.startIcon') with the resource file you use.
Image($r('app.media.startIcon'))
.geometryTransition('sharedId')
.width(100)
@@ -754,6 +781,7 @@ You can implement shared element transitions between navigation destination page
NavDestination() {
Column() {
// ...
// Replace $r('app.media.startIcon') with the resource file you use.
Image($r('app.media.startIcon'))
.geometryTransition('sharedId')
.width(200)
@@ -782,19 +810,9 @@ You can implement shared element transitions between navigation destination page
.title('FromPage')
```
## Cross-Package Dynamic Routing
Using static imports for page routing can lead to coupling between different modules and prolonged home page loading times.
## Cross-Package Routing
The purpose of dynamic routing is to allow multiple modules (HARs/HSPs) to reuse the same business logic, with decoupling between different modules and integration of routing functionality.
**Advantages of dynamic routing**
- In addition to the URL for navigation, you can configure various information, such as the default orientation (landscape or portrait) and whether authentication is required. The configuration is processed in a unified manner during routing
- You can assign a name to each routing page and navigate by name instead of file path.
- Dynamic imports (on-demand loading) can be used to load pages to prevent the first page from loading a large amount of code, which can cause stuttering.
Dynamic routing provides two modes: [System Routing Table](#system-routing-table) and [Custom Routing Table](#custom-routing-table).
The system provides two implementation modes: [system routing table](#system-routing-table) and [custom routing table](#custom-routing-table).
- The system routing table is easier to use than the custom routing table. It only requires adding the corresponding page navigation configuration items to implement page navigation.
| [System routing table](#system-routing-table) | No need to import page files before redirection; pages are dynamically loaded on demand| Moderate| High; the system automatically maintains the routing table |
| [Custom routing table](#custom-routing-table)| Page files must be imported before redirection| High| Moderate; you must maintain the routing table manually|
### System Routing Table
The system routing table is an implementation of dynamic routing. **Navigation** supports the system routing table for dynamic routing since API version 12. Each service module ([HSP](../quick-start/in-app-hsp.md) or [HAR](../quick-start/har-package.md)) requires an individual **route_map.json** file. When routing is triggered, the application only needs to pass the name of the page that needs to be routed through the routing API provided by **NavPathStack**. The system then automatically completes the dynamic loading of the target module, page component construction, and route redirection. This way, module decoupling is achieved at the development level. The system routing table supports the Emulator but not the Previewer. The main steps are as follows:
@@ -884,9 +911,24 @@ The system routing table is an implementation of dynamic routing. **Navigation**
### Custom Routing Table
The custom routing table is also an implementation of dynamic routing. You can implement cross-package dynamic routing through a <!--RP1-->[custom routing table](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/ApplicationModels/DynamicRouter)<!--RP1End-->.
A custom routing table is implemented by configuring the Builder function for the [navDestination](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navdestination10) attribute of **Navigation**. This approach requires importing page modules, which can be done through either static or dynamic import. The differences between these two methods are as follows.
| Dynamic import| Low coupling between modules| High| Excellent; pages are loaded on demand, with target pages loaded just before navigation|
| Static import| High coupling between modules| Low| Average; all dependent pages are loaded during initialization|
**Dynamic Import (Recommended)**
**Implementation:**
Dynamic import enables reuse of service logic across multiple modules (HAR/HSP) to achieve service module decoupling. In addition, it supports route function extension and integration while allowing on-demand loading. For implementation details, see <!--RP1-->the [dynamic route example](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/ApplicationModels/DynamicRouter)<!--RP1End-->.
Dynamic import offers the following advantages:
- Beyond the navigation URL, you can configure extended information in route definitions, such as the default orientation (landscape or portrait) and authentication requirements, which is processed during route navigation.
- You can assign a name to each routing page and navigate by name instead of file path.
- Dynamic imports (on-demand loading) can be used to load pages to prevent the first page from loading a large amount of code, which can cause stuttering.
Implementation solution:
1. Define page navigation configuration items.
- Use resource files for definitions and use the [@ohos.resourceManager](../reference/apis-localization-kit/js-apis-resource-manager.md) module to parse the resource files at runtime.
@@ -894,6 +936,108 @@ The custom routing table is also an implementation of dynamic routing. You can i
2. Use [dynamic import](../arkts-utils/arkts-dynamic-import.md) to load the module containing the target page at runtime. Once the module is loaded, call a method within the module that uses **import** to load and display the target page, then return the **Builder** function defined after the page has finished loading.
3. Execute the **Builder** function loaded in step 2 on the [navDestination](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navdestination10) attribute of the **Navigation** component to navigate to the target page.
**Static Import**
Static import is straightforward to implement. However, using static imports for routing navigation creates dependency coupling between modules and increases the initial page loading time. Whenever possible, use either dynamic imports with a [custom routing table](#custom-routing-table) or the [system routing table](#system-routing-table) instead.
Implementation solution:
``` TypeScript
import { hilog } from '@kit.PerformanceAnalysisKit';
const DOMAIN = 0x0000;
@Entry
@Component
struct NavigationExample {
@Provide('navPathStack') navPathStack: NavPathStack = new NavPathStack();
this.pathInfos.pushPathByName(`${item}`, 'Details page parameters'); // Push the navigation destination page specified by name, with the data specified by param, to the routing stack.
this.navPathStack.pushPathByName(`${item}`, 'Details page parameters'); // Push the navigation destination page specified by name, with the data specified by param, to the navigation stack.
Page routing refers to the redirection and data transfer between different pages in an application. It can be implemented through APIs of the **Router** module. Through different URLs, you can easily navigate users through pages. This document outlines the key features of the **Router** module, including: [Page Redirection](#page-redirection), [Page Return](#page-return), [Adding a Confirmation Dialog Box Before Page Return](#adding-a-confirmation-dialog-box-before-page-return), and [Named Route](#named-route).
@@ -15,23 +15,23 @@ Page routing refers to the redirection and data transfer between different pages
## Page Redirection
Page redirection is an important part of the development process. When using an application, you usually need to jump between different pages, and sometimes you need to pass data from one page to another.
Page redirection is a fundamental part of development. Users often need to move between different pages within an application, and sometimes data must be passed from one page to another.
The Router module provides two redirection modes: [pushUrl](../reference/apis-arkui/arkts-apis-uicontext-router.md#pushurl) and [replaceUrl](../reference/apis-arkui/arkts-apis-uicontext-router.md#replaceurl). Whether the target page will replace the current page depends on the mode used.
The **Router** module provides two redirection modes: [pushUrl](../reference/apis-arkui/arkts-apis-uicontext-router.md#pushurl) and [replaceUrl](../reference/apis-arkui/arkts-apis-uicontext-router.md#replaceurl). Whether the target page will replace the current page depends on the mode used.
- pushUrl: The target page is not replaced with the current page. Instead, the target page is pushed to the page stack. In this way, the status of the current page can be retained, and the current page can be returned by pressing the back button or calling the [back](../reference/apis-arkui/arkts-apis-uicontext-router.md#back) method.
- **pushUrl**: The target page does not replace the current page. Instead, it is pushed onto the page stack. In this mode, the state of the current page is retained, and users can return to the current page by pressing the back button or calling the [back](../reference/apis-arkui/arkts-apis-uicontext-router.md#back) API.
- replaceUrl: The target page replaces the current page and destroys the current page. In this mode, the resources of the current page can be released, and users cannot return to the current page.
- **replaceUrl**: The target page replaces the current page, and the current page is destroyed. In this mode, the resources of the current page are released, and users cannot return to the current page.
>**NOTE**
>
>- When creating a page, configure the route to this page by following instructions in <!--RP1-->[Building the Second Page](../quick-start/start-with-ets-stage.md#building-the-second-page)<!--RP1End-->.
>
>
>- The maximum capacity of a page stack is 32 pages. If the number of pages exceeds the limit, you can call the [clear](../reference/apis-arkui/arkts-apis-uicontext-router.md#clear) method to clear the historical page stack and release the memory space.
>- The maximum capacity of a page stack is 32 pages. If this limit is exceeded, the [clear](../reference/apis-arkui/arkts-apis-uicontext-router.md#clear) API can be called to clear the historical page stack and free the memory.
The **Router** module also provides two instance modes: **Standard** and **Single**. Depending on the mode, the target URL is mapped to one or more instances.
@@ -42,17 +42,26 @@ The **Router** module also provides two instance modes: **Standard** and **Singl
- Scenario 1: There is a home page (**Home**) and a details page (**Detail**). You want to click an offering on the home page to go to the details page. In addition, the home page needs to be retained in the page stack so that the status can be restored when the page is returned. In this scenario, you can use the **pushUrl** API and use the **Standard** instance mode (which can also be omitted).
```ts
// On the Home page
onJumpClick(): void {
this.getUIContext().getRouter().pushUrl({
url: 'pages/Detail' // Target URL.
}, router.RouterMode.Standard, (err) => {
if (err) {
console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);
return;
}
console.info('Invoke pushUrl succeeded.');
});
import { router } from '@kit.ArkUI';
@Entry
@Component
struct Index {
// On the Home page
onJumpClick(): void {
this.getUIContext().getRouter().pushUrl({
url: 'pages/Detail' // Target URL.
}, router.RouterMode.Standard, (err) => {
if (err) {
console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);
return;
}
console.info('Invoke pushUrl succeeded.');
});
}
build() {
}
}
```
@@ -63,17 +72,26 @@ The **Router** module also provides two instance modes: **Standard** and **Singl
- Scenario 2: There is a login page (**Login**) and a personal center page (**Profile**). After a user successfully logs in from the **Login** page, the **Profile** page is displayed. At the same time, the **Login** page is destroyed, and the application exits when the back button is pressed. In this scenario, you can use the **replaceUrl** API and use the Standard instance mode (which can also be omitted).
```ts
// On the Login page
onJumpClick(): void {
this.getUIContext().getRouter().replaceUrl({
url: 'pages/Profile' // Target URL.
}, router.RouterMode.Standard, (err) => {
if (err) {
console.error(`Invoke replaceUrl failed, code is ${err.code}, message is ${err.message}`);
return;
}
console.info('Invoke replaceUrl succeeded.');
})
import { router } from '@kit.ArkUI';
@Entry
@Component
struct Index {
// On the Login page
onJumpClick(): void {
this.getUIContext().getRouter().replaceUrl({
url: 'pages/Profile' // Target URL.
}, router.RouterMode.Standard, (err) => {
if (err) {
console.error(`Invoke replaceUrl failed, code is ${err.code}, message is ${err.message}`);
return;
}
console.info('Invoke replaceUrl succeeded.');
})
}
build() {
}
}
```
@@ -84,34 +102,52 @@ The **Router** module also provides two instance modes: **Standard** and **Singl
- Scenario 3: There is a **Setting** page and a **Theme** page. After a theme option on the **Setting** page is clicked, the **Theme** page is displayed. Only one **Theme** page exists in the page stack at the same time. When the back button is clicked on the **Theme** page, the **Setting** page is displayed. In this scenario, you can use the **pushUrl** API and use the **Single** instance mode.
```ts
// On the Setting page
onJumpClick(): void {
this.getUIContext().getRouter().pushUrl({
url: 'pages/Theme' // Target URL.
}, router.RouterMode.Single, (err) => {
if (err) {
console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);
return;
}
console.info('Invoke pushUrl succeeded.');
});
import { router } from '@kit.ArkUI';
@Entry
@Component
struct Index {
// On the Setting page
onJumpClick(): void {
this.getUIContext().getRouter().pushUrl({
url: 'pages/Theme' // Target URL.
}, router.RouterMode.Single, (err) => {
if (err) {
console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);
return;
}
console.info('Invoke pushUrl succeeded.');
});
}
build() {
}
}
```
- Scenario 4: There is a search result list page (**SearchResult**) and a search result details page (**SearchDetail**). You want to click a result on the **SearchResult** page to go to the **SearchDetail** page. In addition, if the result has been viewed before, clicking the result displays the existing details page, instead of creating a new one. In this scenario, you can use the **replaceUrl** API and use the **Single** instance mode.
```ts
// On the SearchResult page
onJumpClick(): void {
this.getUIContext().getRouter().replaceUrl({
url: 'pages/SearchDetail' // Target URL.
}, router.RouterMode.Single, (err) => {
if (err) {
console.error(`Invoke replaceUrl failed, code is ${err.code}, message is ${err.message}`);
return;
}
console.info('Invoke replaceUrl succeeded.');
})
import { router } from '@kit.ArkUI';
@Entry
@Component
struct Index {
// On the SearchResult page
onJumpClick(): void {
this.getUIContext().getRouter().replaceUrl({
url: 'pages/SearchDetail' // Target URL.
}, router.RouterMode.Single, (err) => {
if (err) {
console.error(`Invoke replaceUrl failed, code is ${err.code}, message is ${err.message}`);
return;
}
console.info('Invoke replaceUrl succeeded.');
})
}
build() {
}
}
```
@@ -152,7 +188,7 @@ onJumpClick(): void {
}
```
On the target page, you can call the [getParams](../reference/apis-arkui/arkts-apis-uicontext-router.md#getparams) method of the Router module to obtain the passed parameters. Example:
On the target page, you can call the [getParams](../reference/apis-arkui/arkts-apis-uicontext-router.md#getparams) API of the **Router** module to obtain the passed parameters. Example:
```ts
@@ -208,7 +244,7 @@ You can use any of the following methods to return to a page:
```ts
this.getUIContext().getRouter().back({
url: 'myPage' // myPage is the returned alias of the naming route page.
url: 'myPage' // myPage is the alias of the page to return to.
});
```
@@ -232,16 +268,16 @@ You can use any of the following methods to return to a page:
```ts
this.getUIContext().getRouter().back({
url: 'yPage', // myPage is the alias of the named route page to be returned.
url: 'myPage', // myPage is the alias of the page to return to.
params: {
info: 'From Home Page'
}
});
```
This method not only allows you to return to the specified page, but also pass in custom parameter information during the return process. You can call the [getParams](../reference/apis-arkui/arkts-apis-uicontext-router.md#getparams) method on the target page to obtain and parse the parameters.
This method not only lets you return to the specified page, but also allows custom parameters to be passed during the return. On the target page, you can call the [getParams](../reference/apis-arkui/arkts-apis-uicontext-router.md#getparams) method to obtain and parse these parameters.
On the target page, call the [getParams](../reference/apis-arkui/arkts-apis-uicontext-router.md#getparams) method where parameters need to be obtained, for example, in the [onPageShow](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md#onpageshow) lifecycle callback.
On the target page, call [getParams](../reference/apis-arkui/arkts-apis-uicontext-router.md#getparams) where the parameters are needed, for example, in the [onPageShow](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md#onpageshow) lifecycle callback.
> **NOTE**
>
@@ -266,39 +302,39 @@ struct Home {
>**NOTE**
>
>When the back method is used to return to a specified page, all pages from the original top page (included) to the specified page (excluded) are popped out of the stack and destroyed.
>When the **back** API is used to return to a specified page, all pages between the top page (included) and the specified page (excluded) are pushed from the page stack and destroyed.
>
> In addition, if the back method is used to return to the original page, the original page is not created repeatedly. Therefore, variables declared using \@State are not declared repeatedly, and the aboutToAppear lifecycle callback of the page is not triggered. If you want to use the custom parameters transferred from the returned page on the original page, you can parse the parameters in the required position. For example, parameter parsing can be performed in the **onPageShow** lifecycle callback.
> If the **back** API is used to return to the original page, the original page will not be created repeatedly. Therefore, the variable declared using \@State will not be declared repeatedly, and the **aboutToAppear** lifecycle callback of the page will not be triggered. If you want to use the custom parameters transferred from the returned page on the original page, you can parse the parameters in the required position. For example, parameter parsing can be performed in the **onPageShow** lifecycle callback.
## Lifecycle
[\@Entry](state-management/arkts-create-custom-components.md#entry)-decorated component lifecycle. The following lifecycle APIs are provided:
The [router](../reference/apis-arkui/js-apis-router.md) page lifecycle refers to the lifecycle of components decorated with [\@Entry](state-management/arkts-create-custom-components.md#entry). The following lifecycle callbacks are provided:
- [onPageShow](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md#onpageshow): Invoked each time the page is displayed, for example, during page redirection or when the application is switched to the foreground.
- [onPageHide](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md#onpagehide): Invoked each time the page is hidden, for example, during page redirection or when the application is switched to the background.
- [onBackPress](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md#onbackpress): Invoked when the user clicks the **Back** button.
- [onBackPress](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md#onbackpress): Invoked when the user clicks the back button.
```ts
// Index.ets
@Entry
@Component
struct MyComponent {
// Only components decorated by @Entry can call the lifecycle callbacks of a page.
// Only components decorated with @Entry can call the lifecycle callbacks of a page.
onPageShow() {
console.info('Index onPageShow');
}
// Only components decorated by @Entry can call the lifecycle callbacks of a page.
// Only components decorated with @Entry can call the lifecycle callbacks of a page.
onPageHide() {
console.info('Index onPageHide');
}
// Only components decorated by @Entry can call the lifecycle callbacks of a page.
// Only components decorated with @Entry can call the lifecycle callbacks of a page.
onBackPress() {
console.info('Index onBackPress');
// If true is returned, the page processes the return logic and does not perform page routing. If false is returned, the default return logic is used. If no return value is set, false is used.
// The value true means that the page executes its own return logic, and false (default) means that the default return logic is used.
return true;
}
@@ -321,18 +357,18 @@ struct Page {
@State textColor: Color = Color.Black;
@State num: number = 0;
// Only components decorated by @Entry can call the lifecycle callbacks of a page.
// Only components decorated with @Entry can call the lifecycle callbacks of a page.
onPageShow() {
console.info('Page onPageShow');
this.num = 5;
}
// Only components decorated by @Entry can call the lifecycle callbacks of a page.
// Only components decorated with @Entry can call the lifecycle callbacks of a page.
onPageHide() {
console.info('Page onPageHide');
}
// Only components decorated by @Entry can call the lifecycle callbacks of a page.
// Only components decorated with @Entry can call the lifecycle callbacks of a page.
onBackPress() { // If the value is not set, false is used.
[pageTransition](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md#pagetransition9) can be used to customize the transition of router. For details, see [Page Transition (pageTransition)](../reference/apis-arkui/arkui-ts/ts-page-transition-animation.md).
[pageTransition](../reference/apis-arkui/arkui-ts/ts-custom-component-lifecycle.md#pagetransition9) can be used to customize router page transitions. For details, see [Page Transition (pageTransition)](../reference/apis-arkui/arkui-ts/ts-page-transition-animation.md).
## Adding a Confirmation Dialog Box Before Page Return
@@ -377,11 +413,11 @@ Such a dialog box can be in the [default style](#default-confirmation-dialog-box
### Default Confirmation Dialog Box
You can use the [showAlertBeforeBackPage](../reference/apis-arkui/arkts-apis-uicontext-router.md#showalertbeforebackpage) and [back](../reference/apis-arkui/arkts-apis-uicontext-router.md#back) methods provided by the router module to implement this function.
To implement this feature, you can use the showAlertBeforeBackPage](../reference/apis-arkui/arkts-apis-uicontext-router.md#showalertbeforebackpage) and [back](../reference/apis-arkui/arkts-apis-uicontext-router.md#back) APIs provided by the **Router** module.
Directly using **router** can lead to the issue of [ambiguous UI context](./arkts-global-interface.md#ambiguous-ui-context). To avoid this, obtain a [UIContext](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md) instance using the **getUIContext()** API, and then obtain the **router** object bound to that instance through the [getRouter](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#getrouter) API.
If you want to display a confirmation dialog box on the target page, you need to call the [showAlertBeforeBackPage](../reference/apis-arkui/arkts-apis-uicontext-router.md#showalertbeforebackpage) method to set the information about the confirmation dialog box before calling the [back](../reference/apis-arkui/arkts-apis-uicontext-router.md#back) method. For example, define a click event processing function for the back button on the payment page:
To enable the confirmation dialog box for page return, call the [showAlertBeforeBackPage](../reference/apis-arkui/arkts-apis-uicontext-router.md#showalertbeforebackpage) API (for setting the information about the dialog box), then the [back](../reference/apis-arkui/arkts-apis-uicontext-router.md#back) API. For example, define a click event processing function for the back button on the payment page:
```ts
import { BusinessError } from '@kit.BasicServicesKit';
@@ -404,20 +440,20 @@ function onBackClick(): void {
}
```
The this.getUIContext().getRouter().showAlertBeforeBackPage method receives an object as a parameter. The object contains the following attributes:
The **this.getUIContext().getRouter().showAlertBeforeBackPage** API receives an object as a parameter. The object contains the following attributes:
**message**: content of the dialog box. The value is of the string type.
If the API is called successfully, the confirmation dialog box is displayed on the target page. Otherwise, an exception is thrown and the error code and error information is obtained through **err.code** and **err.message**.
When the user clicks the back button, a confirmation dialog box is displayed, prompting the user to confirm their operation. If you tap Cancel, the current page is displayed. If you tap OK, the [back](../reference/apis-arkui/arkts-apis-uicontext-router.md#back) method is triggered, and the jump is determined based on the parameter.
When the user clicks the back button, a confirmation dialog box is displayed, prompting the user to confirm their operation. If the user selects **Cancel**, the application stays on the current page. If the user selects **OK**, the [back](../reference/apis-arkui/arkts-apis-uicontext-router.md#back) API is called and the redirection is performed based on the parameters.
### Custom Confirmation Dialog Box
You can customize a dialog box by using the [showDialog](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#showdialog-1) or custom pop-up window. . This topic uses the APIs in the **PromptAction** module an example to describe how to implement a custom confirmation dialog box.
To implement a custom confirmation dialog box, use [showDialog](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#showdialog-1) or create a custom dialog box . This topic uses the APIs in the **PromptAction** module an example to describe how to implement a custom confirmation dialog box.
Directly using **router** can lead to the issue of [ambiguous UI context](./arkts-global-interface.md). To avoid this, obtain a [UIContext](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md) instance using the **getUIContext()** API, and then obtain the **router** object bound to that instance through the [getRouter](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#getrouter) API.
In the event callback, call the [showDialog](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#showdialog-1) method of the pop-up window.
In the event callback, call the [showDialog](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#showdialog-1) API.
```ts
import { promptAction} from '@kit.ArkUI';
@@ -455,24 +491,17 @@ onBackClick() {
}
```
When the user clicks the back button, the custom confirmation dialog box is displayed, prompting the user to confirm their operation. If the user taps Cancel, the user stays on the current page. If the user taps OK, the [back](../reference/apis-arkui/arkts-apis-uicontext-router.md#back) method is triggered, and the redirection is determined based on the parameters.
When the user clicks the back button, the custom confirmation dialog box is displayed, prompting the user to confirm their operation. If the user selects **Cancel**, the application stays on the current page. If the user selects **OK**, the [back](../reference/apis-arkui/arkts-apis-uicontext-router.md#back) API is called and the redirection is performed based on the parameters.
## Named Route
You can use [pushNamedRoute](../reference/apis-arkui/arkts-apis-uicontext-router.md#pushnamedroute) to redirect to a page in a shared package [HAR](../quick-start/har-package.md) or [HSP](../quick-start/in-app-hsp.md).
To redirect to a page in a [HAR](../quick-start/har-package.md) or [HSP](../quick-start/in-app-hsp.md), you can use [pushNamedRoute](../reference/apis-arkui/arkts-apis-uicontext-router.md#pushnamedroute).
Before using the **Router** module, import it first.
```ts
import { router } from '@kit.ArkUI';
```
In the shared package [HAR](../quick-start/har-package.md) or [HSP](../quick-start/in-app-hsp.md) page to which you want to redirect, name the custom component EntryOptions decorated with [@Entry](../ui/state-management/arkts-create-custom-components.md#entry).
In the target[HAR](../quick-start/har-package.md) or [HSP](../quick-start/in-app-hsp.md), name the [@Entry](../ui/state-management/arkts-create-custom-components.md#entry) decorated custom component in **EntryOptions**.
```ts
// library/src/main/ets/pages/Index.ets
@@ -502,14 +531,14 @@ When the configuration is successful, import the named route page to the page fr
>
>```ts
>"dependencies": {
> "@ohos/library": "file:../library",
> "library": "file:../library",
> // ...
> }
>```
```ts
import { BusinessError } from '@kit.BasicServicesKit';
import '@ohos/library/src/main/ets/pages/Index'; // Import the named route page from the library of the shared package.
import 'library/src/main/ets/pages/Index'; // Import the named route page from the library of the shared package.
A semi-modal page, implemented using [bindSheet](../reference/apis-arkui/arkui-ts/ts-universal-attributes-sheet-transition.md#bindsheet), is a modal, non-full-screen popup interaction page by default, allowing parts of the underlying parent view to be visible. This helps users retain the context of their parent view while interacting with the semi-modal.
A modal sheet, implemented using [bindSheet](../reference/apis-arkui/arkui-ts/ts-universal-attributes-sheet-transition.md#bindsheet), is a modal, non-full-screen popup interaction page by default, allowing parts of the underlying parent view to be visible. This helps users retain the context of their parent view while interacting with the sheet.
Semi-modal pages are suitable for displaying simple tasks or information panels, such as personal information, text introductions, sharing panels, creating schedules, and adding content. If a semi-modal page needs to be displayed in a way that could potentially affect the parent view, it can be configured to use a non-modal interaction form.
Modal sheets are suitable for displaying simple tasks or information panels, such as personal information, text introductions, sharing panels, creating schedules, and adding content. If a sheet needs to be displayed in a way that could potentially affect the parent view, it can be configured to use a non-modal interaction form.
Semi-modal pages have different form capabilities on devices of different widths. For details about the form requirements on devices with different widths, see the [preferType](../reference/apis-arkui/arkui-ts/ts-universal-attributes-sheet-transition.md#sheetoptions) property. You can use **bindSheet** to build semi-modal transition effects. For details, see [Modal Transition](arkts-modal-transition.md#creating-sheet-transition-with-bindsheet). For complex or lengthy user processes, consider other transition methods instead of semi-modals, such as [full-modal transition](arkts-contentcover-page.md) and [navigation transition](arkts-navigation-navigation.md).
Modal sheets have different form capabilities on devices of different widths. For details about the form requirements on devices with different widths, see the [preferType](../reference/apis-arkui/arkui-ts/ts-universal-attributes-sheet-transition.md#sheetoptions) property. You can use **bindSheet** to build modal sheet transition effects. For details, see [Modal Transition](arkts-modal-transition.md#creating-sheet-transition-with-bindsheet). For complex or lengthy user processes, consider other transition methods instead of modal sheets, such as [full-modal transition](arkts-contentcover-page.md) and [navigation transition](arkts-navigation-navigation.md).
## Constraints
- When a [UIExtension](../reference/apis-arkui/js-apis-arkui-uiExtension.md) is embedded in a semi-modal, launching another semi-modal or popup window within the UIExtension is not allowed.
- When a [UIExtension](../reference/apis-arkui/js-apis-arkui-uiExtension.md) is embedded in a modal sheet, launching another modal sheet or popup window within the UIExtension is not allowed.
- In scenarios without secondary confirmation or custom close behavior, avoid using the [shouldDismiss/onWillDismiss](../reference/apis-arkui/arkui-ts/ts-universal-attributes-sheet-transition.md#sheetoptions) API.
## Lifecycle
The semi-modal page provides lifecycle callbacks to notify the application of the lifecycle status of the popup. These callbacks are triggered in the following order: onWillAppear -> onAppear -> onWillDisappear -> onDisappear.
The modal sheet provides lifecycle callbacks to notify the application of its lifecycle status. These callbacks are triggered in the following order: onWillAppear -> onAppear -> onWillDisappear -> onDisappear.
| onWillAppear | () => void | Callback for when the semi-modal page is about to appear (before the animation starts).|
| onAppear | () => void | Callback for when the semi-modal page appears (after the animation ends). |
| onWillDisappear | () => void | Callback for when the semi-modal page is about to disappear (before the animation starts).|
| onDisappear |() => void | Callback for when the semi-modal page disappears (after the animation ends). |
| onWillAppear | () => void | Callback for when the modal sheet is about to appear (before the animation starts).|
| onAppear | () => void | Callback for when the modal sheet appears (after the animation ends). |
| onWillDisappear | () => void | Callback for when the modal sheet is about to disappear (before the animation starts).|
| onDisappear |() => void | Callback for when the modal sheet disappears (after the animation ends). |
## Using Nested Scrolling
The priority of operations during scrolling in the content area of a semi-modal panel is as follows:
The priority of operations during scrolling in the content area of a modal sheet is as follows:
1. 1. Content at the top and content that cannot be scrolled
Swiping up: The sheet will attempt to expand upwards. If no expansion is possible, the content will scroll.
Swiping up: The modal sheet will attempt to expand upwards. If no expansion is possible, the content will scroll.
Swiping down: The panel will attempt to contract downwards. If no contraction is possible, the panel will close.
Swiping down: The modal sheet will attempt to contract downwards. If no contraction is possible, the panel will close.
2. 2. Content in the middle (scrollable both up and down)
Swiping up or down: The content will scroll until it reaches the top or bottom of the panel.
@@ -44,7 +50,7 @@ The priority of operations during scrolling in the content area of a semi-modal
By default, the nested scrolling mode for the half-modal panel is as follows: {Forward: PARENT\_FIRST, Backward: SELF\_FIRST}
If you want to define a scrollable container, such as **List** or **Scroll**, in the panel content builder, and combine it with the semi-modal's interaction capabilities, you must set the nested scrolling attributes for the scrollable container in the vertical direction.
If you want to define a scrollable container, such as **List** or **Scroll**, in the panel content builder, and combine it with the modal sheet's interaction capabilities, you must set the nested scrolling attributes for the scrollable container in the vertical direction.
```ts
.nestedScroll({
@@ -111,55 +117,85 @@ struct SheetDemo {
}
```

## Secondary Confirmation Capability
To implement the secondary confirmation capability, you are advised to use the **onWillDismiss** API, with which you can handle secondary confirmation or custom close behavior in the callback.
> **NOTE**
>
> After the **onWillDismiss** API is declared, all close operations of the semi-modal page, including side swiping, touching the close button, touching the mask, and pulling down, must be implemented by calling the **dismiss** API. If this logic is not implemented, the semi-modal page will not respond to the above close operations.
> After the **onWillDismiss** API is declared, all dismiss operations of the modal sheet, including side swiping, touching the close button, touching the mask, and pulling down, must be implemented by calling the **dismiss** API. If this logic is not implemented, the modal sheet will not respond to the above dismiss operations.
// Step 2: Implement the secondary confirmation interaction, using an AlertDialog component to prompt the user for confirmation.
this.getUIContext().showAlertDialog(
{
message: 'Do you want to close the sheet?',
autoCancel: true,
alignment: DialogAlignment.Bottom,
gridCount: 4,
offset: { dx: 0, dy: -20 },
primaryButton: {
value: 'Cancel',
action: () => {
console.info('Callback when the cancel button is clicked');
}
},
secondaryButton: {
enabled: true,
defaultFocus: true,
style: DialogButtonStyle.HIGHLIGHT,
value: 'Close',
// Step 3: Define the logic for closing the modal sheet within the AlertDialog button callback.
action: () => {
// Step 4: Call dismiss() to close the modal sheet when the logic in step 3 is triggered.
DismissSheetAction.dismiss();
console.info('Callback when the ok button is clicked');
}
},
cancel: () => {
console.info('AlertDialog Closed callbacks');
}
}
)
})
})
}
}
```

## Blocking Specific Dismiss Behavior
After the **onWillDismiss** API is declared, it takes control over all dismiss behaviors of the semi-modal. This means that the semi-modal can be dismissed only when you explicitly call the **dismiss** API. You can customize the dismissal logic using **if** statements or other logic.
For example, you might want the semi-modal to be dismissed only when the user swipes down. Here's how you can implement this:
After the **onWillDismiss** API is declared, it takes control over all dismiss behaviors of the modal sheet. This means that the modal sheet can be dismissed only when you explicitly call the **dismiss** API. You can customize the dismissal logic using **if** statements or other logic.
For example, you might want the modal sheet to be dismissed only when the user swipes down. Here's how you can implement this:
To enhance the user experience during the swiping down action, you can use the **onWillSpringBackWhenDismiss** API.
Just like with **onWillDismiss**, after **onWillSpringBackWhenDismiss** is declared, the rebound operation during a swipe-down of the half-modal requires handling with **SpringBackAction.springBack()**; without this logic, no rebound will occur.
Here is the specific code to prevent the rebound effect when the semi-modal is swiped down:
Here is the specific code to prevent the rebound effect when the modal sheet is swiped down:
// No springBack is registered, so the half-modal will not bounce back when swiped down.
// No springBack is registered, so the modal sheet will not bounce back when swiped down.
}),
```
## Implementing Center Axis Avoidance
Center axis avoidance is supported for modal sheets since API version 14. This capability is enabled by default on 2-in-1 devices (avoidance behavior is triggered only when the window is in waterfall mode), with the default avoidance area set to the upper half of the screen. You can actively configure whether to enable center axis avoidance using the **enableHoverMode** property in [SheetOptions](../reference/apis-arkui/arkui-ts/ts-universal-attributes-sheet-transition.md#sheetoptions), and specify the display area after avoidance using the **hoverModeArea** property.
- Center axis avoidance for modal sheets does not support the subwindow capability. This restriction applies to scenarios where **showInSubWindow** in [SheetOptions](../reference/apis-arkui/arkui-ts/ts-universal-attributes-sheet-transition.md#sheetoptions) is set to **true**.
- On 2-in-1 devices, center axis avoidance occurs only when the window is in waterfall mode.
Powered by the ArkTS-based declarative development paradigm, ArkUI is a simplified, high-performance UI development framework for cross-device applications. It provides the capabilities required for building the application UI, including:
- **ArkTS**
ArkTS is the preferred programming language for application development. As a superset of [TypeScript](https://www.typescriptlang.org/) (TS for short), it contains all TS features and added features, including declarative UI description, custom components, dynamic UI element extension, state management, and rendering control. State management in ArkTS provides clear page re-render processes and pipes through decorators with different functions. It covers UI component states and application states, allowing for a comprehensive data update and UI rendering mechanism across the application. To learn more about ArkTS, see [Getting Started with ArkTS](../quick-start/arkts-get-started.md).
ArkTS is the preferred programming language for application development. Extending the [TypeScript](https://www.typescriptlang.org/) ecosystem, ArkTS enhances it with capabilities tailored for application development, including declarative UI description, custom components, dynamic UI element extension, state management, and rendering control. State management in ArkTS provides clear page re-render processes and pipes through decorators with different functions. It covers UI component states and application states, allowing for a comprehensive data update and UI rendering mechanism across the application. To learn more about ArkTS, see [Getting Started with ArkTS](../quick-start/arkts-get-started.md).
- **Layout**
Layout defines how components are laid out in the UI. ArkUI offers a diverse array of layouts. Besides the basic layouts, such as linear, stack, flex, and relative, you also have access to the advanced layouts, including list, grid, and swiper, for more complex UI design needs.
Layout defines how components are laid out in the UI. ArkUI offers a diverse array of layout options. Besides the basic layouts, such as linear, stack, flex, and relative, advanced layouts including list, grid, and swiper are available for more complex UI design requirements.
- **Component**
@@ -53,7 +53,7 @@ Powered by the ArkTS-based declarative development paradigm, ArkUI is a simplifi
- Language compiler and runtime optimization: The productivity punch includes unified bytecode, efficient Foreign Function Interface (FFI), ahead-of-time (AOT), engine minimization, and type optimization.
- Promising ecosystem
ArkUI can gain traction with its relatively neutral and friendly programming language. It can tap on the ecosystems of mainstream languages and pushed toward a steady revolutionary path with standards organizations.
ArkUI can gain traction with its relatively neutral and developer-friendly programming language. It can tap on the ecosystems of mainstream languages and advance along an evolutionary path with standards organizations.
## Architecture
@@ -66,7 +66,7 @@ Powered by the ArkTS-based declarative development paradigm, ArkUI is a simplifi
- **Declarative UI frontend**
Provides basic language specifications of the UI development paradigm, built-in UI components, layouts, and animations, and multiple state management mechanisms, with a wide array of APIs for you to call as required.
Provides basic language specifications of the UI development paradigm, built-in UI components, layout, and animations, and multiple state management mechanisms, with a wide array of APIs for you to call as required.
- **Language runtime**
Provides the parsing capability for the UI paradigm syntax and allows for cross-language API calls for a high-performance operating environment of the TS language.
# Global Custom Dialog Box Independent of UI Components (openCustomDialog) (Recommended)
# Global Custom Dialog Box Independent of UI Components (openCustomDialog)
<!--Kit: ArkUI-->
<!--Subsystem: ArkUI-->
<!--Owner: @houguobiao-->
@@ -6,7 +6,7 @@
<!--Tester: @lxl007-->
<!--Adviser: @Brilliantry_Rui-->
For complex application scenarios, use the [openCustomDialog](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#opencustomdialog12) API from the **PromptAction** object obtained through UIContext to implement custom dialog boxes. Compared with [CustomDialogController](../reference/apis-arkui/arkui-ts/ts-methods-custom-dialog-box.md#customdialogcontroller), this approach offers better page decoupling and supports [dynamic updates](../reference/apis-arkui/js-apis-arkui-ComponentContent.md#update).
In scenarios that require user interaction responses such as advertisements, prize notifications, warnings, and software updates, you can use the [openCustomDialog](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#opencustomdialog12) API provided by the **PromptAction** object obtained from **UIContext** to implement custom dialog boxes. Compared with [CustomDialogController](../reference/apis-arkui/arkui-ts/ts-methods-custom-dialog-box.md#customdialogcontroller), its advantages include decoupling from pages and support for [dynamic updates](../reference/apis-arkui/js-apis-arkui-ComponentContent.md#update).
> **NOTE**
>
@@ -26,8 +26,8 @@ The dialog box provides lifecycle functions to notify users of its lifecycle eve
| CommonAttribute | [animation](../reference/apis-arkui/arkui-ts/ts-animatorproperty.md#animation) | Method not implemented. | Animation attributes are not supported. |
| CommonAttribute | [attributeModifier](../reference/apis-arkui/arkui-ts/ts-universal-attributes-attribute-modifier.md#attributemodifiert) | - | **attributeModifier** does not take effect when nested.|
| CommonAttribute | [attributeModifier](../reference/apis-arkui/arkui-ts/ts-universal-attributes-attribute-modifier.md#attributemodifier) | - | **attributeModifier** does not take effect when nested.|
| CommonAttribute | [backgroundFilter](../reference/apis-arkui/arkui-ts/ts-universal-attributes-filter-effect.md#backgroundfilter) | is not callable | - |
| CommonAttribute | [chainWeight](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#chainweight14) | is not callable | - |
| CommonAttribute | [compositingFilter](../reference/apis-arkui/arkui-ts/ts-universal-attributes-filter-effect.md#compositingfilter) | is not callable | - |
@@ -329,7 +329,6 @@ You can use **AttributeModifier** to set polymorphic styles and events, which en
| CommonAttribute | [bindSheet](../reference/apis-arkui/arkui-ts/ts-universal-attributes-sheet-transition.md#bindsheet) | Method not implemented. | Attributes that accept a CustomBuilder are not supported.|
| CommonAttribute | [dragPreview](../reference/apis-arkui/arkui-ts/ts-universal-attributes-drag-drop.md#dragpreview15) | Builder is not supported. | Attributes that accept a CustomBuilder are not supported.|
| CommonAttribute | [bindPopup](../reference/apis-arkui/arkui-ts/ts-universal-attributes-popup.md#bindpopup) | Method not implemented. | Attributes that accept a CustomBuilder are not supported.|
| CommonAttribute | [onDragStart](../reference/apis-arkui/arkui-ts/ts-universal-events-drag-drop.md#ondragstart) | Method not implemented. | Attributes that return a CustomBuilder are not supported.|
| CommonAttribute | [accessibilityVirtualNode](../reference/apis-arkui/arkui-ts/ts-universal-attributes-accessibility.md#accessibilityvirtualnode11) | is not callable | Attributes that accept a CustomBuilder are not supported.|
Customization capabilities in the ArkUI development framework allow for flexible UI development and personalization. These capabilities span various control levels, each suited for different use cases. Lower levels of customization provide closer access to foundational capabilities, offering greater flexibility but also higher development complexity and demands on developer skills.
Currently, the following customization levels are available, organized from the most basic to the most advanced:
- **Custom composition**: the most basic customization method provided by the ArkUI framework, which combines and reuses existing components through the basic capabilities of built-in and custom components to encapsulate new components. This includes basic capabilities such as encapsulation, layout, drawing, and animation.
- **Custom composition**: the most basic customization method provided by the ArkUI framework, which combines and reuses existing components through the basic capabilities of system and custom components to encapsulate new components. This includes basic capabilities such as encapsulation, layout, drawing, and animation.
- **Custom extension**: a range of modifiers, including the following, that enable the enhancement and customization of UI components in a way that is separate from the UI: [AttributeModifier](../reference/apis-arkui/arkui-ts/ts-universal-attributes-attribute-modifier.md), [GestureModifier](../reference/apis-arkui/arkui-ts/ts-universal-attributes-gesture-modifier.md#gesturemodifier-1), [DrawModifier](../reference/apis-arkui/arkui-ts/ts-universal-attributes-draw-modifier.md#drawmodifier-1).
- **Custom nodes**: node objects with some basic capabilities of underlying entity nodes, which can be mixed and displayed with built-in components through [custom placeholder nodes](./arkts-user-defined-place-holder.md). There are three types of custom nodes: [FrameNode](../reference/apis-arkui/js-apis-arkui-frameNode.md), [RenderNode](../reference/apis-arkui/js-apis-arkui-renderNode.md), and [BuilderNode](../reference/apis-arkui/js-apis-arkui-builderNode.md). These nodes have customization capabilities for individual nodes, such as measurement and layout, setting basic attributes, setting event listeners, and custom drawing and content rendering.
- **Custom nodes**: node objects with some basic capabilities of underlying entity nodes, which can be mixed and displayed with system components through [custom placeholder nodes](./arkts-user-defined-place-holder.md). There are three types of custom nodes: [FrameNode](../reference/apis-arkui/js-apis-arkui-frameNode.md), [RenderNode](../reference/apis-arkui/js-apis-arkui-renderNode.md), and [BuilderNode](../reference/apis-arkui/js-apis-arkui-builderNode.md). These nodes have customization capabilities for individual nodes, such as measurement and layout, setting basic attributes, setting event listeners, and custom drawing and content rendering.
- **Custom rendering**: custom content rendering implemented by writing display data generated by EGL/OpenGLES or other decoded media stream data into the **NativeWindow** object, thanks to the "surface" mode of [XComponent](napi-xcomponent-guidelines.md) that exposes the **NativeWindow** object and the NDK APIs.
## A Quick Glance of Customization Capabilities
@@ -20,8 +28,8 @@
|Custom composition|Custom animation| Use [property animation](./arkts-attribute-animation-apis.md) for custom animation effects on animatable component properties.<br>Use [@AnimatableExtend](../ui/state-management/arkts-animatable-extend.md) to animate non-animatable properties.<br>Use APIs in [@ohos.animator](../reference/apis-arkui/js-apis-animator.md) to create custom animations similar to frame animations, by modifying properties frame-by-frame or integrating with custom drawing.|
|Custom extension|Attribute extension| Use [AttributeModifier](../reference/apis-arkui/arkui-ts/ts-universal-attributes-attribute-modifier.md#attributemodifier) for UI and style separation, dynamic setting and updating of attributes and events, and exporting and reusing across files, which is useful for component encapsulation and extending properties through exposed modifiers.<br>Use [custom modifiers](../reference/apis-arkui/arkui-ts/ts-universal-attributes-attribute-modifier.md#custom-modifier) for simplified attribute passing and extension in component encapsulation.<br> Use [AttributeUpdater](../reference/apis-arkui/js-apis-arkui-AttributeUpdater.md) for direct attribute setting to improve performance in scenarios with frequent attribute updates.|
|Custom extension|Gesture extension| Use [GestureModifier](../reference/apis-arkui/arkui-ts/ts-universal-attributes-gesture-modifier.md#gesturemodifier-1) for gesture extension, adding or removing gestures dynamically, with cross-file export and reuse, which is suitable for encapsulating and reusing custom gesture handling logic.|
|Custom extension|Content extension| Use [DrawModifier](../reference/apis-arkui/arkui-ts/ts-universal-attributes-draw-modifier.md#drawmodifier-1) to extend or replace default component drawing with custom content.<br>Use [ContentModifier](../reference/apis-arkui/arkui-ts/ts-universal-attributes-content-modifier.md#contentmodifiert) to replace component content with custom **Builder** methods in components with clear content and interaction areas.|
|Custom nodes|Component node| Use [FrameNode](arkts-user-defined-arktsNode-frameNode.md) for the following capabilities:<br>Fully custom node capability, including custom measurement, layout, and rendering, with support for dynamically adding and removing nodes, setting universal attributes, and configuring event callbacks. It is suitable for third-party frameworks with high-level languages that do not have their own rendering engines but rely on system capabilities for layout, events, animation, and rendering.<br>Native component proxy capabilities for built-in components, enabling traversal of the node tree. By using FrameNodes within the component tree, you can navigate the entire tree and access component information or register additional event listeners. This is useful for combining seamless listening APIs to implement services such as tracking, advertising SDKs, and mid-end DFX.<br>Use [TypedFrameNode](../reference/apis-arkui/js-apis-arkui-frameNode.md#typedframenode12) for creating specific types of FrameNodes, which can then be mounted with APIs of **FrameNode** to generate a custom component tree. It is ideal for seamless integration with dynamic frameworks developed in high-level programming languages.|
|Custom extension|Content extension| Use [DrawModifier](../reference/apis-arkui/arkui-ts/ts-universal-attributes-draw-modifier.md#drawmodifier-1) to extend or replace default component drawing with custom content.<br>Use [ContentModifier](../reference/apis-arkui/arkui-ts/ts-universal-attributes-content-modifier.md#contentmodifiert) to replace component content with custom **Builder** methods in system components with clear content and interaction areas.|
|Custom nodes|Component node| Use [FrameNode](arkts-user-defined-arktsNode-frameNode.md) for the following capabilities:<br>Fully custom node capability, including custom measurement, layout, and rendering, with support for dynamically adding and removing nodes, setting universal attributes, and configuring event callbacks. It is suitable for third-party frameworks with high-level languages that do not have their own rendering engines but rely on system capabilities for layout, events, animation, and rendering.<br>Component proxy capabilities for declarative components, enabling traversal of the node tree. By using FrameNodes, you can navigate the entire component tree and access component information or register additional event listeners. This is useful for combining seamless listening APIs to implement services such as tracking, advertising SDKs, and mid-end DFX.<br>Use [TypedFrameNode](../reference/apis-arkui/js-apis-arkui-frameNode.md#typedframenode12) for creating specific types of FrameNodes, which can then be mounted with APIs of **FrameNode** to generate a custom component tree. It is ideal for seamless integration with dynamic frameworks developed in high-level programming languages.|
|Custom nodes|Rendering node| Use [RenderNode](arkts-user-defined-arktsNode-renderNode.md) for lightweight rendering nodes that provide rendering-related attribute setting, custom drawing, and node operation capabilities. It is suitable for integration with third-party frameworks without a rendering engine but relying on system animation and rendering capabilities.|
|Custom nodes| Mixing with built-in components| Use [BuilderNode](arkts-user-defined-arktsNode-builderNode.md) to create and update built-in components and component trees. It allows for the integration of declarative components within custom FrameNode or RenderNode structures, facilitating the hybrid display of built-in components with custom nodes. It also allows builder content to be exported as textures, facilitating same-layer rendering in environments created by the **XComponent**.|
|Custom nodes| Mixing with system components| Use [BuilderNode](arkts-user-defined-arktsNode-builderNode.md) to create and update system components and component trees. It allows for the integration of declarative components within custom FrameNode or RenderNode structures, facilitating the hybrid display of system components with custom nodes. It also allows builder content to be exported as textures, facilitating same-layer rendering in environments created by the **XComponent**.|
|Custom rendering| Independent rendering| Use [XComponent](napi-xcomponent-guidelines.md)'s surface mode with the NDK APIs to create a standalone rendering environment through **NativeWindow**, which enables writing display data generated by EGL/OpenGLES or other media stream data decoded through various methods into the **NativeWindow** object. This way, custom rendering is achieved without relying on other components provided by the ArkUI framework. It is suitable for frameworks that come with their own rendering engines, such as those used in gaming engines, mapping applications, and camera software.|
@@ -18,21 +18,21 @@ ArkUI provides a comprehensive infrastructure for application UI development, in
## Two Development Paradigms
ArkUI comes with two development paradigms: [ArkTS-based declarative development paradigm](arkts-ui-development-overview.md) (declarative development paradigm for short) and [JS-compatible web-like development paradigm](ui-js-overview.md) (web-like development paradigm for short). You can choose whichever development paradigm that aligns with your practice.
ArkUI comes with two development paradigms: [ArkTS-based declarative development paradigm](arkts-ui-development-overview.md) (declarative development paradigm for short) and [JavaScript-compatible web-like development paradigm](ui-js-overview.md) (web-like development paradigm for short). You can choose whichever development paradigm that aligns with your practice.
- **Declarative development paradigm**: uses [ArkTS](../quick-start/arkts-get-started.md) – a superset of TypeScript with declarative UI syntax, providing UI drawing capabilities from three dimensions: component, animation, and state management.
- **Declarative development paradigm**: uses the [ArkTS language](../quick-start/arkts-get-started.md), which extends TypeScript with declarative UI syntax, to provide UI drawing capabilities from three dimensions: components, animations, and state management.
- **Web-like development paradigm**: uses the classical three-stage programming model, in which <!--RP1-->HML<!--RP1End--> is used for building layouts, CSS for defining styles, and JS for adding processing logic. This development paradigm has a low learning curve for frontend web developers, allowing them to quickly transform existing web applications into ArkUI applications.
- **Web-like development paradigm**: uses the classical three-stage programming model, in which <!--RP1-->HML<!--RP1End--> is used for building layouts, CSS for defining styles, and JavaScript for adding processing logic. This development paradigm has a low learning curve for frontend web developers, allowing them to quickly transform existing web applications into ArkUI applications.
The declarative development paradigm is a better choice for building new application UIs for the following reasons:
- **Higher development efficiency**: In the declarative development paradigm, the programming mode used is closer to natural semantics. You can intuitively describe the UI without caring about how the framework implements UI drawing and rendering, leading to simplified and efficient development.
- **Higher application performance**: As shown below, the two development paradigms share the UI backend engine and language runtime. However, the declarative development paradigm does not require the JS framework for managing the page DOM. As such, it has more streamlined rendering and update links and less memory usage.
- **Higher application performance**: As shown below, the two development paradigms share the UI backend engine and language runtime. However, the declarative development paradigm does not require the JavaScript framework for managing the page DOM. As such, it has more streamlined rendering and update links and less memory usage.
- **Future proof**: The declarative development paradigm will continue to develop as the preferred development paradigm, providing increasingly diverse and powerful capabilities.
**Figure 1** ArkUI framework
**Figure 1** ArkUI framework

@@ -46,9 +46,9 @@ The supported development paradigm varies according to the [application model](.
| Application Model | Page Form | Supported Development Paradigm |
@@ -109,7 +109,7 @@ To enhance user experience, applications should adapt to the system's dark and l
5. Listening for Color Mode Switching Events
Applications can listen for system color mode changes and perform custom logic, such as initializing resources of other types. This approach works regardless of whether the application is set to follow the system's dark or light mode.
Applications can listen for system color mode changes and perform custom logic, such as initializing resources of other types. When an application uses [setColorMode](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#setcolormode18) to manually set the color mode, it will not receive the **onConfigurationUpdate** callback. Except for this case, this listener remains effective regardless of whether the application follows the system's color mode changes.
a. Save the current color mode to the AppStorage in the **onCreate()** lifecycle of the AbilityStage.
@@ -161,7 +161,7 @@ To enhance user experience, applications should adapt to the system's dark and l
6. Partial Adaptation
Using [WithTheme](../reference/apis-arkui/arkui-ts/ts-container-with-theme.md), you can set three color modes: follow the system, light mode, and dark mode.
Using [WithTheme](../reference/apis-arkui/arkui-ts/ts-container-with-theme.md), you can set three [color modes](../reference/apis-arkui/arkui-ts/ts-universal-attributes-foreground-blur-style.md#themecolormode): follow the system, light mode, and dark mode.
Within the scope of **WithTheme**, component styles adapt to the specified color mode by accessing the corresponding system and application resource values, ensuring components adjust their appearance based on the configured mode. For details, see [Setting a Custom Theme Style for Specific Application Pages](./theme_skinning.md#setting-a-custom-theme-style-for-specific-application-pages).
@@ -171,7 +171,7 @@ By default, applications follow the system's color mode. When configured this wa
> **NOTE**
>
> If your application does not support dark mode properly and displays abnormalities, you can use this approach to lock the UI in light mode.
> If an application is not specifically adapted for dark mode, directly following the system settings may cause display issues in dark mode. As a workaround, this method can be used to lock the application in light mode.
```ts
onCreate(): void {
@@ -208,7 +208,7 @@ onCreate(): void {
- Not Recommended Approach
Avoid adapting to color mode changes through functions in attribute settings that rely on re-executing attribute setting code during the color mode switching process. Incorrect usage:
Avoid adapting to color mode changes through function return values in attribute settings that rely on re-executing attribute setting code during the color mode switching process. Incorrect usage:
```ts
getResource() : string {
@@ -236,7 +236,7 @@ Starting from API version 20, the system provides an optimized color mode switch
> **NOTE**
>
> When configuring **metadata**, ensure that any custom adaptation logic implemented through attribute setting functions properly handles color mode changes.
> When configuring **metadata**, ensure that color mode switching is not implemented through function return values in attribute settings.
> <!--RP1--><!--RP1End-->
1. Enable color mode switching optimization through **metadata**.
@@ -254,11 +254,151 @@ Starting from API version 20, the system provides an optimized color mode switch
2. Ensure proper adaptation of your application's custom behavior.
After enabling color mode switching optimization, frontend code and attribute settings are not re-executed during mode switching. Only essential attributes are updated and redrawn. If your application relies on function-based attribute settings to handle mode changes, this adaptation approach will no longer work. You must implement proper adaptation before enabling the optimization. For detailed guidance, see [Recommendations and Precautions](#recommendations-and-precautions).
After enabling color mode switching optimization, frontend code and attribute settings are not re-executed during mode switching. Only essential attributes are updated and redrawn. If your application relies on function-based attribute settings to handle mode changes, this adaptation approach will no longer work. You must implement proper adaptation before enabling the optimization. For detailed guidance, see [Recommendations and Precautions](#recommendations-and-precautions). Below are three typical adaptation scenarios:
- Returning different resource values based on the current color mode
After enabling the optimization, you can actively listen for system color mode changes using either the [AbilityStage's callback](../reference/apis-ability-kit/js-apis-app-ability-abilityStage.md#onconfigurationupdate) or the [Ability's callback](../reference/apis-ability-kit/js-apis-app-ability-ability.md#abilityonconfigurationupdate), and update the text color accordingly. Example:
```ts
// EntryAbility.ets
import { Configuration, UIAbility } from '@kit.AbilityKit';
export default class EntryAbility extends UIAbility {
if (this.colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT) {
this.textColor = $r("app.color.color_light")
} else {
this.textColor = $r("app.color.color_night")
}
}
build() {
Column() {
Text('fontColor')
.fontColor(this.textColor)
}
}
}
```
- Returning different resource values based on a custom theme mode
fter enabling the optimization, you need to bind both the text content and the text color of the **Text** component to state variables. When a color mode switch event occurs, update the component attributes through those state variables. Example:
```ts
// ResourceTheme.ets
export enum ThemeMode {
mode1 = 0,
mode2
}
export class ResourceTheme {
fontColor: ResourceColor = this.getColor();
themeMode: ThemeMode = ThemeMode.mode1;
setThemeMode(mode: ThemeMode) {
this.themeMode = mode
}
getThemeMode(): ThemeMode {
return this.themeMode
}
getColor(): ResourceColor {
if (this.themeMode === ThemeMode.mode1) {
return $r("app.color.color_light")
} else {
return $r("app.color.color_night")
}
}
}
```
```ts
// Index.ets
import { ConfigurationConstant } from '@kit.AbilityKit';
import { ResourceTheme, ThemeMode } from './ResourceTheme';
- Returning different resource values based on a member variable's value
After enabling the optimization, you need to bind the text color attribute to a state variable. During a color mode switch, update the state variable via a callback so that attribute changes are applied on the next mode switch. Example:
```ts
// Index.ets
import { ConfigurationConstant } from '@kit.AbilityKit';
## Using Color Inversion for Quick Dark Mode Adaptation
Starting from API version 20, applications with substantial existing codebases can leverage the system's color inversion capability to rapidly implement dark mode support. This approach serves as an alternative to the [resource configuration approach](#following-the-systems-color-mode) and [theme-based adaptation](../reference/apis-arkui/arkui-ts/ts-container-with-theme.md).
Starting from API version 20, for applications with a large existing codebase that have already partially adapted to dark mode via [resource configuration](#following-the-systems-color-mode) or [theme](../reference/apis-arkui/arkui-ts/ts-container-with-theme.md) approaches, you can use the system's built‑in color inversion capability to quickly achieve full dark‑mode adaptation.
While offering less granular control compared to resource configuration and theme modes, color inversion significantly reduces adaptation effort and prevents application package size growth from extensive resource definitions. This method provides visually acceptable results in most scenarios.
@@ -274,17 +414,19 @@ While offering less granular control compared to resource configuration and them
> **NOTE**
>
> 1. Before calling **OH_ArkUI_SetForceDarkConfig**, ensure that [OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1")](../reference/apis-arkui/capi-native-interface-h.md#oh_arkui_querymoduleinterfacebyname) is loaded.
> - Before calling **OH_ArkUI_SetForceDarkConfig**, ensure that [OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1")](../reference/apis-arkui/capi-native-interface-h.md#oh_arkui_querymoduleinterfacebyname) is loaded.
>
> - The **OH_ArkUI_SetForceDarkConfig** API must be called in the UI thread before node creation. **After a page is created, dynamically modifying the application's color inversion capability status via this API is not supported.**
>
> 2. The **OH_ArkUI_SetForceDarkConfig** API must be called in the UI thread before node creation.
> - The **OH_ArkUI_SetForceDarkConfig** API takes effect only at the process level. Different instances cannot use different color inversion algorithms.
>
> 3. The **OH_ArkUI_SetForceDarkConfig** API takes effect only at the process level. Different instances cannot use different color inversion algorithms.
> - The **OH_ArkUI_SetForceDarkConfig** API supports only C API implementation. This design avoids significant cross-language call overhead during frequent color mode transitions.
>
> 4. The **OH_ArkUI_SetForceDarkConfig** API supports only C API implementation. This design avoids significant cross-language call overhead during frequent color mode transitions.
> - [DatePickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-datepicker-dialog.md), [TimePickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-timepicker-dialog.md), [CalendarPickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-calendarpicker-dialog.md), and [TextPickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-textpicker-dialog.md) do not support color inversion because they lack physical node implementations.
>
> 5. [DatePickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-datepicker-dialog.md), [TimePickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-timepicker-dialog.md), [CalendarPickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-calendarpicker-dialog.md), and [TextPickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-textpicker-dialog.md) do not support color inversion because they lack physical node implementations.
> - Color inversion is not supported for the following properties in **TextArea**: **NODE_BORDER_COLOR**, **NODE_TEXT_RADIAL_GRADIENT**, and **NODE_TEXT_LINEAR_GRADIENT**.
>
> 6. Color inversion is not supported for the following **TextArea** attributes: **NODE_BORDER_COLOR**, **NODE_TEXT_RADIAL_GRADIENT**, and **NODE_TEXT_LINEAR_GRADIENT**.
> - If a component has an invalid color value or **undefined** configured, the color inversion capability will not take effect.
This example demonstrates the fundamental usage of the **OH_ArkUI_SetForceDarkConfig** API. Configure a custom color inversion algorithm based on actual scenarios to display appropriate color values during color mode transitions.
@@ -341,4 +483,4 @@ While offering less granular control compared to resource configuration and them
3. Implement inversion capability control.
Use the [allowForceDark](../reference/apis-arkui/arkui-ts/ts-allow-force-dark.md#allowforcedark) attribute as an escape mechanism to disable automatic color inversion for specific components, preserving their original appearance during theme transitions.
Starting from API version 21, you can use the [allowForceDark](../reference/apis-arkui/arkui-ts/ts-allow-force-dark.md#allowforcedark) attribute as an escape mechanism to disable automatic color inversion for specific components, preserving their original appearance during theme transitions.
- [基于Native接口的MindSpore Lite ASR应用开发(C/C++)(API14)](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/DocsSample/MindSporeLiteKit/MindSporeLiteCDemoASR)
不同于从外部获取数据或在运行时生成数据,硬编码是指将数据、参数、常量等直接嵌入到程序中,实现特定功能。在界面中显示的文字,包括图片中的文字、音频、字幕等,不能采用硬编码,避免难以本地化或增加本地化的工作量。同时,界面上的一句完整文本,不应由多个片段直接前后拼接而成,这可能导致翻译时无法获取句子完整信息,从而导致翻译错误或语义表达顺序问题。例如,下图中将“Rain tomorrow”和“Bring an umbrella”两句直接拼接在一起,造成语句大小写问题。
与从外部获取数据或在运行时动态生成数据不同,硬编码是将数据、参数或常量直接写入程序代码中,从而实现特定功能。在界面中显示的文字,包括图片中的文字、音频、字幕等,不能采用硬编码,避免难以本地化或增加本地化的工作量。同时,界面上的一句完整文本,不应由多个片段直接前后拼接而成,这可能导致翻译时无法获取句子完整信息,从而导致翻译错误或语义表达顺序问题。例如,下图中将“Rain tomorrow”和“Bring an umbrella”两句直接拼接在一起,造成语句大小写问题。
Thank you for your continuous support to the Openl Qizhi Community AI Collaboration Platform. In order to protect your usage rights and ensure network security, we updated the Openl Qizhi Community AI Collaboration Platform Usage Agreement in January 2024. The updated agreement specifies that users are prohibited from using intranet penetration tools. After you click "Agree and continue", you can continue to use our services. Thank you for your cooperation and understanding.