diff --git a/en/application-dev/ui/Readme-EN.md b/en/application-dev/device/ui/Readme-CN.md old mode 100755 new mode 100644 similarity index 73% rename from en/application-dev/ui/Readme-EN.md rename to en/application-dev/device/ui/Readme-CN.md index 3ab9ea92f9b73bb2ed358a7cea895dd52eb36f7e..d398aa74d8d44f8da390c879c4a9e83b094b17c4 --- a/en/application-dev/ui/Readme-EN.md +++ b/en/application-dev/device/ui/Readme-CN.md @@ -1,6 +1,7 @@ # UI -- JavaScript-based Web-Like Development Paradigm +- [ArkUI Overview](arkui-overview.md) +- JavaScript-based Web-like Development Paradigm - [Overview](ui-js-overview.md) - Framework - [File Organization](js-framework-file.md) @@ -25,26 +26,27 @@ - [Developing Animations](ui-js-building-ui-animation.md) - [Defining Events](ui-js-building-ui-event.md) - [Defining Page Routes](ui-js-building-ui-routes.md) - - Common Component Development Guidelines - - [Text](ui-js-components-text.md) - - [Input](ui-js-components-input.md) - - [Button](ui-js-components-button.md) - - [List](ui-js-components-list.md) - - [Picker](ui-js-components-picker.md) - - [Dialog](ui-js-components-dialog.md) - - [Form](ui-js-components-form.md) - - [Stepper](ui-js-components-stepper.md) - - [Tabs](ui-js-component-tabs.md) - - [Image](ui-js-components-images.md) + - Common Component Development Guidelines + - [<text> Development](ui-js-components-text.md) + - [<input> Development](ui-js-components-input.md) + - [<button> Development](ui-js-components-button.md) + - [<list> Development](ui-js-components-list.md) + - [<picker> Development](ui-js-components-picker.md) + - [<dialog> Development](ui-js-components-dialog.md) + - [<form> Development](ui-js-components-form.md) + - [<stepper> Development](ui-js-components-stepper.md) + - [<tabs> Development](ui-js-component-tabs.md) + - [<image> Development](ui-js-components-images.md) - Animation Development Guidelines - CSS Animation - [Defining Attribute Style Animations](ui-js-animate-attribute-style.md) - [Defining Animations with the transform Attribute](ui-js-animate-transform.md) - [Defining Animations with the background-position Attribute](ui-js-animate-background-position-style.md) + - [Defining Animations for SVG Components](ui-js-animate-svg.md) - JS Animation - [Component Animation](ui-js-animate-component.md) - Interpolator Animation - - [Animation Effect](ui-js-animate-dynamic-effects.md) + - [Animation Effect](ui-js-animate-dynamic-effects.md) - [Animation Frame](ui-js-animate-frame.md) - [Custom Components](ui-js-custom-components.md) - TypeScript-based Declarative Development Paradigm @@ -65,9 +67,9 @@ - General UI Description Specifications - [Basic Concepts](ts-general-ui-concepts.md) - Declarative UI Description Specifications - - [Parameterless Configuration](ts-parameterless-configuration.md) + - [Configuration Without Parameters](ts-parameterless-configuration.md) - [Configuration with Mandatory Parameters](ts-configuration-with-mandatory-parameters.md) - - [Attribution Configuration](ts-attribution-configuration.md) + - [Attribute Configuration](ts-attribution-configuration.md) - [Event Configuration](ts-event-configuration.md) - [Child Component Configuration](ts-child-component-configuration.md) - Componentization @@ -77,6 +79,7 @@ - [@Builder](ts-component-based-builder.md) - [@Extend](ts-component-based-extend.md) - [@CustomDialog](ts-component-based-customdialog.md) + - [@Styles](ts-component-based-styles.md) - About UI State Management - [Basic Concepts](ts-ui-state-mgmt-concepts.md) - Managing Component States @@ -88,19 +91,21 @@ - [PersistentStorage](ts-application-states-apis-persistentstorage.md) - [Environment](ts-application-states-apis-environment.md) - Managing Other States - - [@observed and @objectLink](ts-other-states-observed-objectlink.md) + - [@Observed and @ObjectLink](ts-other-states-observed-objectlink.md) - [@Consume and @Provide](ts-other-states-consume-provide.md) - [@Watch](ts-other-states-watch.md) - - About Rendering Control Syntax - - [if/else](ts-rending-control-syntax-if-else.md) - - [ForEach](ts-rending-control-syntax-foreach.md) - - [LazyForEach](ts-rending-control-syntax-lazyforeach.md) + - About Rendering Control Syntax + - [if/else](ts-rending-control-syntax-if-else.md) + - [ForEach](ts-rending-control-syntax-foreach.md) + - [LazyForEach](ts-rending-control-syntax-lazyforeach.md) - About @Component - [build Function](ts-function-build.md) - - [Custom Component Initialization](ts-custom-component-initialization.md) + - [Initialization of Custom Components' Member Variables](ts-custom-component-initialization.md) - [Custom Component Lifecycle Callbacks](ts-custom-component-lifecycle-callbacks.md) - - [Example: Component Creation and Re-Initialization](ts-component-creation-re-initialization.md) - - [Syntactic Sugar](ts-syntactic-sugar.md) + - [Component Creation and Re-initialization](ts-component-creation-re-initialization.md) + - [About Syntactic Sugar](ts-syntactic-sugar.md) + - Common Component Development Guidelines + - [<web> Development](ui-ts-components-web.md) - Experiencing the Declarative UI - [Creating a Declarative UI Project](ui-ts-creating-project.md) - [Getting to Know Components](ui-ts-components.md) @@ -110,4 +115,3 @@ - [Building a Food Category List Layout](ui-ts-building-category-list-layout.md) - [Building a Food Category Grid Layout](ui-ts-building-category-grid-layout.md) - [Implementing Page Redirection and Data Transmission](ui-ts-page-redirection-data-transmission.md) - diff --git a/en/application-dev/device/ui/arkui-overview.md b/en/application-dev/device/ui/arkui-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..a5ba95916cfd3fad3e6eebe945ea6f22f6aa2aea --- /dev/null +++ b/en/application-dev/device/ui/arkui-overview.md @@ -0,0 +1,58 @@ +# ArkUI Overview + + +## Introduction + +ArkUI is a UI development framework that provides what you'll need to develop application UIs. + + +## Basic Concepts + +- Component: the smallest unit for UI building and display. You build a UI that meets your needs through flexible combinations of components. + +- Page: the smallest unit for ArkUI application scheduling. You can design multiple pages for your application, manage their files on a per-page basis, and schedule page redirection through routing APIs, so as to implement decoupling of application functions. + + +## Key Capabilities + +- Diverse components: In addition to a wide range of basic components, such as components for text display, image display, and keypress interaction, ArkUI provides media components that support video playback. Better yet, it also provides polymorphic components, which can adapt to styles of different devices. + +- Flexible layouts: Creating a responsive UI in ArkUI is easy, with our carefully-designed layout approaches: Besides the classic flexible layout capability, you also have access to the list, grid, and atomic layouts that auto-adapt to screen resolutions. + +- Animation: Apart from animations embedded in components, ArkUI offers additional animation features: attribute animation, transition animation, and custom animation. + +- UI interaction: ArkUI allows users to interact with your application UI properly, regardless of the system platform and input device. By default, the UI accepts input from touch gestures, remote controls, and mouse devices, with support for the event notification capability. + +- Drawing: ArkUI offers advanced drawing capabilities that allow you to draw custom shapes with a range of editors, from images to fill colors and texts. + +- Platform API channel: ArkUI provides an API extension mechanism through which platform capabilities are encapsulated to produce JavaScript APIs in a unified style. + + +## Development Paradigms + +ArkUI comes with two development paradigms: JavaScript-based web-like development paradigm (web-like development paradigm for short) and TypeScript-based declarative development paradigm (declarative development paradigm for short). You can choose whichever development paradigm that aligns with your practice. + + +### Web-like Development Paradigm + +The web-like development paradigm uses the classical three-stage programming model, in which OpenHarmony Markup Language (HML) is used for building layouts, CSS for defining styles, and JavaScript for adding processing logic. UI components are associated with data through one-way data-binding. This means that when data changes, the UI automatically updates with the new data. This development paradigm has a low learning curve for frontend web developers, allowing them to quickly transform existing web applications into ArkUI applications. It could be helpful if you are developing small- and medium-sized applications with simple UIs. + + +### Declarative Development Paradigm + +The declarative development paradigm uses the TypeScript programming language and extends the declarative UI syntax, providing UI drawing capabilities from three dimensions: component, animation, and state management. 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. With type annotations in TypeScript, you can enforce type checking at compile time. If you are developing large applications, the declarative development paradigm is more applicable. + + +### Web-like Development Paradigm vs. Declarative Development Paradigm + + | Development Paradigm | Language | UI Update Mode | Applicable To | Intended Audience | +| -------- | -------- | -------- | -------- | -------- | +| Web-like development paradigm | JavaScript | Data-driven | Applets and service widgets with simple UIs | Frontend web developers | +| Declarative development paradigm | Extended TypeScript (eTS) | Data-driven | Applications involving technological sophistication and teamwork | Mobile application and system application developers | + + +### Framework Structure + +![en-us_image_0000001267647869](figures/en-us_image_0000001267647869.png) + +As shown above, the two development paradigms share the UI backend engine and language runtime. The UI backend engine implements the six basic capabilities of the ArkUI framework. 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. This makes the declarative development paradigm a better choice for building application UIs. diff --git a/en/application-dev/device/ui/figures/directory-structure-for-resource-sharing-5+.png b/en/application-dev/device/ui/figures/directory-structure-for-resource-sharing-5+.png new file mode 100644 index 0000000000000000000000000000000000000000..5e4322d20ad887573ad85958bc181a1be0f85f1c Binary files /dev/null and b/en/application-dev/device/ui/figures/directory-structure-for-resource-sharing-5+.png differ diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001174104404.png b/en/application-dev/device/ui/figures/en-us_image_0000001174104404.png new file mode 100644 index 0000000000000000000000000000000000000000..e370a44cf043fc34bd8891f57faad2cd2ca05707 Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001174104404.png differ diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001174264376.png b/en/application-dev/device/ui/figures/en-us_image_0000001174264376.png new file mode 100644 index 0000000000000000000000000000000000000000..dfcb0c5e259b3f8d7375c21712249c1e847edd67 Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001174264376.png differ diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001174422914.png b/en/application-dev/device/ui/figures/en-us_image_0000001174422914.png new file mode 100644 index 0000000000000000000000000000000000000000..bc28f5056c679e189543c8ad6fba67fb56db7655 Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001174422914.png differ diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001174582864.png b/en/application-dev/device/ui/figures/en-us_image_0000001174582864.png new file mode 100644 index 0000000000000000000000000000000000000000..b54dbc2391d1a8f16312dd02dc3d65a35ea2626f Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001174582864.png differ diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001174582866.png b/en/application-dev/device/ui/figures/en-us_image_0000001174582866.png new file mode 100644 index 0000000000000000000000000000000000000000..56d32d4cd371c5374b133cb81c9c077aaf7b110d Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001174582866.png differ diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001182832088.gif b/en/application-dev/device/ui/figures/en-us_image_0000001182832088.gif new file mode 100644 index 0000000000000000000000000000000000000000..53a8a2063ae440915a9b1710d9b184c470f26010 Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001182832088.gif differ diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001183871404.gif b/en/application-dev/device/ui/figures/en-us_image_0000001183871404.gif new file mode 100644 index 0000000000000000000000000000000000000000..92bac3bec6a14037b71c86d76d4d87ac3a40171a Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001183871404.gif differ diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001219662661.png b/en/application-dev/device/ui/figures/en-us_image_0000001219662661.png new file mode 100644 index 0000000000000000000000000000000000000000..9c43caf5fdfd466eafc37b793f509a6bde2b885d Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001219662661.png differ diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001219662663.png b/en/application-dev/device/ui/figures/en-us_image_0000001219662663.png new file mode 100644 index 0000000000000000000000000000000000000000..5c5e360f249a2002ba68ad9b94bd7f66f5d6aab1 Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001219662663.png differ diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001219662665.png b/en/application-dev/device/ui/figures/en-us_image_0000001219662665.png new file mode 100644 index 0000000000000000000000000000000000000000..309d1c46f8bc396df5eaed381a5ffa2f0389d602 Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001219662665.png differ diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001219744201.png b/en/application-dev/device/ui/figures/en-us_image_0000001219744201.png new file mode 100644 index 0000000000000000000000000000000000000000..0d22570503febc7a7dcba0d1e870f49f32fe489a Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001219744201.png differ diff --git a/en/application-dev/ui/figures/000000.png b/en/application-dev/device/ui/figures/en-us_image_0000001219864153.png similarity index 100% rename from en/application-dev/ui/figures/000000.png rename to en/application-dev/device/ui/figures/en-us_image_0000001219864153.png diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001219982719.png b/en/application-dev/device/ui/figures/en-us_image_0000001219982719.png new file mode 100644 index 0000000000000000000000000000000000000000..fde616c73000d3f58fd98eea59088177221127a5 Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001219982719.png differ diff --git a/en/application-dev/ui/figures/en-us_image_0000001214595111.png b/en/application-dev/device/ui/figures/en-us_image_0000001222807756.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001214595111.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222807756.png diff --git a/en/application-dev/ui/figures/4.gif b/en/application-dev/device/ui/figures/en-us_image_0000001222807760.gif similarity index 100% rename from en/application-dev/ui/figures/4.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001222807760.gif diff --git a/en/application-dev/ui/figures/2.png b/en/application-dev/device/ui/figures/en-us_image_0000001222807768.png similarity index 100% rename from en/application-dev/ui/figures/2.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222807768.png diff --git a/en/application-dev/ui/figures/32.gif b/en/application-dev/device/ui/figures/en-us_image_0000001222807772.gif similarity index 100% rename from en/application-dev/ui/figures/32.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001222807772.gif diff --git a/en/application-dev/ui/figures/d2.gif b/en/application-dev/device/ui/figures/en-us_image_0000001222807776.gif similarity index 100% rename from en/application-dev/ui/figures/d2.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001222807776.gif diff --git a/en/application-dev/ui/figures/01.png b/en/application-dev/device/ui/figures/en-us_image_0000001222807780.png similarity index 100% rename from en/application-dev/ui/figures/01.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222807780.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001214330169.png b/en/application-dev/device/ui/figures/en-us_image_0000001222807784.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001214330169.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222807784.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001215199399.png b/en/application-dev/device/ui/figures/en-us_image_0000001222807792.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001215199399.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222807792.png diff --git a/en/application-dev/ui/figures/7-11.png b/en/application-dev/device/ui/figures/en-us_image_0000001222807796.png similarity index 100% rename from en/application-dev/ui/figures/7-11.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222807796.png diff --git a/en/application-dev/ui/figures/video_2021-10-22_103503.gif b/en/application-dev/device/ui/figures/en-us_image_0000001222807800.gif similarity index 100% rename from en/application-dev/ui/figures/video_2021-10-22_103503.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001222807800.gif diff --git a/en/application-dev/ui/figures/25.gif b/en/application-dev/device/ui/figures/en-us_image_0000001222807808.gif similarity index 100% rename from en/application-dev/ui/figures/25.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001222807808.gif diff --git a/en/application-dev/ui/figures/1-14.gif b/en/application-dev/device/ui/figures/en-us_image_0000001222807812.gif similarity index 100% rename from en/application-dev/ui/figures/1-14.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001222807812.gif diff --git a/en/application-dev/ui/figures/running-effect.png b/en/application-dev/device/ui/figures/en-us_image_0000001222807816.png old mode 100755 new mode 100644 similarity index 100% rename from en/application-dev/ui/figures/running-effect.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222807816.png diff --git a/en/application-dev/ui/figures/21.gif b/en/application-dev/device/ui/figures/en-us_image_0000001222967740.gif similarity index 100% rename from en/application-dev/ui/figures/21.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001222967740.gif diff --git a/en/application-dev/ui/figures/05-3.png b/en/application-dev/device/ui/figures/en-us_image_0000001222967744.png similarity index 100% rename from en/application-dev/ui/figures/05-3.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222967744.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001251421931.png b/en/application-dev/device/ui/figures/en-us_image_0000001222967752.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001251421931.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222967752.png diff --git a/en/application-dev/ui/figures/29.gif b/en/application-dev/device/ui/figures/en-us_image_0000001222967756.gif similarity index 100% rename from en/application-dev/ui/figures/29.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001222967756.gif diff --git a/en/application-dev/ui/figures/q2.gif b/en/application-dev/device/ui/figures/en-us_image_0000001222967760.gif similarity index 100% rename from en/application-dev/ui/figures/q2.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001222967760.gif diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001222967764.png b/en/application-dev/device/ui/figures/en-us_image_0000001222967764.png new file mode 100644 index 0000000000000000000000000000000000000000..62c786d7dacd69bae17ebe4074a2d429cd7f6851 Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001222967764.png differ diff --git a/en/application-dev/ui/figures/corespec_figures_state-mgmt-overview.png b/en/application-dev/device/ui/figures/en-us_image_0000001222967768.png similarity index 100% rename from en/application-dev/ui/figures/corespec_figures_state-mgmt-overview.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222967768.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001168888822.png b/en/application-dev/device/ui/figures/en-us_image_0000001222967772.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001168888822.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222967772.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001213968747.png b/en/application-dev/device/ui/figures/en-us_image_0000001222967776.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001213968747.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222967776.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001214128687.png b/en/application-dev/device/ui/figures/en-us_image_0000001222967780.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001214128687.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222967780.png diff --git a/en/application-dev/ui/figures/page-routing.png b/en/application-dev/device/ui/figures/en-us_image_0000001222967784.png old mode 100755 new mode 100644 similarity index 100% rename from en/application-dev/ui/figures/page-routing.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222967784.png diff --git a/en/application-dev/ui/figures/9.gif b/en/application-dev/device/ui/figures/en-us_image_0000001222967788.gif similarity index 100% rename from en/application-dev/ui/figures/9.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001222967788.gif diff --git a/en/application-dev/ui/figures/page-layout.png b/en/application-dev/device/ui/figures/en-us_image_0000001222967792.png old mode 100755 new mode 100644 similarity index 100% rename from en/application-dev/ui/figures/page-layout.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222967792.png diff --git a/en/application-dev/ui/figures/3-16.gif b/en/application-dev/device/ui/figures/en-us_image_0000001222967796.gif similarity index 100% rename from en/application-dev/ui/figures/3-16.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001222967796.gif diff --git a/en/application-dev/ui/figures/en-us_image_0000001195117633.png b/en/application-dev/device/ui/figures/en-us_image_0000001222967800.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001195117633.png rename to en/application-dev/device/ui/figures/en-us_image_0000001222967800.png diff --git a/en/application-dev/ui/figures/zh-cn_image_0000001077953992.png b/en/application-dev/device/ui/figures/en-us_image_0000001223127696.png similarity index 100% rename from en/application-dev/ui/figures/zh-cn_image_0000001077953992.png rename to en/application-dev/device/ui/figures/en-us_image_0000001223127696.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001213462329.png b/en/application-dev/device/ui/figures/en-us_image_0000001223127700.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001213462329.png rename to en/application-dev/device/ui/figures/en-us_image_0000001223127700.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001168059158.png b/en/application-dev/device/ui/figures/en-us_image_0000001223127704.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001168059158.png rename to en/application-dev/device/ui/figures/en-us_image_0000001223127704.png diff --git a/en/application-dev/ui/figures/19.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223127708.gif similarity index 100% rename from en/application-dev/ui/figures/19.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223127708.gif diff --git a/en/application-dev/ui/figures/d4.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223127712.gif similarity index 100% rename from en/application-dev/ui/figures/d4.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223127712.gif diff --git a/en/application-dev/ui/figures/00.png b/en/application-dev/device/ui/figures/en-us_image_0000001223127716.png similarity index 100% rename from en/application-dev/ui/figures/00.png rename to en/application-dev/device/ui/figures/en-us_image_0000001223127716.png diff --git a/en/application-dev/ui/figures/01-1.png b/en/application-dev/device/ui/figures/en-us_image_0000001223127720.png similarity index 100% rename from en/application-dev/ui/figures/01-1.png rename to en/application-dev/device/ui/figures/en-us_image_0000001223127720.png diff --git a/en/application-dev/ui/figures/static-animation.png b/en/application-dev/device/ui/figures/en-us_image_0000001223127724.png old mode 100755 new mode 100644 similarity index 100% rename from en/application-dev/ui/figures/static-animation.png rename to en/application-dev/device/ui/figures/en-us_image_0000001223127724.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001214210217.png b/en/application-dev/device/ui/figures/en-us_image_0000001223127732.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001214210217.png rename to en/application-dev/device/ui/figures/en-us_image_0000001223127732.png diff --git a/en/application-dev/ui/figures/10-10.png b/en/application-dev/device/ui/figures/en-us_image_0000001223127736.png similarity index 100% rename from en/application-dev/ui/figures/10-10.png rename to en/application-dev/device/ui/figures/en-us_image_0000001223127736.png diff --git a/en/application-dev/ui/figures/4444.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223127740.gif similarity index 100% rename from en/application-dev/ui/figures/4444.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223127740.gif diff --git a/en/application-dev/ui/figures/listrouter.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223127744.gif similarity index 100% rename from en/application-dev/ui/figures/listrouter.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223127744.gif diff --git a/en/application-dev/ui/figures/26.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223127748.gif similarity index 100% rename from en/application-dev/ui/figures/26.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223127748.gif diff --git a/en/application-dev/ui/figures/111-17.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223127752.gif similarity index 100% rename from en/application-dev/ui/figures/111-17.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223127752.gif diff --git a/en/application-dev/ui/figures/6.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223127756.gif similarity index 100% rename from en/application-dev/ui/figures/6.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223127756.gif diff --git a/en/application-dev/ui/figures/en-us_image_0000001195119619.png b/en/application-dev/device/ui/figures/en-us_image_0000001223127760.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001195119619.png rename to en/application-dev/device/ui/figures/en-us_image_0000001223127760.png diff --git a/en/application-dev/ui/figures/34.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223287652.gif similarity index 100% rename from en/application-dev/ui/figures/34.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223287652.gif diff --git a/en/application-dev/ui/figures/2-7.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223287656.gif similarity index 100% rename from en/application-dev/ui/figures/2-7.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223287656.gif diff --git a/en/application-dev/ui/figures/02.png b/en/application-dev/device/ui/figures/en-us_image_0000001223287668.png similarity index 100% rename from en/application-dev/ui/figures/02.png rename to en/application-dev/device/ui/figures/en-us_image_0000001223287668.png diff --git a/en/application-dev/ui/figures/18.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223287672.gif similarity index 100% rename from en/application-dev/ui/figures/18.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223287672.gif diff --git a/en/application-dev/ui/figures/3-9.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223287676.gif similarity index 100% rename from en/application-dev/ui/figures/3-9.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223287676.gif diff --git a/en/application-dev/ui/figures/5.png b/en/application-dev/device/ui/figures/en-us_image_0000001223287680.png similarity index 100% rename from en/application-dev/ui/figures/5.png rename to en/application-dev/device/ui/figures/en-us_image_0000001223287680.png diff --git a/en/application-dev/ui/figures/24.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223287684.gif similarity index 100% rename from en/application-dev/ui/figures/24.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223287684.gif diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001223287688.png b/en/application-dev/device/ui/figures/en-us_image_0000001223287688.png new file mode 100644 index 0000000000000000000000000000000000000000..cc39aec87bb14a36eb6214a2ef39d45c631d4a2b Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001223287688.png differ diff --git a/en/application-dev/ui/figures/continuous-animation-effect.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223287696.gif old mode 100755 new mode 100644 similarity index 100% rename from en/application-dev/ui/figures/continuous-animation-effect.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223287696.gif diff --git a/en/application-dev/ui/figures/en-us_image_0000001169599582.png b/en/application-dev/device/ui/figures/en-us_image_0000001223287704.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001169599582.png rename to en/application-dev/device/ui/figures/en-us_image_0000001223287704.png diff --git a/en/application-dev/ui/figures/video_2021-10-21_105602.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223287708.gif similarity index 100% rename from en/application-dev/ui/figures/video_2021-10-21_105602.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223287708.gif diff --git a/en/application-dev/ui/figures/en-us_image_0000001169532276.png b/en/application-dev/device/ui/figures/en-us_image_0000001223287712.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001169532276.png rename to en/application-dev/device/ui/figures/en-us_image_0000001223287712.png diff --git a/en/application-dev/ui/figures/20211008-184455(welinkpc).gif b/en/application-dev/device/ui/figures/en-us_image_0000001223287716.gif similarity index 100% rename from en/application-dev/ui/figures/20211008-184455(welinkpc).gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223287716.gif diff --git a/en/application-dev/ui/figures/38.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223287720.gif similarity index 100% rename from en/application-dev/ui/figures/38.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223287720.gif diff --git a/en/application-dev/ui/figures/1-18.gif b/en/application-dev/device/ui/figures/en-us_image_0000001223287724.gif similarity index 100% rename from en/application-dev/ui/figures/1-18.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001223287724.gif diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001229510983.gif b/en/application-dev/device/ui/figures/en-us_image_0000001229510983.gif new file mode 100644 index 0000000000000000000000000000000000000000..56ad8e92f8376a00a0e5e201e7946144acb7659a Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001229510983.gif differ diff --git a/en/application-dev/ui/figures/en-us_image_0000001168956332.png b/en/application-dev/device/ui/figures/en-us_image_0000001267607861.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001168956332.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267607861.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001148858818.png b/en/application-dev/device/ui/figures/en-us_image_0000001267607865.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001148858818.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267607865.png diff --git a/en/application-dev/ui/figures/37.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267607869.gif similarity index 100% rename from en/application-dev/ui/figures/37.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267607869.gif diff --git a/en/application-dev/ui/figures/q8.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267607873.gif similarity index 100% rename from en/application-dev/ui/figures/q8.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267607873.gif diff --git a/en/application-dev/ui/figures/en-us_image_0000001169678922.png b/en/application-dev/device/ui/figures/en-us_image_0000001267607877.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001169678922.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267607877.png diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001267607881.png b/en/application-dev/device/ui/figures/en-us_image_0000001267607881.png new file mode 100644 index 0000000000000000000000000000000000000000..13b5b576503f783a01e729e9bb1f740e0c5b03ed Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001267607881.png differ diff --git a/en/application-dev/ui/figures/33.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267607885.gif similarity index 100% rename from en/application-dev/ui/figures/33.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267607885.gif diff --git a/en/application-dev/ui/figures/sample_css.png b/en/application-dev/device/ui/figures/en-us_image_0000001267607889.png similarity index 100% rename from en/application-dev/ui/figures/sample_css.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267607889.png diff --git a/en/application-dev/ui/figures/pixel-unit.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267607893.gif similarity index 100% rename from en/application-dev/ui/figures/pixel-unit.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267607893.gif diff --git a/en/application-dev/ui/figures/en-us_image_0000001215079443.png b/en/application-dev/device/ui/figures/en-us_image_0000001267607901.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001215079443.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267607901.png diff --git a/en/application-dev/ui/figures/17.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267607905.gif similarity index 100% rename from en/application-dev/ui/figures/17.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267607905.gif diff --git a/en/application-dev/ui/figures/routercategory.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267607909.gif similarity index 100% rename from en/application-dev/ui/figures/routercategory.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267607909.gif diff --git a/en/application-dev/ui/figures/7.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267607913.gif similarity index 100% rename from en/application-dev/ui/figures/7.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267607913.gif diff --git a/en/application-dev/ui/figures/1111.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267607921.gif similarity index 100% rename from en/application-dev/ui/figures/1111.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267607921.gif diff --git a/en/application-dev/ui/figures/en-us_image_0000001158896538.png b/en/application-dev/device/ui/figures/en-us_image_0000001267647841.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001158896538.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267647841.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001167746622.png b/en/application-dev/device/ui/figures/en-us_image_0000001267647849.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001167746622.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267647849.png diff --git a/en/application-dev/ui/figures/36.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267647853.gif similarity index 100% rename from en/application-dev/ui/figures/36.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267647853.gif diff --git a/en/application-dev/ui/figures/30.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267647857.gif similarity index 100% rename from en/application-dev/ui/figures/30.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267647857.gif diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001267647861.png b/en/application-dev/device/ui/figures/en-us_image_0000001267647861.png new file mode 100644 index 0000000000000000000000000000000000000000..cd29fb73e562d56acd907ffa221d347b14cb1812 Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001267647861.png differ diff --git a/en/application-dev/ui/figures/05.png b/en/application-dev/device/ui/figures/en-us_image_0000001267647865.png similarity index 100% rename from en/application-dev/ui/figures/05.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267647865.png diff --git a/en/application-dev/device/ui/figures/en-us_image_0000001267647869.png b/en/application-dev/device/ui/figures/en-us_image_0000001267647869.png new file mode 100644 index 0000000000000000000000000000000000000000..91179e770c418c02c3751111b14bbea637b48b1c Binary files /dev/null and b/en/application-dev/device/ui/figures/en-us_image_0000001267647869.png differ diff --git a/en/application-dev/ui/figures/en-us_image_0000001168728872.png b/en/application-dev/device/ui/figures/en-us_image_0000001267647873.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001168728872.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267647873.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001204538065.png b/en/application-dev/device/ui/figures/en-us_image_0000001267647881.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001204538065.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267647881.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001215113569.png b/en/application-dev/device/ui/figures/en-us_image_0000001267647885.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001215113569.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267647885.png diff --git a/en/application-dev/ui/figures/d1.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267647889.gif similarity index 100% rename from en/application-dev/ui/figures/d1.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267647889.gif diff --git a/en/application-dev/ui/figures/20211217-130837(welinkpc).gif b/en/application-dev/device/ui/figures/en-us_image_0000001267647893.gif similarity index 100% rename from en/application-dev/ui/figures/20211217-130837(welinkpc).gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267647893.gif diff --git a/en/application-dev/ui/figures/1-15.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267647897.gif similarity index 100% rename from en/application-dev/ui/figures/1-15.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267647897.gif diff --git a/en/application-dev/ui/figures/zan.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267647901.gif old mode 100755 new mode 100644 similarity index 100% rename from en/application-dev/ui/figures/zan.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267647901.gif diff --git a/en/application-dev/ui/figures/10.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267767837.gif similarity index 100% rename from en/application-dev/ui/figures/10.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267767837.gif diff --git a/en/application-dev/ui/figures/11-8.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267767841.gif similarity index 100% rename from en/application-dev/ui/figures/11-8.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267767841.gif diff --git a/en/application-dev/ui/figures/en-us_image_0000001168728272.png b/en/application-dev/device/ui/figures/en-us_image_0000001267767845.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001168728272.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267767845.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001204537865.png b/en/application-dev/device/ui/figures/en-us_image_0000001267767849.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001204537865.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267767849.png diff --git a/en/application-dev/ui/figures/q3.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267767853.gif similarity index 100% rename from en/application-dev/ui/figures/q3.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267767853.gif diff --git a/en/application-dev/ui/figures/31.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267767857.gif similarity index 100% rename from en/application-dev/ui/figures/31.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267767857.gif diff --git a/en/application-dev/ui/figures/27.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267767861.gif similarity index 100% rename from en/application-dev/ui/figures/27.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267767861.gif diff --git a/en/application-dev/ui/figures/8.png b/en/application-dev/device/ui/figures/en-us_image_0000001267767865.png similarity index 100% rename from en/application-dev/ui/figures/8.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267767865.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001169759552.png b/en/application-dev/device/ui/figures/en-us_image_0000001267767869.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001169759552.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267767869.png diff --git a/en/application-dev/ui/figures/34-12.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267767873.gif similarity index 100% rename from en/application-dev/ui/figures/34-12.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267767873.gif diff --git a/en/application-dev/ui/figures/3333.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267767877.gif similarity index 100% rename from en/application-dev/ui/figures/3333.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267767877.gif diff --git a/en/application-dev/ui/figures/en-us_image_0000001214998349.png b/en/application-dev/device/ui/figures/en-us_image_0000001267767881.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001214998349.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267767881.png diff --git a/en/application-dev/ui/figures/8-6.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267767885.gif similarity index 100% rename from en/application-dev/ui/figures/8-6.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267767885.gif diff --git a/en/application-dev/ui/figures/figures3.png b/en/application-dev/device/ui/figures/en-us_image_0000001267767889.png similarity index 100% rename from en/application-dev/ui/figures/figures3.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267767889.png diff --git a/en/application-dev/ui/figures/5-5.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267767893.gif similarity index 100% rename from en/application-dev/ui/figures/5-5.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267767893.gif diff --git a/en/application-dev/ui/figures/en-us_image_0000001215433095.png b/en/application-dev/device/ui/figures/en-us_image_0000001267767897.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001215433095.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267767897.png diff --git a/en/application-dev/ui/figures/28.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267887817.gif similarity index 100% rename from en/application-dev/ui/figures/28.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267887817.gif diff --git a/en/application-dev/ui/figures/3-2.png b/en/application-dev/device/ui/figures/en-us_image_0000001267887821.png similarity index 100% rename from en/application-dev/ui/figures/3-2.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267887821.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001168888224.png b/en/application-dev/device/ui/figures/en-us_image_0000001267887829.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001168888224.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267887829.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001204776353.png b/en/application-dev/device/ui/figures/en-us_image_0000001267887833.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001204776353.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267887833.png diff --git a/en/application-dev/ui/figures/d3.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267887837.gif similarity index 100% rename from en/application-dev/ui/figures/d3.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267887837.gif diff --git a/en/application-dev/ui/figures/111-13.png b/en/application-dev/device/ui/figures/en-us_image_0000001267887841.png similarity index 100% rename from en/application-dev/ui/figures/111-13.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267887841.png diff --git a/en/application-dev/ui/figures/8-4.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267887845.gif similarity index 100% rename from en/application-dev/ui/figures/8-4.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267887845.gif diff --git a/en/application-dev/ui/figures/1.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267887849.gif similarity index 100% rename from en/application-dev/ui/figures/1.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267887849.gif diff --git a/en/application-dev/ui/figures/en-us_image_0000001168570318.png b/en/application-dev/device/ui/figures/en-us_image_0000001267887853.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001168570318.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267887853.png diff --git a/en/application-dev/ui/figures/en-us_image_0000001168410342.png b/en/application-dev/device/ui/figures/en-us_image_0000001267887861.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001168410342.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267887861.png diff --git a/en/application-dev/ui/figures/111.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267887865.gif similarity index 100% rename from en/application-dev/ui/figures/111.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267887865.gif diff --git a/en/application-dev/ui/figures/video_2021-10-21_105956.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267887869.gif similarity index 100% rename from en/application-dev/ui/figures/video_2021-10-21_105956.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267887869.gif diff --git a/en/application-dev/ui/figures/11.png b/en/application-dev/device/ui/figures/en-us_image_0000001267887873.png similarity index 100% rename from en/application-dev/ui/figures/11.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267887873.png diff --git a/en/application-dev/ui/figures/qqqq.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267887877.gif similarity index 100% rename from en/application-dev/ui/figures/qqqq.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267887877.gif diff --git a/en/application-dev/ui/figures/en-us_image_0000001147417424.png b/en/application-dev/device/ui/figures/en-us_image_0000001267887881.png similarity index 100% rename from en/application-dev/ui/figures/en-us_image_0000001147417424.png rename to en/application-dev/device/ui/figures/en-us_image_0000001267887881.png diff --git a/en/application-dev/ui/figures/22.gif b/en/application-dev/device/ui/figures/en-us_image_0000001267887885.gif similarity index 100% rename from en/application-dev/ui/figures/22.gif rename to en/application-dev/device/ui/figures/en-us_image_0000001267887885.gif diff --git a/en/application-dev/device/ui/figures/unnaming-(1).png b/en/application-dev/device/ui/figures/unnaming-(1).png new file mode 100644 index 0000000000000000000000000000000000000000..b27b0977b2a668e11011c6106e9c53fe890b16db Binary files /dev/null and b/en/application-dev/device/ui/figures/unnaming-(1).png differ diff --git a/en/application-dev/device/ui/js-framework-file.md b/en/application-dev/device/ui/js-framework-file.md new file mode 100644 index 0000000000000000000000000000000000000000..caf71cb477dc28feaa479be5b2cf0e1e1ec345a5 --- /dev/null +++ b/en/application-dev/device/ui/js-framework-file.md @@ -0,0 +1,68 @@ +# File Organization + +## Directory Structure + +The following figure shows the typical directory structure of the JavaScript module \(entry/src/main/js/module\) for an application with feature abilities \(FA\) using JavaScript APIs. + +**Figure1** Directory structure + +![](figures/unnaming-(1).png) + +**Figure2** Directory structure for resource sharing 5+ + +![](figures/directory-structure-for-resource-sharing-5+.png "directory-structure-for-resource-sharing-5+") + +Functions of the files are as follows: + +- .hml files describe the page layout. +- .css files describe the page style. +- .js files process the interactions between pages and users. + +Functions of the folders are as follows: + +- The app.js file manages global JavaScript logics and application lifecycle. For details, see [app.js](js-framework-js-file.md). +- The pages directory stores all component pages. +- The common directory stores public resource files, such as media resources, custom components, and .js files. +- The resources directory stores resource configuration files, for example, for multi-resolution loading. For details, see [Resource Limitations and Access](js-framework-resource-restriction.md). +- The share directory5+ is used to configure resources shared by multiple instances. For example, images and JSON files in this directory can be shared by default1 and default2 instances. + +>![](public_sys-resources/icon-note.gif) **NOTE**: +>- Reserved folders \(i18n and resources\) cannot be renamed. +>- If the same resource name and directory are used under the share directory and the instance \(default\) directory, the resource in the instance directory will be used when you reference the directory. +>- The share directory does not support i18n. +>- You should create the optional folders \(shown in the directory structure\) as needed after you create the project in DevEco Studio. + +## File Access Rules + +Application resources can be accessed via an absolute or relative path. In the JS UI framework, an absolute path starts with a slash \(/\), and a relative path starts with ./ or ../. The rules are as follows: + +- To reference a code file, use a relative path, for example, ../common/utils.js. +- To reference a resource file, use an absolute path, for example, /common/xxx.png. +- Store code files and resource files in the common directory and access the files in a required fashion. +- In a .css file, use the url\(\) function to create a URL, for example, url\(/common/xxx.png\). + +>![](public_sys-resources/icon-note.gif) **NOTE**: +>When code file A needs to reference code file B: +> +>- If code files A and B are in the same directory, you can use either a relative or absolute path in code file B to reference resource files. +>- If code files A and B are in different directories, you must use an absolute path in code file B to reference resource files because the directory of code file B changes during Webpack packaging. +>- Use an absolute path if you want to dynamically change the resource file path through data binding in a .js file. + +## Media File Formats + +Table1 Supported image formats + +| Image Format | File Format | +| ------------ | ----------- | +| BMP | .bmp | +| GIF | .gif | +| JPEG | .jpg | +| PNG | .png | +| WebP | .webp | + +Table2 Supported video formats + +| Video Formats | File Format | +| ------------------------------- | ----------- | +| H.264 AVC Baseline Profile (BP) | .3gp .mp4 | + diff --git a/en/application-dev/device/ui/js-framework-js-file.md b/en/application-dev/device/ui/js-framework-js-file.md new file mode 100644 index 0000000000000000000000000000000000000000..f8fdc74c167642da160ad0f2fc0e0b09678b1266 --- /dev/null +++ b/en/application-dev/device/ui/js-framework-js-file.md @@ -0,0 +1,49 @@ +# app.js + + +## Application Lifecycle + + You can customize the [lifecycle](js-framework-lifecycle.md) implementation logic on an application-by-application basis in app.js. The following example only prints the corresponding logs in the lifecycle function: + +``` +// app.js +export default { + onCreate() { + console.info('Application onCreate'); + }, + + onDestroy() { + console.info('Application onDestroy'); + }, +} +``` + +## Application Object6+ + + | Attribute | Data Type | Description | +| -------- | -------- | -------- | +| getApp | Function | Obtains the object exposed in the app.js file from the custom .js file. | + +The following is a sample code snippet: + + +``` +// app.js +export default { + data: { + test: "by getAPP" + }, + onCreate() { + console.info('AceApplication onCreate'); + }, + onDestroy() { + console.info('AceApplication onDestroy'); + }, +}; +``` + + +``` +// test.js Customize the logic code. +export var appData = getApp().data; +``` diff --git a/en/application-dev/device/ui/js-framework-js-tag.md b/en/application-dev/device/ui/js-framework-js-tag.md new file mode 100644 index 0000000000000000000000000000000000000000..ad407559177d7a7c0cd39615341ef36a8560bd37 --- /dev/null +++ b/en/application-dev/device/ui/js-framework-js-tag.md @@ -0,0 +1,105 @@ +# "js" Tag + + +The "js" tag contains the instance name, window style, and page route information. + + + | Tag | Data Type | Default Value | Mandatory | Description | +| -------- | -------- | -------- | -------- | -------- | +| name | string | default | Yes | Name of the JavaScript instance. | +| pages | Array | - | Yes | Route information. For details, see ["pages"](#pages). | +| window | Object | - | No | Window information. For details, see ["window"](#window). | + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> The "name", "window", and "pages" tags are configured in the "js" tag of the config.json file. + + +## "pages" + +The "pages" defines the route information of each page. Each page consists of the page path and page name. The following is an example: + + +``` +{ + ... + "pages": [ + "pages/index/index", + "pages/detail/detail" + ] + ... +} +``` + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> +> - The first page in the pages list is the home page, also referred to as the entry, of the application. +> +> +> - The page name should not be a component name, for example, text.hml or button.hml. + +## window + +The "window" defines window-related configurations. To solve the screen adaptation problem, you can use either of the following methods: + +- Specify designWidth, which is the logical screen width. All size styles, such as width and font-size, are scaled at the ratio of designWidth to the physical screen width. For example, when designWidth is 720 px and if you set width to 100 px, the actual display width is scaled to 200 physical px on the screen whose physical width is 1440 px. + +- Set autoDesignWidth to true, the designWidth field will be ignored, and the component and layout will be scaled automatically based on the screen density. The logical screen width is automatically calculated based on the physical screen width and screen density. The logical screen width may vary depending on the device. Use the relative layout to adapt to different devices. For example, on a device with a resolution of 466x466 and 320 DPI (a screen density of 2x, with 160 DPI as the base), 1 px is equivalent to 2 physical px. + + > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: + > 1. The default <length> value in the current style is calculated based on the screen density. For example, if the screen density is x2 (with 160 DPI as the baseline) and the default <length> value is 1 px, the actual length rendered on the device is 2 physical px. + > + > 2. Values of autoDesignWidth and designWidth do not affect how the default <length> value is calculated and the final effect. +| Attribute | Type | Mandatory | Default Value | Description | +| -------- | -------- | -------- | -------- | -------- | +| | | | | | +| designWidth | number | No | 720
| Logical screen width, which is a reference value for page design. The actual display width is scaled at the ratio of the value to the device width. | +| autoDesignWidth | boolean | No | false | Whether to automatically calculate the baseline width. If autoDesignWidth is set to true, designWidth is ignored. The baseline width is calculated based on the physical screen width and screen density. | + +The following is a sample code snippet: + +``` +{ + ... + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + ... +} +``` + + +## Example + + +``` +{ + "app": { + "bundleName": "com.example.player", + "version": { + "code": 1, + "name": "1.0" + }, + "vendor": "example" + } + "module": { + ... + "js": [ + { + "name": "default", + "pages": [ + "pages/index/index", + "pages/detail/detail" + ], "window": { "designWidth": 720, "autoDesignWidth": false } + } + ], + "abilities": [ + { + ... + } + ] + } +} +``` diff --git a/en/application-dev/device/ui/js-framework-lifecycle.md b/en/application-dev/device/ui/js-framework-lifecycle.md new file mode 100644 index 0000000000000000000000000000000000000000..292415ca893d6a6b90164efea54994a459a7f042 --- /dev/null +++ b/en/application-dev/device/ui/js-framework-lifecycle.md @@ -0,0 +1,45 @@ +# Lifecycle + + +## Application Lifecycle + +You can define the following application lifecycle functions in the app.js file. + + | Attribute | Type | Description | Called When | +| -------- | -------- | -------- | -------- | +| onCreate | () => void | Listens for application creation. | The application is created. | +| onShow6+ | () => void | Listens for whether the application is running in the foreground. | The application is running in the foreground. | +| onHide6+ | () => void | Listens for whether the application is running in the background. | The application is running in the background. | +| onDestroy | () => void | Listens for application uninstallation. | The application exits. | + +## Page Lifecycle + +You can define the following page lifecycle functions in the .js file of the page. + +| Attribute | Type | Description | Called When | +| -------- | -------- | -------- | -------- | +| onInit | () => void | Listens for page initialization. | Page initialization is complete. This function is called only once in the page lifecycle. | +| onReady | () => void | Listens for page creation. | A page is created. This function is called only once in the page lifecycle. | +| onShow | () => void | Listens for page display. | The page is displayed. | +| onHide | () => void | Listens for page disappearance. | The page disappears. | +| onDestroy | () => void | Listens for page destruction. | The page is destroyed. | +| onBackPress | () => boolean | Listens for the back button action. | The back button is touched.
- true means that the page processes the return logic.
- false means that the default return logic is used.
- If no value is returned, the default return logic is used. | +| onActive()5+ | () => void | Listens for page activation. | The page is activated. | +| onInactive()5+ | () => void | Listens for page suspension. | The page is suspended. | +| onNewRequest()5+ | () => void | Listens for a new FA request. | The FA has been started and a new request is received. | + + The lifecycle functions of page A are called in the following sequence: +- Open page A: onInit() -> onReady() -> onShow() + +- Open page B on page A: onHide() + +- Go back to page A from page B: onShow() + +- Exit page A: onBackPress() -> onHide() -> onDestroy() + +- Hide page A: onInactive() -> onHide() + +- Show background page A on the foreground: onShow() -> onActive() + +![en-us_image_0000001267887881](figures/en-us_image_0000001267887881.png) + diff --git a/en/application-dev/device/ui/js-framework-multiple-languages.md b/en/application-dev/device/ui/js-framework-multiple-languages.md new file mode 100644 index 0000000000000000000000000000000000000000..0405f3f9a0a22cfb83c713356af6f11e4cd33580 --- /dev/null +++ b/en/application-dev/device/ui/js-framework-multiple-languages.md @@ -0,0 +1,195 @@ +# Multi-Language Capability + + +Applications designed based on the JS UI framework apply to different countries and regions. With the multi-language capability, you do not need to develop application versions in different languages, and your users can switch between various locales. This also facilitates project maintenance. + + +You only need to perform operations in [Resource Files](#resource-files) and [Resource Reference](#resource-reference) to use the multi-language capability of this framework. For details about how to obtain the current system language, see [Language Acquisition](#language-acquisition). + + +## Resource Files + +Resource files store application content in multiple languages. This framework uses JSON files to store resource definitions. Place the resource file of each locale in the i18n directory described in [File Organization](js-framework-file.md). + +Resource files should be named in _language-script-region_.json format. For example, the resource file for Hong Kong Chinese in the traditional script is named zh-Hant-HK. You can omit the region, for example, zh-CN for simplified Chinese, or omit both the script and region, for example, zh for Chinese. + + +``` +language[-script-region].json +``` + +The following table describes the requirements for the qualifiers of resource file names. + + Table1 Requirements for qualifier values + +| Qualifier Type | Description and Value Range | +| -------- | -------- | +| Language | Indicates the language used by the device. The value consists of two or three lowercase letters, for example, zh indicates Chinese, en indicates English, and mai indicates Maithili.
For details about the value range, refer to ISO 639 (codes for the representation of names of languages). | +| Script | Indicates the script type used by the device. The value starts with one uppercase letter followed by three lowercase letters, for example, Hans indicates simplified Chinese and Hant indicates traditional Chinese.
For details about the value range, refer to ISO 15924 (codes for the representation of names of scripts). | +| Country/Region | Indicates the country or region where a user is located. The value consists of two or three uppercase letters or three digits, for example, CN indicates China and GB indicates the United Kingdom.
For details about the value range, refer to ISO 3166-1 (codes for the representation of names of countries and their subdivisions). | + +If there is no resource file of the locale that matches the system language, content in the en-US.json file will be used by default. + +The format of the resource file content is as follows: + + en-US.json + +``` +{ + "strings": { + "hello": "Hello world!", + "object": "Object parameter substitution-{name}", + "array": "Array type parameter substitution-{0}", + "symbol": "@#$%^&*()_+-={}[]\\|:;\"'<>,./?" + }, + + "files": { + "image": "image/en_picture.PNG" + } +} +``` + + +Different languages have different matching rules for singular and plural forms. In the resource file, zero, one, two, few, many, and other are used to define the string content in different singular and plural forms. For example, there is only the other scenario in Chinese since the language does not have singular and plural forms. one and other scenarios are applicable to English. All six scenarios are needed for Arabic. + + +The following example takes en-US.json and ar-AE.json as examples: + + +en-US.json + + +``` +{ + "strings": { + "people": { + "one": "one person", + "other": "{count} people" + } + } +} +``` + + +ar-AE.json + + +``` +{ + "strings": { + "people": { + "zero": "لا أحد", + "one": "وحده", + "two": "اثنان", + "few": "ستة اشخاص", + "many": "خمسون شخص", + "other": "مائة شخص" + } + } +} +``` + + +## Resource Reference + +Multi-language syntax used on application development pages (including simple formatting and singular-plural formatting) can be used in .hml or .js files. + +- Simple formatting + Use the $t function to reference to resources of different locales. The $t function is available for both .hml and .js files. The system displays content based on a resource file path specified via $t and the specified resource file whose locale matches the current system language. + + Table2 Simple formatting + + | Attribute | Type | Parameter | Mandatory | Description | + | -------- | -------- | -------- | -------- | -------- | + | $t | Function | See Table3 | Yes | Sets the parameters based on the system language, for example, this.$t('strings.hello'). | + + Table3 $t function parameters + + | Parameter | Type | Mandatory | Description | + | -------- | -------- | -------- | -------- | + | path | string | Yes | Path of the language resource key | + | params | Array\|Object | No | Content used to replace placeholders during runtime. There are two types of placeholders available:
- Named placeholder, for example, {name}. The actual content must be of the object type, for example, $t('strings.object', { name: 'Hello world' }).
- Digit placeholder, for example, {0}. The actual content must be of the array type, for example, $t('strings.array', ['Hello world']. | + +- Example code for simple formatting + + ``` + +
+ + {{ $t('strings.hello') }} + + {{ $t('strings.object', { name: 'Hello world' }) }} + + {{ $t('strings.array', ['Hello world']) }} + + {{ hello }} + + {{ replaceObject }} + + {{ replaceArray }} + + + + + +
+ ``` + + + ``` + // xxx.js + // The following example uses the $t function in the .js file. + export default { + data: { + hello: '', + replaceObject: '', + replaceArray: '', + replaceSrc: '', + }, + onInit() { + this.hello = this.$t('strings.hello'); + this.replaceObject = this.$t('strings.object', { name: 'Hello world' }); + this.replaceArray = this.$t('strings.array', ['Hello world']); + this.replaceSrc = this.$t('files.image'); + }, + } + ``` + +- Singular-plural formatting + Table4 Singular-plural formatting + + | Attribute | Type | Parameter | Mandatory | Description | + | -------- | -------- | -------- | -------- | -------- | + | $tc | Function | See Table 5. | Yes | Converts between the singular and plural forms based on the system language, for example, this.$tc('strings.people').
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> The resource content is distinguished by the following JSON keys: zero, one, two, few, many, and other. | + + Table5 $tc function parameters + + | Parameter | Type | Mandatory | Description | + | -------- | -------- | -------- | -------- | + | path | string | Yes | Path of the language resource key | + | count | number | Yes | Number | + +- Sample code for singular-plural formatting + + ``` + +
+ + {{ $tc('strings.people', 0) }} + + {{ $tc('strings.people', 1) }} + + {{ $tc('strings.people', 2) }} + + {{ $tc('strings.people', 6) }} + + {{ $tc('strings.people', 50) }} + + {{ $tc('strings.people', 100) }} +
+ ``` + + +## Language Acquisition + +For details about how to obtain the language, see the Application Configuration section. diff --git a/en/application-dev/device/ui/js-framework-resource-restriction.md b/en/application-dev/device/ui/js-framework-resource-restriction.md new file mode 100644 index 0000000000000000000000000000000000000000..8636ebfd2197cb2b1a875d522b6d7469816b01c3 --- /dev/null +++ b/en/application-dev/device/ui/js-framework-resource-restriction.md @@ -0,0 +1,95 @@ +# Resource Limitations and Access + + +## Resource Qualifiers + +The name of a resource qualifier consists of one or more qualifiers that represent the application scenarios or device characteristics, covering the screen density, and more. The qualifiers are separated using hyphens (-). When creating a qualifiers file under resources, you need to understand the file naming conventions and the rules for matching qualifiers files and the device status. + + +## Naming Conventions for Resource Qualifiers + +- Qualifiers are ordered in the following sequence: screen density. You can select one or multiple qualifiers to name your file based on your application scenarios and device characteristics, while following the preceding sequence. + +- The qualifiers are separated using hyphens (-), for example, res-dark-ldpi.json. + +- Value range of qualifiers: The value of each qualifier must meet the requirements specified in the following table. Otherwise, the resource files in the resources directory cannot be matched. The qualifiers are case sensitive. + +- Qualifier prefix: The name of a qualifier file in the resources file has the prefix res, for example, res-ldpi.json. + +- Default resource qualifier file: By default, the resource qualifier file in resources is res-defaults.json. + +- In the resource qualifier file, color enumeration cannot be used to set resources. + + + Table1 Resource qualifiers + +| Data Type | Description and Value Range | +| -------- | -------- | +| Screen density | Indicates the screen density of the device, in dpi. The value can be:
- ldpi: low-density screen (~120 dpi) (0.75 x Reference density)
- mdpi: medium-density screen (~160 dpi) (reference density)
- hdpi: high-density screen (~240 dpi) (1.5 x Reference density)
- xhdpi: extra high-density screen (~320 dpi) (2.0 x Reference density)
- xxhdpi: extra extra high-density screen (~480 dpi) (3.0 x Reference density)
- xxxhdpi: extra extra extra high-density screen (~640 dpi) (4.0 x Reference density) | + + +## Rules for Matching Qualifiers Files and Device Resources + +- Qualifiers are matched with the device resources in the following priorities: screen orientation > dark mode > screen density. If no matching resource qualifier file is found, the default resource qualifier file is used. + +- If a qualifier file contains resource qualifiers, their values must be consistent with the current device status so that the file can be used for matching the device status. For example, the res-hdpi.json qualifier file does not match the device density xhdpi. + + +## Referencing Resources in the JS Module + +You can use the $r syntax in the application development files .hml and .js to format the JSON resources in the resources directory of the JS module and obtain the corresponding resources. + +| Attribute | Type | Description | +| -------- | -------- | -------- | +| $r | (key: string) => string | Obtains the resource content that matches the specific qualifiers, for example, this.$r('strings.hello loaded).
Parameter description:
- key: key value defined in the resource qualifier file, for example, strings.hello.
| + +Example of res-defaults.json:
+ +``` +{ + strings: { + hello: 'hello world' + } +} +``` + +## Example + +resources/res-dark.json: + + +``` +{ + "image": { + "clockFace": "common/dark_face.png" + }, + "colors": { + "background": "#000000" + } +} +``` + +resources/res-defaults.json: + + +``` +{ + "image": { + "clockFace": "common/face.png" + }, + "colors": { + "background": "#ffffff" + } +} +``` + + +``` + +
+ +
+``` + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> The resource qualifier file does not support color enumeration. diff --git a/en/application-dev/device/ui/js-framework-syntax-css.md b/en/application-dev/device/ui/js-framework-syntax-css.md new file mode 100644 index 0000000000000000000000000000000000000000..6f4c8e3f3253e0ea9d82b84f180ad3d8d12787b2 --- /dev/null +++ b/en/application-dev/device/ui/js-framework-syntax-css.md @@ -0,0 +1,225 @@ +# CSS + + +Cascading Style Sheets (CSS) is a language used to describe the HML page structure. All HML components have default styles. You can customize styles for these components using CSS to design various pages. + +## Size Unit + +1. Logical px set by <length>: + 1. The default logical screen width is 720 px (for details, see the "window" section in [config.json](js-framework-js-tag.md)). Your page will be scaled to fit the actual width of the screen. For example, on a screen with the actual width of 1440 physical px, 100 px is displayed on 200 physical px, with all sizes doubled from 720 px to 1440 px. + 2. If you set autoDesignWidth to true (for details, see the "window" section in [config.json](js-framework-js-tag.md)), the logical px are scaled based on the screen density. For example, if the screen density is 3x, 100 px will be rendered on 300 physical px. This approach is recommended when your application needs to adapt to multiple devices. + +2. Percentage set by <percentage>: The component size is represented by its percentage of the parent component size. For example, if the width <percentage> of a component is set to 50%, the width of the component is half of its parent component's width. + + +## Style Import + +CSS files can be imported using the @import statement. This facilitates module management and code reuse. + + +## Style Declaration + +The .css file with the same name as the .hml file in each page directory describes the styles of components on the HML page, determining how the components will be displayed. + +1. Internal style: The style and class attributes can be used to specify the component style. Example: + + ``` + +
+ Hello World +
+ ``` + + + ``` + /* index.css */ + .container { + justify-content: center; + } + ``` + +2. External style files: You need to import the files. For example, create a style.css file in the common directory and import the file at the beginning of index.css. + + ``` + /* style.css */ + .title { + font-size: 50px; + } + ``` + + + ``` + /* index.css */ + @import '../../common/style.css'; + .container { + justify-content: center; + } + ``` + + +## Selectors + +A CSS selector is used to select elements for which styles need to be added to. The following table lists the supported selectors. + +| Selector | Example | Description | +| -------- | -------- | -------- | +| .class | .container | Selects all components whose class is container. | +| \#id | \#titleId | Selects all components whose id is titleId. | +| tag | text | Selects all <text> components. | +| , | .title, .content | Selects all components whose class is title or content. | +| \#id .class tag | \#containerId .content text | Selects all grandchild <text> components whose grandparent components are identified as containerId and whose parent components are of the content class. To select child components, use > to replace the space between \#id and .class, for example, \#containerId>.content. | + +The following is an example: + + +``` + +
+ Title +
+ Content +
+
+``` + + +``` +/* Page style xxx.css */ +/* Set the style for all
components. */ +div { + flex-direction: column; +} +/* Set the style for the component whose class is title. */ +.title { + font-size: 30px; +} +/* Set the style for the component whose id is contentId. */ +#contentId { + font-size: 20px; +} +/* Set padding for all components of the title or content class to 5 px. */ +.title, .content { + padding: 5px; +} +/* Set the style for all texts of components whose class is container. + */ +.container text { + color: #007dff; +} +/* Set the style for direct descendant texts of components whose class is container. +*/ +.container > text { + color: #fa2a2d; +} +``` + +The above style works as follows: + +![en-us_image_0000001267607889](figures/en-us_image_0000001267607889.png) + +In the preceding example, .container text sets title and content to blue, and .container > text sets title to red. The two styles have the same priority, but .container > text declares the style later and overwrites the former style. (For details about the priority, see [Selector Specificity](#selector-specificity).) + +## Selector Specificity + +The specificity rule of the selectors complies with the W3C rule, which is only available for inline styles, id, class, tag, grandchild components, and child components. (Inline styles are those declared in the style attribute.) + +When multiple selectors point to the same element, their priorities are as follows (in descending order): inline style > id > class > tag. + + +## Pseudo-classes + +A CSS pseudo-class is a keyword added to a selector that specifies a special state of the selected element(s). For example, :disabled can be used to select the element whose disabled attribute is true. + +In addition to a single pseudo-class, a combination of pseudo-classes is supported. For example, :focus:checked selects the element whose focus and checked attributes are both set to true. The following table lists the supported single pseudo-class in descending order of priority. + + | Pseudo-class | Available Components | Description | +| -------- | -------- | -------- | +| :disabled | Components that support the disabled attribute | Selects the element whose disabled attribute is changed to true (unavailable for animation attributes). | +| :focus | Components that support the focusable attribute | Selects the element that takes focus (unavailable for animation attributes). | +| :active | Components that support the click event
| Selects the element activated by a user. For example, a pressed button or a selected tab-bar (unavailable for animation attributes). | +| :waiting | button | Selects the element whose waiting attribute is true (unavailable for animation attributes). | +| :checked | input[type="checkbox", type="radio"], and switch | Selects the element whose checked attribute is true (unavailable for animation attributes). | +| :hover6+ | Components that support the mouseover event | Selects the element that the cursor is on. | + +The following is an example for you to use the :active pseudo-class to control the style when a user presses the button. + + +``` + +
+ +
+``` + + +``` +/* index.css */ +.button:active { + background-color: #888888;/* After the button is activated, the background color is changed to #888888. */ +} +``` + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> Pseudo-classes are not supported for the component and its child components, including, , ,
``` + ``` // xxx.js export default { @@ -235,24 +248,30 @@ export default { } ``` -The **tid** attribute accelerates the **for** loop and improves the re-rendering efficiency when data in a loop changes. +The tid attribute accelerates the for loop and improves the re-rendering efficiency when data in a loop changes. + +The tid attribute specifies the unique ID of each element in the array. If it is not specified, the index of each element in the array is used as the ID. For example, tid="id" indicates that the id attribute of each element is its unique ID. + +The for loop supports the following statements: + +- for="array": array is an array object, whose element variable is $item by default. -The **tid** attribute specifies the unique ID of each element in the array. If it is not specified, the index of each element in the array is used as the ID. For example, **tid="id"** indicates that the **id** attribute of each element is its unique ID. +- for="v in array": v is a custom element variable, whose index is $idx by default. -The **for** loop supports the following statements: +- for="(i, v) in array": i indicates the element index, and v indicates the element variable. All elements of the array object will be looped through. -- for="array": **array** is an array object, whose element variable is **$item** by default. -- for="v in array": **v** is a custom element variable, whose index is **$idx** by default. -- for="\(i, v\) in array": **i** indicates the element index, and **v** indicates the element variable. All elements of the array object will be looped through. +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - Each element in the array must have the data attribute specified by tid. Otherwise, an exception may occur. +> +> - The attribute specified by tid in the array must be unique. Otherwise, performance loss occurs. In the above example, only id and name can be used as tid because they are unique fields. +> +> - The tid field does not support expressions. ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- Each element in the array must have the data attribute specified by **tid**. Otherwise, an exception may occur. ->- The attribute specified by **tid** in the array must be unique. Otherwise, performance loss occurs. In the above example, only **id** and **name** can be used as **tid** because they are unique fields. ->- The **tid** field does not support expressions. -## Conditional Rendering +## Conditional Rendering + +There are two ways to implement conditional rendering: if-elif-else or show. In if-elif-else, when the if statement evaluates to false, the component is not built in the VDOM and is not rendered. For show, when show is false, the component is not rendered but is built in the VDOM. In addition, the if-elif-else statements must be used in sibling nodes. Otherwise, the compilation fails. The following example uses both ways to implement conditional rendering: -There are two ways to implement conditional rendering: **if-elif-else** or **show**. In **if-elif-else**, when the **if** statement evaluates to **false**, the component is not built in the VDOM and is not rendered. For **show**, when show is **false**, the component is not rendered but is built in the VDOM. In addition, the **if-elif-else** statements must be used in sibling nodes. Otherwise, the compilation fails. The following example uses both ways to implement conditional rendering: ``` @@ -265,6 +284,7 @@ There are two ways to implement conditional rendering: **if-elif-else** or ** ``` + ``` /* xxx.css */ .container{ @@ -278,6 +298,7 @@ There are two ways to implement conditional rendering: **if-elif-else** or ** } ``` + ``` // xxx.js export default { @@ -294,7 +315,8 @@ export default { } ``` -In the optimized rendering \(**show**\), if **show** is **true**, the node is rendered properly; if it is **false**, the display style will be **none**. +In the optimized rendering (show), if show is true, the node is rendered properly; if it is false, the display style will be none. + ``` @@ -304,6 +326,7 @@ In the optimized rendering \(**show**\), if **show** is **true**, the node is ``` + ``` /* xxx.css */ .container{ @@ -317,6 +340,7 @@ In the optimized rendering \(**show**\), if **show** is **true**, the node is } ``` + ``` // xxx.js export default { @@ -329,12 +353,13 @@ export default { } ``` ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->Do not use **for** and **if** attributes at the same time in an element. +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> Do not use for and if attributes at the same time in an element. -## Logic Control Block +## Logic Control Block + + makes loop rendering and conditional rendering more flexible. A will not be compiled as a real component. **NOTE** that the tag supports only the for and if attributes. -**** makes loop rendering and conditional rendering more flexible. A **** will not be compiled as a real component. Note that the **** tag supports only the **for** and **if** attributes. ``` @@ -352,6 +377,7 @@ export default { ``` + ``` // xxx.js export default { @@ -364,9 +390,10 @@ export default { } ``` -## Template Reference +## Template Reference + +HML supports using elements to reference template files. For details, see Custom Components. -HML supports using elements to reference template files. For details, see [Custom Components](../reference/arkui-js/js-components-custom.md). ``` @@ -376,6 +403,7 @@ HML supports using elements to reference template files. For details, see [Cust ``` + ``` @@ -383,4 +411,3 @@ HML supports using elements to reference template files. For details, see [Cust ``` - diff --git a/en/application-dev/ui/js-framework-syntax-js.md b/en/application-dev/ui/js-framework-syntax-js.md index 9742330e0e9f05f1e15d6f901edceb2937e91cf5..6651a84e33a77efe6020a087a830150b3d71f783 100644 --- a/en/application-dev/ui/js-framework-syntax-js.md +++ b/en/application-dev/ui/js-framework-syntax-js.md @@ -1,449 +1,234 @@ -# JavaScript +# JavaScript -You can use a **.js** file to define the service logic of an HML page. The JS UI framework supports the JavaScript language that conforms to the ECMAScript specification. With dynamic typing, JavaScript can make your application more expressive with a flexible design. The following describes the JavaScript compilation and running. -## Syntax +You can use a .js file in the ECMAScript compliant JavaScript language to define the service logic of an HML page. With dynamic typing, JavaScript can make your application more expressive with a flexible design. The following describes the JavaScript compilation and running. -The ES6 syntax is supported. -- **Module declaration** +## Syntax - Import functionality modules. +The ES6 syntax is supported. - ``` - import router from '@system.router'; - ``` +- Module declaration + Import functionality modules. -- **Code reference** + + ``` + import router from '@system.router'; + ``` - Import JavaScript code. +- Code reference + Import JavaScript code. - ``` - import utils from '../../common/utils.js'; - ``` + + ``` + import utils from '../../common/utils.js'; + ``` -## Objects +## Objects -- **Application Object** +- Application Object + | Attribute | Type | Description | + | -------- | -------- | -------- | + | $def | Object | Object that is exposed in the app.js file and obtained by this.$app.$def.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> Application objects do not support data binding. Data update should be triggered on the UI. | - - - - - - - - - - - -

Attribute

-

Type

-

Description

-

$def

-

Object

-

Object that is exposed in the app.js file and obtained by this.$app.$def.

-
NOTE:

Application objects do not support data binding. Data update should be triggered on the UI.

-
-
+ Example Code - Example Code - - ``` - // app.js - export default { - onCreate() { - console.info('Application onCreate'); - }, - onDestroy() { - console.info('Application onDestroy'); - }, - globalData: { - appData: 'appData', - appVersion: '2.0', - }, - globalMethod() { - console.info('This is a global method!'); - this.globalData.appVersion = '3.0'; - } - }; - ``` - - ``` - // index.js - export default { - data: { - appData: 'localData', - appVersion:'1.0', - }, - onInit() { - this.appData = this.$app.$def.globalData.appData; - this.appVersion = this.$app.$def.globalData.appVersion; - }, - invokeGlobalMethod() { - this.$app.$def.globalMethod(); - }, - getAppVersion() { - this.appVersion = this.$app.$def.globalData.appVersion; - } + + ``` + // app.js + export default { + onCreate() { + console.info('AceApplication onCreate'); + }, + onDestroy() { + console.info('AceApplication onDestroy'); + }, + globalData: { + appData: 'appData', + appVersion: '2.0', + }, + globalMethod() { + console.info('This is a global method!'); + this.globalData.appVersion = '3.0'; } - ``` - -- **Page objects** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Attribute

-

Type

-

Description

-

data

-

Object/Function

-

Data model of the page. If the attribute is of the function type, the return value must be of the object type. The attribute name cannot start with a dollar sign ($) or underscore (_). Do not use reserved words (for, if, show, and tid).

-

Do not use this attribute and private or public at the same time.

-

$refs

-

Object

-

DOM elements or child component instances that have registered the ref attribute. For example code, see Obtaining a DOM element.

-

private

-

Object

-

Data model of the page. Private data attribute can be modified only on the current page.

-

public

-

Object

-

Data model of the page. Behaviors of public data attributes are the same as those of the data attribute.

-

props

-

Array/Object

-

Used for communication between components. This attribute can be transferred to components via <tag xxxx='value'>. A props name must be in lowercase and cannot start with a dollar sign ($) or underscore (_). Do not use reserved words (for, if, show, and tid). Currently, props does not support functions. For details, see Custom Components.

-

computed

-

Object

-

Used for pre-processing an object for reading and setting. The result is cached. The name cannot start with a dollar sign ($) or underscore (_). Do not use reserved words. For details, see Custom Components.

-
- - -## Functions - -- **Data functions** - - - - - - - - - - - - - - - - -

Function

-

Parameter

-

Description

-

$set

-

key: string, value: any

-

Adds an attribute or modifies an existing attribute.

-

Usage:

-

this.$set('key',value): Add an attribute.

-

$delete

-

key: string

-

Deletes an attribute.

-

Usage:

-

this.$delete('key'): Delete an attribute.

-
- - Example Code - - ``` - export default { - data: { - keyMap: { - OS: 'OpenHarmony', - Version: '2.0', - }, - }, - getAppVersion() { - this.$set('keyMap.Version', '3.0'); - console.info("keyMap.Version = " + this.keyMap.Version); // keyMap.Version = 3.0 - - this.$delete('keyMap'); - console.info("keyMap.Version = " + this.keyMap); // log print: keyMap.Version = undefined - } + }; + ``` + + + ``` + // index.js + export default { + data: { + appData: 'localData', + appVersion:'1.0', + }, + onInit() { + this.appData = this.$app.$def.globalData.appData; + this.appVersion = this.$app.$def.globalData.appVersion; + }, + invokeGlobalMethod() { + this.$app.$def.globalMethod(); + }, + getAppVersion() { + this.appVersion = this.$app.$def.globalData.appVersion; } - ``` - -- **Public functions** - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function

-

Parameter

-

Description

-

$element

-

id: string

-

Obtains the component with a specified ID. If no ID is specified, the root component is returned. For example code, see Obtaining a DOM element.

-

Usage:

-

<div id='xxx'></div>

-
  • this.$element('xxx'): Obtain the component whose ID is xxx.
  • this.$element(): Obtain the root component.
-

$rootElement

-

None

-

Obtains the root element.

-

Usage: this.$rootElement().scrollTo({ duration: 500, position: 300 }), which scrolls the page by 300 px within 500 ms.

-

$root

-

N/A

-

Obtains the root ViewModel instance. For example code, see Obtaining the ViewModel.

-

$parent

-

N/A

-

Obtains the parent ViewModel instance. For example code, see Obtaining the ViewModel.

-

$child

-

id: string

-

Obtains the ViewModel instance of a custom child component with a specified ID. For example code, see Obtaining the ViewModel.

-

Usage:

-

this.$child('xxx'): Obtain the ViewModel instance of a custom child component whose ID is xxx.

-
- -- **Event function** - - - - - - - - - - - - -

Function

-

Parameter

-

Description

-

$watch

-

data: string, callback: string | Function

-

Listens for attribute changes. If the value of the data attribute changes, the bound event is triggered. For details, see Custom Components.

-

Usage:

-

this.$watch('key', callback)

-
- -- **Page function** - - - - - - - - - - - - -

Function

-

Parameter

-

Description

-

scrollTo6+

-

scrollPageParam: ScrollPageParam

-

Scrolls the page to the target position. You can specify the position using the ID selector or scrolling distance.

-
- - **Table 1** ScrollPageParam6+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Name

-

Type

-

Default Value

-

Description

-

position

-

number

-

-

-

Position to scroll to.

-

id

-

string

-

-

-

ID of the element to be scrolled to.

-

duration

-

number

-

300

-

Scrolling duration, in milliseconds.

-

timingFunction

-

string

-

ease

-

Animation curve for scrolling. Available option:

-

animation-timing-function

-

complete

-

() => void

-

-

-

Callback to be invoked when the scrolling is complete.

-
- - Example: - - ``` - this.$rootElement.scrollTo({position: 0}) - this.$rootElement.scrollTo({id: 'id', duration: 200, timingFunction: 'ease-in', complete: ()=>void}) - ``` - - -## Obtaining a DOM Element - -1. Use **$refs** to obtain a DOM element. - - ``` - -
- -
- ``` - - ``` - // index.js - export default { - data: { - images: [ - { src: '/common/frame1.png' }, - { src: '/common/frame2.png' }, - { src: '/common/frame3.png' }, - ], - }, - handleClick() { - const animator = this.$refs.animator; // Obtain the DOM element whose $refs attribute is animator. - const state = animator.getState(); - if (state === 'paused') { - animator.resume(); - } else if (state === 'stopped') { - animator.start(); - } else { - animator.pause(); - } - }, - }; - ``` - -2. Call **$element** to obtain a DOM element. - - ``` - -
- -
- ``` - - ``` - // index.js - export default { - data: { - images: [ - { src: '/common/frame1.png' }, - { src: '/common/frame2.png' }, - { src: '/common/frame3.png' }, - ], - }, - handleClick() { - const animator = this.$element('animator'); // Obtain the DOM element whose ID is animator. - const state = animator.getState(); - if (state === 'paused') { - animator.resume(); - } else if (state === 'stopped') { - animator.start(); - } else { - animator.pause(); - } + } + ``` + +- Page objects + | Attribute | Type | Description | + | -------- | -------- | -------- | + | data | Object/Function | Data model of the page. If the attribute is of the function type, the return value must be of the object type. The attribute name cannot start with a dollar sign ($) or underscore (_). Do not use reserved words (for, if, show, and tid).
Do not use this attribute and private or public at the same time. | + | $refs | Object | DOM elements or child component instances that have registered the ref attribute. For example code, see [Obtaining a DOM element](#obtaining-a-dom-element). | + | private | Object | Data model of the page. Private data attribute can be modified only on the current page. | + | public | Object | Data model of the page. Behaviors of public data attributes are the same as those of the data attribute. | + | props | Array/Object | Used for communication between components. This attribute can be transferred to components via <tag xxxx='value'>. A props name must be in lowercase and cannot start with a dollar sign ($) or underscore (_). Do not use reserved words (for, if, show, and tid). Currently, props does not support functions. For details, see [Custom Component](../reference/arkui-js/js-components-custom-props.md). | + | computed | Object | Used for pre-processing an object for reading and setting. The result is cached. The name cannot start with a dollar sign ($) or underscore (_). Do not use reserved words. For details, see [Custom Component](../reference/arkui-js/js-components-custom-props.md). | + +## Functions + +- Data functions + | Function | Parameter | Description | + | -------- | -------- | -------- | + | $set | key: string, value: any | Adds an attribute or modifies an existing attribute.
Usage:
this.$set('_key_',_value_): Add an attribute. | + | $delete | key: string | Deletes an attribute.
Usage:
this.$delete('_key_'): Delete an attribute. | + + Example Code + + + ``` + // index.js + export default { + data: { + keyMap: { + OS: 'OpenHarmony', + Version: '2.0', }, - }; - ``` - - -## Obtaining the ViewModel + }, + getAppVersion() { + this.$set('keyMap.Version', '3.0'); + console.info("keyMap.Version = " + this.keyMap.Version); // keyMap.Version = 3.0 + + this.$delete('keyMap'); + console.info("keyMap.Version = " + this.keyMap); // log print: keyMap.Version = undefined + } + } + ``` + +- Public functions + | Function | Parameter | Description | + | -------- | -------- | -------- | + | $element | id: string | Obtains the component with a specified ID. If no ID is specified, the root component is returned. For example code, see [Obtaining a DOM element](#obtaining-a-dom-element).
Usage:
```
```
- this.$element('_xxx_'): Obtain the component whose ID is _xxx_.
- this.$element(): Obtain the root component. | + | $rootElement | None | Obtains the root element.
Usage: this.$rootElement().scrollTo({ duration: 500, position: 300 }), which scrolls the page by 300 px within 500 ms. | + | $root | N/A | Obtains the root ViewModel instance. For example code, see [Obtaining the ViewModel](#obtaining-the-viewmodel). | + | $parent | N/A | Obtains the parent ViewModel instance. For example code, see [Obtaining the ViewModel](#obtaining-the-viewmodel). | + | $child | id: string | Obtains the ViewModel instance of a custom child component with a specified ID. For example code, see [Obtaining the ViewModel](#obtaining-the-viewmodel).
Usage:
this.$child('_xxx_'): Obtain the ViewModel instance of a custom child component whose ID is _xxx_. | + +- Event function + | Function | Parameter | Description | + | -------- | -------- | -------- | + | $watch | data: string, callback: string \| Function | Listens for attribute changes. If the value of the data attribute changes, the bound event is triggered. For details, see [Custom Component](../reference/arkui-js/js-components-custom-props.md)
Usage:
this.$watch('_key_',_callback_) | + +- Page function + | Function | Parameter | Description | + | -------- | -------- | -------- | + | scrollTo6+ | scrollPageParam: ScrollPageParam | Scrolls the page to the target position. You can specify the position using the ID selector or scrolling distance. | + + Table1 ScrollPageParam6+ + + | Name | Type | Default Value | Description | + | -------- | -------- | -------- | -------- | + | position | number | - | Position to scroll to. | + | id | string | - | ID of the element to be scrolled to. | + | duration | number | 300 | Scrolling duration, in milliseconds. | + | timingFunction | string | ease | Animation curve for scrolling. Available option:
[Animation Styles](../reference/arkui-js/js-components-common-animation.md) | + | complete | () => void | - | Callback to be invoked when the scrolling is complete. | + + Example: + + + ``` + this.$rootElement.scrollTo({position: 0}) + this.$rootElement.scrollTo({id: 'id', duration: 200, timingFunction: 'ease-in', complete: ()=>void}) + ``` + + +## Obtaining a DOM Element + +1. Use $refs to obtain a DOM element. + + ``` + +
+ +
+ ``` + + + ``` + // index.js + export default { + data: { + images: [ + { src: '/common/frame1.png' }, + { src: '/common/frame2.png' }, + { src: '/common/frame3.png' }, + ], + }, + handleClick() { + const animator = this.$refs.animator; // Obtain the DOM element whose $refs attribute is animator. + const state = animator.getState(); + if (state === 'paused') { + animator.resume(); + } else if (state === 'stopped') { + animator.start(); + } else { + animator.pause(); + } + }, + }; + ``` + +2. Call $element to obtain a DOM element. + + ``` + +
+ +
+ ``` + + + ``` + // index.js + export default { + data: { + images: [ + { src: '/common/frame1.png' }, + { src: '/common/frame2.png' }, + { src: '/common/frame3.png' }, + ], + }, + handleClick() { + const animator = this.$element('animator'); // Obtain the DOM element whose ID is animator. + const state = animator.getState(); + if (state === 'paused') { + animator.resume(); + } else if (state === 'stopped') { + animator.start(); + } else { + animator.pause(); + } + }, + }; + ``` + +## Obtaining the ViewModel The following shows files of the root page: + ``` @@ -455,6 +240,7 @@ The following shows files of the root page: ``` + ``` // root.js export default { @@ -466,6 +252,7 @@ export default { Customize the parent component. + ``` @@ -476,6 +263,7 @@ Customize the parent component. ``` + ``` // parent.js export default { @@ -495,6 +283,7 @@ export default { Customize the child component. + ```
@@ -503,6 +292,7 @@ Customize the child component.
``` + ``` // child.js export default { @@ -519,4 +309,3 @@ export default { }, } ``` - diff --git a/en/application-dev/ui/js-framework-syntax.md b/en/application-dev/ui/js-framework-syntax.md deleted file mode 100644 index 9ba136648a707eb0b4970f2e0d9a9b7b55bc2794..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/js-framework-syntax.md +++ /dev/null @@ -1,9 +0,0 @@ -# Syntax - -- **[HML](js-framework-syntax-hml.md)** - -- **[CSS](js-framework-syntax-css.md)** - -- **[JavaScript](js-framework-syntax-js.md)** - - diff --git a/en/application-dev/ui/js-framework.md b/en/application-dev/ui/js-framework.md deleted file mode 100644 index 9747766bd040881d19b537c7eb77159e4f1be265..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/js-framework.md +++ /dev/null @@ -1,17 +0,0 @@ -# Framework - -- **[File Organization](js-framework-file.md)** - -- **["js" Tag](js-framework-js-tag.md)** - -- **[app.js](js-framework-js-file.md)** - -- **[Syntax](js-framework-syntax.md)** - -- **[Lifecycle](js-framework-lifecycle.md)** - -- **[Resource Limitations and Access](js-framework-resource-restriction.md)** - -- **[Multi-Language Capability](js-framework-multiple-languages.md)** - - diff --git a/en/application-dev/ui/ts-a-deep-dive-into-component.md b/en/application-dev/ui/ts-a-deep-dive-into-component.md deleted file mode 100644 index cc95c1bae6dbfe8e1078c086953e39f85ada01bb..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-a-deep-dive-into-component.md +++ /dev/null @@ -1,11 +0,0 @@ -# About @Component - -- **[build Function](ts-function-build.md)** - -- **[Custom Component Initialization](ts-custom-component-initialization.md)** - -- **[Custom Component Lifecycle Callbacks](ts-custom-component-lifecycle-callbacks.md)** - -- **[Example: Component Creation and Re-Initialization](ts-component-creation-re-initialization.md)** - - diff --git a/en/application-dev/ui/ts-application-resource-access.md b/en/application-dev/ui/ts-application-resource-access.md index 1dbba18d4a78462127eb07f69c3306dd02d4d946..33dee0468c7905ea10d202e347dbb937a2ad2137 100644 --- a/en/application-dev/ui/ts-application-resource-access.md +++ b/en/application-dev/ui/ts-application-resource-access.md @@ -3,35 +3,35 @@ ## Resource Definition -Application resources are defined by in the project's **resources** directory, which is organized as follows: +Application resources are defined by in the project's resources directory, which is organized as follows: -- Level-1: **base** sub-directory, qualifiers sub-directories, and **rawfile** sub-directory - - The **base** sub-directory is a default directory. If no qualifiers sub-directories in the **resources** directory of the application match the device status, the resource file in the **base** sub-directory will be automatically referenced. +- Level-1: base sub-directory, qualifiers sub-directories, and rawfile sub-directory + - The base sub-directory is a default directory. If no qualifiers sub-directories in the resources directory of the application match the device status, the resource file in the base sub-directory will be automatically referenced. - You need to create qualifiers sub-directories on your own. The name of a qualifiers sub-directory consists of one or more qualifiers that represent the application scenarios or device characteristics, covering the mobile country code (MCC), mobile network code (MNC), language, script, country or region, screen orientation, device type, color mode, and screen density. The qualifiers are separated using underscores (_) or hyphens (-). - - When the resources in the **rawfile** sub-directory are referenced, resource files will not be matched based on the device status. You can directly store resource files in the **rawfile** sub-directory. + - When the resources in the rawfile sub-directory are referenced, resource files will not be matched based on the device status. You can directly store resource files in the rawfile sub-directory. - Level-2: resource sub-directories - Resource sub-directories store basic elements such as character strings, colors, and floating point numbers, and resource files such as media files. - Supported files and resource types are listed in the table below: - | File Name | Resource Type | + | File Name | Resource Type | | -------- | -------- | - | color.json | Color resource. | - | float.json | Resources such as spacing, rounded corners, and fonts. | - | string.json | String resource. | - | plural.json | String resource. | - | media directory | Image resource. | + | color.json | Color resource. | + | float.json | Resources such as spacing, rounded corners, and fonts. | + | string.json | String resource. | + | plural.json | String resource. | + | media directory | Image resource. | ## Referencing Resources -To reference an application resource in a project, use the **"$r('app.type.name')"** format. **app** indicates the resource defined in the **resources** directory of the application. **type** indicates the resource type (or the location where the resource is stored). The value can be **color**, **float**, **string**, **plural**, or **media**. **name** indicates the resource name, which you set when defining the resource. +To reference an application resource in a project, use the "$r('app.type.name')" format. app indicates the resource defined in the resources directory of the application. type indicates the resource type (or the location where the resource is stored). The value can be color, float, string, plural, or media. name indicates the resource name, which you set when defining the resource. -When referencing resources in the **rawfile** sub-directory, use the **"$rawfile('filename')"** format. Currently, **$rawfile** allows only the **<Image>** component to reference image resources. In the format, **filename** indicates the relative path of a file in the **rawfile** directory, and the file name must contain the file name extension. Note that the relative path cannot start with a slash (/). +When referencing resources in the rawfile sub-directory, use the "$rawfile('filename')" format. Currently, $rawfile allows only the component to reference image resources. In the format, filename indicates the relative path of a file in the rawfile directory, and the file name must contain the file name extension. **NOTE** that the relative path cannot start with a slash (/). ## Example -Some custom resources in the **base** sub-directory are as follows: +Some custom resources in the base sub-directory are as follows: ``` @@ -49,7 +49,7 @@ Some custom resources in the **base** sub-directory are as follows: └─ newTest.png ``` -The content of the **color.json** file is as follows: +The content of the color.json file is as follows: ``` @@ -67,7 +67,7 @@ The content of the **color.json** file is as follows: } ``` -The content of the **float.json** file is as follows: +The content of the float.json file is as follows: ``` @@ -85,7 +85,7 @@ The content of the **float.json** file is as follows: } ``` -The content of the **string.json** file is as follows: +The content of the string.json file is as follows: ``` @@ -107,7 +107,7 @@ The content of the **string.json** file is as follows: } ``` -The content of the **plural.json** file is as follows: +The content of the plural.json file is as follows: ``` @@ -130,7 +130,7 @@ The content of the **plural.json** file is as follows: } ``` - In the **ets** file, you can use the resources defined in the **resources** directory. + In the ets file, you can use the resources defined in the resources directory. ``` Text($r('app.string.string_hello')) diff --git a/en/application-dev/ui/ts-application-states-apis-environment.md b/en/application-dev/ui/ts-application-states-apis-environment.md index 69e62557dfa01f19e884799ddfb9d66b39d39ddc..112e98bf561287ca283406e1bfad3c964cadb809 100644 --- a/en/application-dev/ui/ts-application-states-apis-environment.md +++ b/en/application-dev/ui/ts-application-states-apis-environment.md @@ -1,118 +1,35 @@ -# Environment +# Environment + + +Environment is a singleton object created by the framework when the application is started. It provides the AppStorage with a series of environment state attributes required by the application. These attributes describe the device environment where the application runs. Environment and its attributes are immutable, and all attribute values are of the simple type. The following example shows how to obtain the semantic environment from Environment: -**Environment** is a singleton object created by the framework when the application is started. It provides the **AppStorage** with a series of environment state attributes required by the application. These attributes describe the device environment where the application runs. **Environment** and its attributes are immutable, and all attribute values are of the simple type. -The following example shows how to obtain the voice environment from **Environment**: ``` Environment.EnvProp("accessibilityEnabled", "default"); -var enable = AppStorageGet("accessibilityEnabled"); +var enable = AppStorage.Get("accessibilityEnabled"); ``` -**accessibilityEnabled** is the default system variable identifier provided by **Environment**. You need to bind the corresponding system attribute to the **AppStorage**. Then, you can use the methods or decorators in the **AppStorage** to access the corresponding system attribute data. -## Environment APIs +accessibilityEnabled is the default system variable identifier provided by Environment. You need to bind the corresponding system attribute to the AppStorage. Then, you can use the methods or decorators in the AppStorage to access the corresponding system attribute data. + + +## Environment APIs - - - - - - - - - - - - - - - - - - - - - - - -

key

-

Parameter

-

Return Value

-

Description

-

EnvProp

-

key : string

-

defaultValue: any

-

boolean

-

Associates this system variable to the Appstorage. You are advised to use this API during application startup. If the attribute already exists in the Appstorage, false is returned. Do not use the variables in the AppStorage. Instead, call this method to bind environment variables.

-

EnvProps

-

keys: {

-

key: string,

-

defaultValue: any

-

}[]

-

void

-

Associates this system item array with the Appstorage.

-

Keys

-

Array<string>

-

number

-

Returns the associated system item array.

-
+| key | Parameter | Return Value | Description | +| -------- | -------- | -------- | -------- | +| EnvProp | key: string,
defaultValue: any | boolean | Binds this system attribute to the AppStorage. You are advised to use this API during application startup. If the attribute already exists in the AppStorage, false is returned. Do not use the variables in the AppStorage. Instead, call this method to bind environment variables. | +| EnvProps | keys: {
key: string,
defaultValue: any
}[] | void | Associates this system item array with the AppStorage. | +| Keys | Array<string> | number | Returns the associated system item array. | -## Built-in Environment Variables - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

key

-

Type

-

Description

-

accessibilityEnabled

-

boolean

-

Whether to enable accessibility.

-

colorMode

-

ColorMode

-

Color mode. The options are as follows:

-
  • ColorMode.LIGHT: light mode.
  • ColorMode.DARK: dark mode.
-

fontScale

-

number

-

Font scale. The value range is [0.85, 1.45].

-

fontWeightScale

-

number

-

Font weight scale. The value range is [0.6, 1.6].

-

layoutDirection

-

LayoutDirection

-

Layout direction. The options are as follows:

-
  • LayoutDirection.LTR: The direction is from left to right.
  • LayoutDirection.RTL: The direction is from right to left.
-

languageCode

-

string

-

Current system language. The value is in lowercase, for example, zh.

-
+## Built-in Environment Variables + | key | Type | Description | +| -------- | -------- | -------- | +| accessibilityEnabled | boolean | Whether to enable accessibility. | +| colorMode | ColorMode | Color mode. The options are as follows:
- ColorMode.LIGHT: light mode.
- ColorMode.DARK: dark mode. | +| fontScale | number | Font scale. The value range is [0.85, 1.45]. | +| fontWeightScale | number | Font weight scale. The value range is [0.6, 1.6]. | +| layoutDirection | LayoutDirection | Layout direction. The options are as follows:
- LayoutDirection.LTR: The direction is from left to right.
- LayoutDirection.RTL: The direction is from right to left. | +| languageCode | string | Current system language. The value is in lowercase, for example, zh. | diff --git a/en/application-dev/ui/ts-application-states-apis-persistentstorage.md b/en/application-dev/ui/ts-application-states-apis-persistentstorage.md index 0d4215b5f06b1e85a4e5c4437d15e9167627f2e1..c776ed015e030c72c0f7be251e7c95d224810872 100644 --- a/en/application-dev/ui/ts-application-states-apis-persistentstorage.md +++ b/en/application-dev/ui/ts-application-states-apis-persistentstorage.md @@ -1,69 +1,23 @@ -# PersistentStorage +# PersistentStorage -**PersistentStorage** is used to manage persistent data of applications. This object can link the persistent data of a specific flag to the **AppStorage** and access the persistent data through the **AppStorage** APIs or access the variable of the corresponding key through the **@StorageLink** decorator. -## PersistentStorage APIs +ArkUI provides some static methods in the PersistentStorage class for managing persistent data of applications. Persistent data with specific tags can be linked to the AppStorage, and then the persistent data can be accessed through the AppStorage APIs. Alternatively, the @StorageLink decorator can be used to access the variable of the specific key. + + +| Name | Type | Return Value | Definition | +| -------- | -------- | -------- | -------- | +| PersistProp | key : string
defaultValue: T | void | Changes the associated named attribute to persistent data in the AppStorage. The value overwriting sequence is as follows:
- If the attribute exists in the AppStorage, use it to overwrite the value in Persistent.
- If Persistent contains the specified attribute, use the attribute value in Persistent.
- If the preceding conditions are not met, use defaultValue. The values null and undefined are not supported. | +| DeleteProp | key: string | void | Cancels two-way binding. The value of this attribute will be deleted from the persistent storage. | +| PersistProps | keys: {
key: string,
defaultValue: any
}[] | void | Associates multiple named attribute bindings. | +| Keys | void | Array <string> | Returns the flags of all persistent attributes. | + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - When using PersistProp, ensure that the input key exists in the AppStorage. +> +> - DeleteProp takes effect only for the data that has been linked during the current startup. - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Name

-

Type

-

Return Value

-

Definition

-

PersistProp

-

key : string

-

defaultValue: T

-

void

-

Changes associated named attribute to persistent data in the AppStorage. Value overwriting sequence:

-

If the attribute exists in the AppStorage, overwrite its value with the attribute value in Persistent.

-

If Persistent contains the specified attribute, use the attribute value in Persistent.

-

If the preceding conditions are not met, use defaultValue. The null and undefined values are not supported.

-

DeleteProp

-

key: string

-

void

-

Cancels two-way binding. The value of this attribute will be deleted from the persistent storage.

-

PersistProps

-

keys: {

-

key: string,

-

defaultValue: any

-

}[]

-

void

-

Associates multiple named attribute bindings.

-

Keys

-

void

-

Array<string>

-

Returns the flags of all persistent attributes.

-
->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- When using **PersistProp**, ensure that the input key exists in the **Appstorage**. ->- **DeleteProp** takes effect only for the data that has been linked during the current startup. ``` PersistentStorage.PersistProp("highScore", "0"); @@ -91,4 +45,3 @@ struct PersistentComponent { } } ``` - diff --git a/en/application-dev/ui/ts-application-states-appstorage.md b/en/application-dev/ui/ts-application-states-appstorage.md index 9dfac0e2e52fcf1df995cb7e8cb0875d4065d9cb..1f5f3b09bfa92962cb764bce02a6ad7768aab2cb 100644 --- a/en/application-dev/ui/ts-application-states-appstorage.md +++ b/en/application-dev/ui/ts-application-states-appstorage.md @@ -1,153 +1,93 @@ -# AppStorage - -**AppStorage** is a singleton object in an application and is created by the UI framework when the application is started. It is designed to provide central storage for changing application state attributes. **AppStorage** contains all the state attributes that need to be accessed throughout the application. The **AppStorage** retains all attributes and their values as long as the application remains running, and the attribute values can be accessed through unique key values. - -The UI component can synchronize the application state data with the **AppStorage** through the decorators. The application service logic can also be implemented by accessing the **AppStorage** through APIs. - -The selection state attribute of the **AppStorage** can be synchronized with different data sources or data sinks. These data sources and data sinks can be local or remote devices and provide different functions, such as data persistence. Such data sources and data sinks can be implemented independently of the UI in the service logic. - -By default, the attributes in the **AppStorage** are changeable. If needed, **AppStorage** can also use immutable \(read-only\) attributes. - -## AppStorage APIs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Name

-

Type

-

Return Value

-

Definition

-

Link

-

key: string

-

@Link

-

Returns the two-way binding to this attribute if there is data with a given key. This means that changes made to the data by a variable or component will be synchronized to the AppStorage, and changes made to the data by the AppStorage will be synchronized to the variable or component. If the attribute with this key does not exist or is read-only, undefined is returned.

-

SetAndLink

-

key : String

-

defaultValue: T

-

@Link

-

Works in a way similar to the Link API. If the current key is stored in the AppStorage, the value corresponding to the key is returned. If the key has not been created, a Link instance corresponding to the default value is created and returned.

-

Prop

-

key: string

-

@Prop

-

Returns one-way binding to an attribute with a given key if the attribute exists. This one-way binding means that changes to the attribute can only be synchronized to variables or components through AppStorage. The variable returned by this method is an immutable one, which is applicable both to the variable and immutable state attributes. If the attribute with this key does not exist, undefined is returned.

-
NOTE:

The attribute value type used in the prop method must be of a simple type.

-
-

SetAndProp

-

key : string

-

defaultValue: S

-

@Prop

-

Works in a way similar to the Prop API. If the current key is stored in the AppStorage, the value corresponding to the key is returned. If the key has not been created, a Prop instance corresponding to the default value is created and returned.

-

Has

-

key: string

-

boolean

-

Checks whether the attribute corresponding to the key value exists.

-

Keys

-

void

-

array<string>

-

Returns an array of strings containing all keys.

-

Get

-

string

-

T or undefined

-

Obtains the value of the key.

-

Set

-

string, newValue : T

-

void

-

Replaces the value of a saved key.

-

SetOrCreate

-

string, newValue : T

-

boolean

-

Returns true if an attribute with the same name exists and the attribute can be modified; returns false otherwise.

-

If the attribute with the same name does not exist: the first attribute whose value is the defaultValue is created and returned. The null and undefined values are not supported.

-

Delete

-

key : string

-

boolean

-

Deletes an attribute. If the attribute exists, true is returned. Otherwise, false is returned.

-

Clear

-

none

-

boolean

-

Deletes all attributes. If any of the attributes is being referenced by a state variable, false is returned.

-

IsMutable

-

key: string

-
  

Specifies whether the attribute exists and can be changed.

-
- ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->Currently, the API can process only basic data and cannot modify a value in an object. - -## Example +# AppStorage + + +AppStorage is a singleton object in an application, which is created by the UI framework when the application is started and destroyed when the application exits. It is used to provide central storage for changing state attributes of an application. AppStorage contains all the state attributes that need to be accessed throughout the application. The AppStorage retains all attributes and their values as long as the application remains running, and the attribute values can be accessed through unique key values. + + +The UI component can synchronize the application state data with the AppStorage through the decorators. The application service logic can also be implemented by accessing the AppStorage through APIs. + + +The selection state attribute of the AppStorage can be synchronized with different data sources or data sinks. These data sources and data sinks can be local or remote devices and provide different functions, such as data persistence. Such data sources and data sinks can be implemented independently of the UI in the service logic. + + +By default, the attributes in the AppStorage are changeable. If needed, AppStorage can also use immutable (read-only) attributes. + + +## AppStorage APIs + +| Name | Type | Return Value | Definition | +| -------- | -------- | -------- | -------- | +| SetAndLink | key: string,
defaultValue: T | @Link | Works in a way similar to the Link API. If the current key is stored in the AppStorage, the value corresponding to the key is returned. If the key has not been created, a Link instance corresponding to the default value is created and returned. | +| Set | key: string,
newValue: T | void | Replaces the value of a saved key. | +| Link | key: string | @Link | Returns two-way binding to this attribute if there is data with a given key. This means that attribute changes made by a variable or component will be synchronized to the AppStorage, and attribute changes made through the AppStorage will be synchronized to the variable or component. If the attribute with this key does not exist or is read-only, undefined is returned. | +| SetAndProp | propName: string,
defaultValue: S | @Prop | Works in a way similar to the Prop API. If the current key is stored in the AppStorage, the value corresponding to the key is returned. If the key has not been created, a Prop instance corresponding to the default value is created and returned. | +| Prop | key: string | @Prop | Returns one-way binding to an attribute with a given key if the attribute exists. This means that attribute changes made through the AppStorage will be synchronized to the variable or component, but attribute changes made by the variable or component will be synchronized to the AppStorage. The variable returned by this method is an immutable one, which is applicable both to the variable and immutable state attributes. If the attribute with the specified key does not exist, undefined is returned.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**:
> The attribute value used in the prop method must be of a simple type. | +| SetOrCreate | key: string,
newValue: T | boolean | If an attribute that has the same name as the specified key exists: replaces the value of the attribute and returns true when the attribute can be modified; retains the original value of the attribute and returns false otherwise.
If an attribute that has the same name as the specified key does not exist: creates an attribute whose key is key and value is newValue. The values null and undefined are not supported. | +| Get | key: string | T or undefined | Obtains the value of the specified key. | +| Has | propName: string | boolean | Checks whether the attribute corresponding to the specified key value exists. | +| Keys | void | array<string> | Returns an array of strings containing all keys. | +| Delete | key: string | boolean | Deletes the key-value pair for the specified key. Returns true if the key-value pair exists and is successfully deleted; returns false otherwise. | +| Clear | void | boolean | Deletes all attributes. If any of the attributes is being referenced by a state variable, false is returned. | +| IsMutable | key: string | boolean | Specifies whether the attribute exists and can be changed. | + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> Currently, the API can process only basic data and cannot modify a value in an object. + + +## Synchronization Between AppStorage and Components + +In [Managing Component States](ts-component-states-state.md), we have defined how to synchronize the state variables of child components with the @State decorated variables in the parent component or ancestor component, including @Prop, @Link, and @Consume. + +In this section, we'll describe how to synchronize component variables with the AppStorage through the @StorageLink and @StorageProp decorators. + + +### @StorageLink Decorator + +Two-way data binding can be established between components and the AppStorage through state variables decorated by @StorageLink(_key_). Wherein, key is the attribute key value in the AppStorage. When a component containing the @StorageLink decorated variable is created, the variable is initialized using the value in the AppStorage. Changes made to this variable in the component will be first synchronized to the AppStorage, and then to other bound instances, such as PersistentStorage or other bound UI components. + + +### @StorageProp Decorator + +One-way data binding can be established between components and the AppStorage through state variables decorated by @StorageProp(_key_). Wherein, key is the attribute key value in the AppStorage. When a component containing the @StorageProp decorated variable is created, the variable is initialized using the value in the AppStorage. Changes made to the value in the AppStorage will cause the bound UI component to update the state. + + +## Example + ``` -let link1 = AppStorage.Link('PropA') -let link2 = AppStorage.Link('PropA') -let prop = AppStorage.Prop('PropA') +let varA = AppStorage.Link('varA') +let envLang = AppStorage.Prop('languageCode') + +@Entry +@Component +struct ComponentA { + @StorageLink('varA') varA: number = 2 + @StorageProp('languageCode') lang: string = 'en' + private label: string = 'count' + + private aboutToAppear() { + this.label = (this.lang === 'en') ? 'Number' : 'Count' + } + + build() { + Row({ space: 20 }) { -link1 = 47 // causes link1 == link2 == prop == 47 -link2 = link1 + prop // causes link1 == link2 == prop == 94 -prop = 1 // error, prop is immutable + Button(`${this.label}: ${this.varA}`) + .onClick(() => { + AppStorage.Set('varA', AppStorage.Get('varA') + 1) + }) + Button(`lang: ${this.lang}`) + .onClick(() => { + if (this.lang === 'zh') { + AppStorage.Set('languageCode', 'en') + } else { + AppStorage.Set('languageCode', 'en') + } + this.label = (this.lang === 'en') ? 'Number' : 'Count' + }) + } + } +} ``` +Each time the user clicks the Count button, the value of this.varA will increase by 1. This variable is synchronized with varA in the AppStorage. Each time the user clicks the language icon, the value of languageCode in the AppStorage will be changed, and the change will be synchronized to the this.lang variable. diff --git a/en/application-dev/ui/ts-attribution-configuration.md b/en/application-dev/ui/ts-attribution-configuration.md index f1ff930d90b2cd8574526fad963ab8085e4e02a7..d1d00d17eb3b607f830959df35d37c12ad6ee040 100644 --- a/en/application-dev/ui/ts-attribution-configuration.md +++ b/en/application-dev/ui/ts-attribution-configuration.md @@ -1,46 +1,41 @@ -# Attribution Configuration +# Attribute Configuration -Use attribute methods to configure component attributes. An attribute method follows the corresponding component and is bound to the component using the "**.**" operator. -The following is an example of configuring the **fontsize** attribute of the **** component: +Use attribute methods to configure component attributes. An attribute method follows the corresponding component and is bound to the component using the "." operator. -``` -Text('123') - .fontSize(12) -``` -You can also use the "**.**" operation to implement chain call to configure multiple attributes at the same time. +- The following is an example of configuring the font size attribute of the Text component: + + ``` + Text('123') + .fontSize(12) + ``` -Below is the sample code for configuring the **width** and **height** attributes of the **** component at the same time: -``` -Image('a.jpg') - .alt('error.jpg') - .width(100) - .height(100) -``` +- Use the "." operator to implement chain call to configure multiple attributes at the same time, as shown below: + + ``` + Image('a.jpg') + .alt('error.jpg') .width(100) .height(100) + ``` -In addition to constants, you can also pass variables or expressions, as shown below: -``` -// Size, count, and offset are private variables defined in the component. -Text('hello') - .fontSize(this.size) -Image('a.jpg') - .width(this.count % 2 === 0 ? 100 : 200) - .height(this.offset + 100) -``` +- In addition to constants, you can also pass variables or expressions, as shown below: + + ``` + // Size, count, and offset are private variables defined in the component. + Text('hello') + .fontSize(this.size) + Image('a.jpg') + .width(this.count % 2 === 0 ? 100 : 200) .height(this.offset + 100) + ``` -For attributes of preset components, the framework also provides some predefined enumeration types, which you can pass as parameters to methods. - -Enumeration types must meet the parameter type requirements on the enumeration type definitions for specific attributes. - -You can configure the font color and weight attributes of the **** component as follows: - -``` -Text('hello') - .fontSize(20) - .fontColor(Color.Red) - .fontWeight(FontWeight.Bold) -``` +- For attributes of preset components, the framework also provides some predefined enumeration types, which you can pass as parameters to methods. Enumeration types must meet the parameter type requirements on the enumeration type definitions for specific attributes. You can configure the font color and weight attributes of the Text component as follows: + + ``` + Text('hello') + .fontSize(20) + .fontColor(Color.Red) + .fontWeight(FontWeight.Bold) + ``` diff --git a/en/application-dev/ui/ts-basic-components-loadingprogress.md b/en/application-dev/ui/ts-basic-components-loadingprogress.md deleted file mode 100644 index 2550e50bee09c3ba09580a996a7fb4e171abe13f..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-basic-components-loadingprogress.md +++ /dev/null @@ -1,44 +0,0 @@ -# LoadingProgress - -> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE** -> This component is supported since API version 8. Updates will be marked with a superscript to indicate their earliest API version. - -The **** component is used to display the loading progress. - -## Required Permissions - -None - -## Child Components - -None - -## APIs - -LoadingProgress() - -Creates a **LoadingProgress** instance. - -## Attributes - -| Name | Type | Default Value | Description | -| ----- | ----- | ------------- | ---------------------------------------- | -| color | Color | - | Foreground color of the loading progress bar. | - -## Example - -``` -@Entry -@Component -struct LoadingProgressExample { - build() { - Column({ space: 5 }) { - Text('Orbital LoadingProgress ').fontSize(9).fontColor(0xCCCCCC).width('90%') - LoadingProgress() - .color(Color.Blue) - }.width('100%').margin({ top: 5 }) - } -} -``` - -![zh-cn_image_0000001198839004](figures/loadingProgress.png) \ No newline at end of file diff --git a/en/application-dev/ui/ts-child-component-configuration.md b/en/application-dev/ui/ts-child-component-configuration.md index 4d8d82427410ae6c037445446eecdbff94cc9d47..61fb05beeaab30c6a2828bd318b034db58197025 100644 --- a/en/application-dev/ui/ts-child-component-configuration.md +++ b/en/application-dev/ui/ts-child-component-configuration.md @@ -1,47 +1,49 @@ -# Child Component Configuration +# Child Component Configuration -For a component that supports child components, for example, a container component, add the UI descriptions of the child components inside "**\{ ... \}**". The ****, ****, ****, ****, ****, and **** components are container components. -The following is a simple example of the **** component: +For a component that supports child components, for example, a container component, add the UI descriptions of the child components inside "{ ... }". The <Column>, <Row>, <Stack>, <Button>, <Grid>, and <List> components are container components. -``` -Column() { - Text('Hello') - .fontSize(100) - Divider() - Text(this.myText) - .fontSize(100) - .fontColor(Color.Red) -} -``` -Multiple child components can be nested in the **** component, as shown below: +- The following is a simple example of the <Column> component: + + ``` + Column() { + Text('Hello') + .fontSize(100) + Divider() + Text(this.myText) + .fontSize(100) + .fontColor(Color.Red) + } + ``` -``` -Column() { - Column() { - Button() { - Text('+ 1') - }.type(ButtonType.Capsule) - .onClick(() => console.log ('+1 clicked!')) - Image('1.jpg') - } - Divider() - Column() { - Button() { - Text('+ 2') - }.type(ButtonType.Capsule) - .onClick(() => console.log ('+2 clicked!')) - Image('2.jpg') - } - Divider() - Column() { - Button() { - Text('+ 3') - }.type(ButtonType.Capsule) - .onClick(() => console.log('+3 clicked!')) - Image('3.jpg') - } -}.alignItems(HorizontalAlign.Center) // center align components inside Column -``` +- Multiple child components can be nested in the <Column> component, as shown below: + + ``` + Column() { + Column() { + Button() { + Text('+ 1') + }.type(ButtonType.Capsule) + .onClick(() => console.log ('+1 clicked!')) + Image('1.jpg') + } + Divider() + Column() { + Button() { + Text('+ 2') + }.type(ButtonType.Capsule) + .onClick(() => console.log ('+2 clicked!')) + Image('2.jpg') + } + Divider() + Column() { + Button() { + Text('+ 3') + }.type(ButtonType.Capsule) + .onClick(() => console.log('+3 clicked!')) + Image('3.jpg') + } + }.alignItems(HorizontalAlign.Center) // center align components inside Column + ``` diff --git a/en/application-dev/ui/ts-component-based-builder.md b/en/application-dev/ui/ts-component-based-builder.md index ca33d875afd237420c4856665c2bcd4736828f4d..94e75620e5a4d9c1f24cb7c0325d6f852017f797 100644 --- a/en/application-dev/ui/ts-component-based-builder.md +++ b/en/application-dev/ui/ts-component-based-builder.md @@ -1,8 +1,9 @@ -# @Builder +# @Builder + + +The @Builder decorated method is used to define the declarative UI description of a component and quickly generate multiple layouts in a custom component. The functionality and syntax of the @Builder decorator are the same as those of the [build Function](ts-function-build.md). -The **@Builder** decorator defines a method for rendering custom components It allows a method to work in the same way as the [build](ts-function-build.md) function. The syntax of methods decorated by **@Builder** is the same as that of the **build** function. -You can use the **@Builder** decorator to quickly generate multiple layouts within a custom component. ``` @Entry @@ -42,3 +43,99 @@ struct CompA { } ``` +## @BuilderParam8+ + +The @BuilderParam decorator is used to modify the function type attributes (for example, @BuilderParam content: () => any) in a custom component. When the custom component is initialized, the attributes modified by the @BuilderParam decorator must be assigned values. + +### Background + +In certain circumstances, you may need to add a specific function, such as a click-to-jump action, to a custom component. However, embedding an event method directly inside of the component can add the function to all places where the component is initialized. This is where the @BuilderParam decorator come into the picture. When initializing a custom component, you can assign a @Builder decorated method to the @BuilderParam decorated attribute, thereby adding the specific function to the custom component. + +### Component Initialization Through Parameters + +When initializing a custom component through parameters, assign a @Builder decorated method to the @BuilderParam decorated attribute —content, and call the value of content in the custom component. + +``` +@Component +struct CustomContainer { + header: string = ""; + @BuilderParam content: () => any; + footer: string = ""; + build() { + Column() { + Text(this.header) + .fontSize(50) + this.content() + Text(this.footer) + .fontSize(50) + } + } +} + +@Entry +@Component +struct CustomContainerUser { + @Builder specificParam(label: string) { + Column() { + Text(label).fontSize(50) + } + } + + build() { + Column() { + CustomContainer({ + header: "Header", + content: this.specificParam("111") + footer: "Footer", + }) + } + } +} +``` + +### Component Initialization Through Trailing Closure + +In a custom component, use the @BuilderParam decorated attribute to receive a trailing closure. When the custom component is initialized, the component name is followed by a pair of braces ({}) to form a trailing closure (CustomComponent(){}). You can consider a trailing closure as a container and add content to it. For example, you can add a component ({Column(){Text("content")}) to the closure. The syntax of the closure is the same as that of [build](ts-function-build.md). In this scenario, the custom component has one and only one @BuilderParam decorated attribute. + +Example: Add a <Column> component and a click event to the closure, and call the specificParam method decorated by @Builder in the new <Column> component. After the <Column> component is clicked, the value of the component's header attribute will be changed to changeHeader. In addition, when the component is initialized, the content of the trailing closure will be assigned to the closer attribute decorated by @BuilderParam. + +``` +@Component +struct CustomContainer { + header: string = ""; + @BuilderParam closer: () => any; + build() { + Column() { + Text(this.header) + .fontSize(50) + this.closer() + } + } +} +@Builder function specificParam(label1: string, label2: string) { + Column() { + Text(label1) + .fontSize(50) + Text(label2) + .fontSize(50) + } +} +@Entry +@Component +struct CustomContainerUser { + @State text: string = "header" + build() { + Column() { + CustomContainer({ + header: this.text, + }){ + Column(){ + specificParam("111", "22") + }.onClick(()=>{ + this.text = "changeHeader" + }) + } + } + } +} +``` diff --git a/en/application-dev/ui/ts-component-based-component.md b/en/application-dev/ui/ts-component-based-component.md index 49854681fd5fa42f8975aa1ab684b738ea4810f7..f247caa2887a59cdbb96e33ba23f22f7ed3137de 100644 --- a/en/application-dev/ui/ts-component-based-component.md +++ b/en/application-dev/ui/ts-component-based-component.md @@ -1,31 +1,28 @@ -# @Component +# @Component -A struct decorated by **@Component** has the component-based capability and can serve as an independent component. This type of component is also called a custom component. -This component can be combined with other components. It describes the UI structure by implementing the **build** method, which must comply with the **Builder** API constraints. The API definition is as follows: +A struct decorated by @Component has the componentization capability and can serve as an independent component. This type of component is also called a custom component, and its UI structure is described in the build method. Custom components have the following features: -``` -interface Builder { - build: () => void -} -``` -Custom components have the following features: +- Composability: Custom components can be used with preset or other components, as well as common attributes and methods. + +- Reusable: Custom components can be reused by other components and used as different instances in different parent components or containers. + +- Lifecycle: Custom components provide callbacks for service logic processing throughout the lifecycle. + +- Data-driven update: The UI of custom components can be automatically updated based on the data of state variables. -- **Composability:** Custom components can be used with preset or other components, as well as common attributes and methods. -- **Reusable:** Custom components can be reused by other components and used as different instances in different parent components or containers. -- **Lifecycle:** Custom components provide callbacks for service logic processing throughout the lifecycle. -- **Data-driven update:** The UI of custom components can be automatically updated based on the status data. -The component lifecycle mainly involves two callbacks, **aboutToAppear** and **aboutToDisappear** . For details, see [Custom Component Lifecycle Callbacks](ts-custom-component-lifecycle-callbacks.md). +For details about componentization, see [About @Component](ts-function-build.md). ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- Components must comply with the preceding **Builder** API constraints. Other components are combined in declarative mode in the internal **build** method. The **build** method is called when a component is created or updated for the first time. ->- Custom constructors are prohibited for components. -## Example +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - The build method must be defined for a custom component. +> +> - Custom constructors are prohibited for custom components. -The following code illustrates how to create a custom component named **MyComponent**: + +The following code illustrates how to create a custom component named MyComponent: ``` @Component @@ -39,9 +36,11 @@ struct MyComponent { } ``` -The **build** method of **MyComponent** is executed during initial rendering. When the component status changes, the **build** method will be executed again. -The following code illustrates how to use **MyComponent**: +The build method of MyComponent is executed during initial rendering. When the component status changes, the build method will be executed again. + + +The following code illustrates how to use MyComponent: ``` @Component @@ -56,7 +55,8 @@ struct ParentComponent { } ``` -**MyComponent** can be embedded multiple times and can be nested in different components, as shown in the code below: + +MyComponent can be applied multiple times and reused in different components, as shown in the code below: ``` @Component @@ -85,4 +85,3 @@ struct ParentComponent { } } ``` - diff --git a/en/application-dev/ui/ts-component-based-customdialog.md b/en/application-dev/ui/ts-component-based-customdialog.md index c03cdc1d402974df3287caa93be16e6a1db7711f..efcc465830ffbd4805ce9097d846d389473f4b03 100644 --- a/en/application-dev/ui/ts-component-based-customdialog.md +++ b/en/application-dev/ui/ts-component-based-customdialog.md @@ -1,7 +1,10 @@ -# @CustomDialog +# @CustomDialog -The **@CustomDialog** decorator is used to decorate custom pop-up dialog boxes. +The @CustomDialog decorator is used to decorate custom pop-up dialog boxes. + + + ``` // custom-dialog-demo.ets @CustomDialog @@ -46,4 +49,3 @@ struct CustomDialogUser { } } ``` - diff --git a/en/application-dev/ui/ts-component-based-entry.md b/en/application-dev/ui/ts-component-based-entry.md index a058f034fdb32a4658bf3de8336850f2893f149c..0973548901962c27b4cd15e30d7f115e51d9acc1 100644 --- a/en/application-dev/ui/ts-component-based-entry.md +++ b/en/application-dev/ui/ts-component-based-entry.md @@ -1,13 +1,14 @@ -# @Entry +# @Entry -The custom component decorated by **@Entry** functions as the default entry component of the respective page. When the page is loaded, the custom component decorated by **@Entry** is created and displayed first. ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->A source file can contain at most one custom component decorated by **@Entry**. +The custom component decorated by @Entry functions as the default entry component of the respective page. When the page is loaded, the custom component decorated by @Entry is created and displayed first. -## Example -Example of using **@Entry**: +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> A source file can contain at most one custom component decorated by @Entry. + + +Example of using @Entry: ``` // Only MyComponent decorated by @Entry is rendered and displayed. "hello world" is displayed, but "goodbye" is not displayed. @@ -32,4 +33,3 @@ struct HideComponent { } } ``` - diff --git a/en/application-dev/ui/ts-component-based-extend.md b/en/application-dev/ui/ts-component-based-extend.md index 729893c2ee6368fdba48ead9635bd540351da1d7..6280fa1b5fc2460ba34e542a8bb22382258ed77f 100644 --- a/en/application-dev/ui/ts-component-based-extend.md +++ b/en/application-dev/ui/ts-component-based-extend.md @@ -1,6 +1,6 @@ -# @Extend +# @Extend -The **@Extend** decorator adds new attribute functions to preset components, such as ****, ****, and ****. You can use the **@Extend** decorator to quickly define and reuse the custom styles of a component. +The @Extend decorator adds new attribute functions to preset components, such as <Text>, <Column>, and <Button>. You can use the @Extend decorator to quickly define and reuse the custom styles of a component. ``` @Extend(Text) function fancy(fontSize: number) { @@ -23,6 +23,4 @@ struct FancyUse { } ``` ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->The **@Extend** decorator cannot be used in the struct definition of a custom component. - +> ![img](public_sys-resources/icon-note.gif) **NOTE**: The @Extend decorator cannot be used in the struct definition of a custom component. \ No newline at end of file diff --git a/en/application-dev/ui/ts-component-based-preview.md b/en/application-dev/ui/ts-component-based-preview.md index c58898c2e41841f5b93b50ed7c0ab79b98e73324..59f5483433cb5c14e94cd414e8c1636789fd11e2 100644 --- a/en/application-dev/ui/ts-component-based-preview.md +++ b/en/application-dev/ui/ts-component-based-preview.md @@ -1,13 +1,14 @@ -# @Preview +# @Preview -Custom components decorated by **@Preview** can be previewed in the Previewer of DevEco Studio. When the page is loaded, the custom components decorated by **@Preview** are created and displayed. ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->In a source file, at most one custom component can be decorated by **@Preview**. +Custom components decorated by @Preview can be previewed in the Previewer of DevEco Studio. When the page is loaded, the custom components decorated by @Preview are created and displayed. -## Example -Example of using **@Preview**: +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> In a source file, at most one custom component can be decorated by @Preview. + + +Example of using @Preview: ``` // Display only Hello Component1 on the PC preview. The content under MyComponent is displayed on the real device. @@ -57,4 +58,3 @@ struct Component2 { } } ``` - diff --git a/en/application-dev/ui/ts-component-based-styles.md b/en/application-dev/ui/ts-component-based-styles.md new file mode 100644 index 0000000000000000000000000000000000000000..33ed37a07a5bb089bcff39f38d4456f6149b646f --- /dev/null +++ b/en/application-dev/ui/ts-component-based-styles.md @@ -0,0 +1,76 @@ +# @Styles + + +The @Styles decorator adds new attribute functions to basic components, such as <Text>, <Column>, and <Button>. Currently, @Styles supports only universal attributes. You can use the @Styles decorator to quickly define and reuse the custom styles of a component. + + +@Styles can be defined inside or outside a component. When it is defined outside a component, the keyword function must be included. + + + +``` +@Styles function globalFancy() { + .backgroundColor(Color.Red) +} + +@Entry +@Component +struct FancyUse { + @Styles componentFancy() { + .backgroundColor(Color.Blue) + } + build() { + Column({ space: 10 }) { + Text("Fancy") + .globalFancy() + .width(100) + .height(100) + .fontSize(30) + Text("Fancy") + .componentFancy() + .width(100) + .height(100) + .fontSize(30) + } + } +} +``` + + +@Styles can also be used inside the StateStyles attribute to assign state-specific attributes to components. + + +In StateStyles, styles defined outside the component can be directly called. However, the keyword this must be used to call styles defined in the component. + + + +``` +@Styles function globalFancy() { + .width(100) + .height(100) +} + +@Entry +@Component +struct FancyUse { + @Styles function componentFancy() { + .width(50) + .height(50) + } + build() { + Row({ space: 10 }) { + Button() { + Text("Fancy") + } + .stateStyles({ + normal: { + .width(80) + .height(80) + }, + disabled: this.componentFancy, + pressed: globalFancy + }) + } + } +} +``` diff --git a/en/application-dev/ui/ts-component-based.md b/en/application-dev/ui/ts-component-based.md deleted file mode 100644 index 2ebfc47886dd60ed5586c20d718e6904a4a46cee..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-component-based.md +++ /dev/null @@ -1,15 +0,0 @@ -# Componentization - -- **[@Component](ts-component-based-component.md)** - -- **[@Entry](ts-component-based-entry.md)** - -- **[@Preview](ts-component-based-preview.md)** - -- **[@Builder](ts-component-based-builder.md)** - -- **[@Extend](ts-component-based-extend.md)** - -- **[@CustomDialog](ts-component-based-customdialog.md)** - - diff --git a/en/application-dev/ui/ts-component-creation-re-initialization.md b/en/application-dev/ui/ts-component-creation-re-initialization.md index ad98aedda691eeed622fe2cf5c7e70afc3a099a5..8be07a11249b0e7cadef3df26d33aea054791fea 100644 --- a/en/application-dev/ui/ts-component-creation-re-initialization.md +++ b/en/application-dev/ui/ts-component-creation-re-initialization.md @@ -1,4 +1,52 @@ -# Example: Component Creation and Re-Initialization +# Component Creation and Re-initialization + + +## Initial Creation and Rendering + +1. Create the parent component ParentComp. + +2. Locally initialize the state variable isCountDown of ParentComp. + +3. Execute the build function of ParentComp. + +4. Create a preset <Column> component. + 1. Create a preset <Text> component, set the text content to be displayed, and add the <Text> component instance to the <Column> component. + 2. Create the component on the true branch based on the if condition. + 1. Create a preset <Image> component and set the image source address. + 2. Create a TimerComponent using the given constructor. + 1. Create a TimerComponent object. + 2. Initialize the values of member variables locally. + 3. Use the parameters provided by the TimerComponent constructor to update the values of member variables. + 4. Execute the aboutToAppear function of TimerComponent. + 5. Execute the build function of TimerComponent to create the corresponding UI description structure. + 3. Create a preset <Button> component and set the corresponding content. + + +## Status Update + +When a user clicks a button: + +1. The value of the isCountDown state variable of ParentComp is changed to false. + +2. The build function of ParentComp is executed. + +3. The preset <Column> component is reused by the framework and reinitialized. + +4. The child components of <Column> reuse and reinitialize the objects in the memory. + 1. Reuse the preset <Text> component after re-initializing the component using new text content. + 2. Reuse the component on the false branch based on the if condition. + 1. Destroy the components on the original true branch as these components are no longer used. + 1. Destroy the created preset <image> component instance. + 2. Destroy the TimerComponent component instance, and call the aboutToDisappear function. + 2. Create components on the false branch. + 1. Create a preset <Image> component and set the image source address. + 2. Create a TimerComponent again using the given constructor. + 3. Initialize the newly created TimerComponent and call the aboutToAppear and build functions. + 3. Reuse the preset <Button> component, with the new image source address. + + +## Example + ``` @Entry @@ -16,7 +64,7 @@ struct ParentComp { TimerComponent({counter: 0, changePerSec: +1, showInColor: Color.Black }) } Button(this.isCountDown ? 'Swtich to Stopwatch' : 'Switch to Count Down') - .onClick(() => {this.isCountDown = !this.isCountDown}) + .onClick(() => {this.isCountDown = !this.isCountDown}) } } } @@ -35,56 +83,14 @@ struct TimerComponent { } aboutToAppear() { - this.timerId = setInterval(() => {this.counter += this.changePerSec}, 1000) + this.timerId = setInterval(() => {this.counter += this.changePerSec}, 1000) } aboutToDisappear() { - if (this.timerId > 0) { + if (this.timerId > 0) { clearTimeout(this.timerId) this.timerId = -1 } } } ``` - -## Initial Creation and Rendering - -1. Create the parent component **ParentComp**. -2. Locally initialize the state variable **isCountDown** of **ParentComp**. -3. Execute the **build** function of **ParentComp**. -4. Create a preset **** component. - 1. Create a preset **** component, set the text content to be displayed, and add the **** component instance to the **** component. - 2. Create the component on the **true** branch based on the **if** condition. - 1. Create a preset **** component and set the image source address. - 2. Create a **TimerComponent** using the given constructor. - 1. Create a **TimerComponent** object. - 2. Initialize the values of member variables locally. - 3. Use the parameters provided by the **TimerComponent** constructor to update the values of member variables. - 4. Execute the **aboutToAppear** function of **TimerComponent**. - 5. Execute the **build** function of **TimerComponent** to create the corresponding UI description structure. - - 3. Create a preset **** component and set the corresponding content. - - -## Status Update - -When a user clicks a button: - -1. The value of the **isCountDown** state variable of **ParentComp** is changed to **false**. -2. The **build** function of **ParentComp** is executed. -3. The preset **** component is reused by the framework and reinitialized. -4. The child components of **** reuse and reinitialize the objects in the memory. - 1. Reuse the preset **** component after re-initializing the component using new text content. - 2. Reuse the component on the **false** branch based on the **if** condition. - 1. Destroy the components on the original **true** branch as these components are no longer used. - 1. Destroy the created preset **** component instance. - 2. Destroy the **TimerComponent** component instance, and call the **aboutToDisappear** function. - - 2. Create components on the **false** branch. - 1. Create a preset **** component and set the image source address. - 2. Create a **TimerComponent** again using the given constructor. - 3. Initialize the newly created **TimerComponent** and call the **aboutToAppear** and **build** functions. - - 3. Reuse the preset **** component, with the new image source address. - - diff --git a/en/application-dev/ui/ts-component-states-link.md b/en/application-dev/ui/ts-component-states-link.md index 16ffb392a2baeab7b77fc6f0aa7b01577724ff52..0112e9cc38582ee6e5da1666fe16c54a5956e9eb 100644 --- a/en/application-dev/ui/ts-component-states-link.md +++ b/en/application-dev/ui/ts-component-states-link.md @@ -1,17 +1,26 @@ -# @Link +# @Link -Two-way binding can be established between the **@Link** decorated variable and the **@State** decorated variable of the parent component. The **@Link** data has the following features: -- **Support for multiple types**: The value of the **@Link** decorated variable can be of the same type as the **@State** decorated variable; that is, the value can be of the following types: **class**, **number**, **string**, **boolean**, or arrays of these types. -- **Private**: Data is accessed only within the component. -- **Single data source**: The variable of the parent component for initializing the **@Link** decorated variable must be the **@State** decorated variable. -- **Two-way binding**: When a child component changes the **@Link** decorated variable, the **@State** decorated variable of its parent component is also changed. -- **Support for initialization with the variable reference passed to the @Link decorated variable**: When creating a new instance of the component, you must use the naming parameter to initialize all **@Link** decorated variables. The **@Link** decorated variable can be initialized by using the reference of the **@State** or **@Link** decorated variable. Wherein, the **@State** decorated variable can be referenced using the '**$**' operator. +Two-way binding can be established between the @Link decorated variable and the @State decorated variable of the parent component. The @Link data has the following features: ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->The **@Link** decorated variable cannot be initialized within the component. -## Simple Type Example +- Support for multiple types: The value of the @Link decorated variable can be of the same type as the @State decorated variable; that is, the value can be of the following types: class, number, string, boolean, or arrays of these types. + +- Private: Data is accessed only within the component. + +- Single data source: The variable of the parent component for initializing the @Link decorated variable must be the @State decorated variable. + +- Two-way binding: When a child component changes the @Link decorated variable, the @State decorated variable of its parent component is also changed. + +- Support for initialization with the variable reference passed to the @Link decorated variable: When creating a new instance of the component, you must use the naming parameter to initialize all @Link decorated variables. The @Link decorated variable can be initialized by using the reference of the @State or @Link decorated variable. Wherein, the @State decorated variable can be referenced using the '$' operator. + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> The @Link decorated variable cannot be initialized within the component. + + +## Simple Type Example + ``` @Entry @@ -41,9 +50,11 @@ struct PlayButton { } ``` -The **@Link** semantics are derived from the '**$**' operator. In other words, **$isPlaying** is the two-way binding of the internal state **this.isPlaying**. When you click **PlayButton**, the **** and **** components of **PlayButton** are refreshed at the same time. +The @Link semantics are derived from the '$' operator. In other words, $isPlaying is the two-way binding of the internal state this.isPlaying. When you click PlayButton, the <Image> and <Text> components of PlayButton are refreshed at the same time. + + +## Complex Type Example -## Complex Type Example ``` @Entry @@ -80,9 +91,11 @@ struct Child { } ``` -In the example above, click **Button1** and **Button2** to change the list of text items displayed in the parent component. +In the example above, click Button1 and Button2 to change the list of text items displayed in the parent component. + + +## Example of Using @Link, @State, and @Prop Together -## Example of Using @Link, @State, and @Prop Together ``` @Entry @@ -118,8 +131,8 @@ struct ChildB { } ``` -In the preceding example, **ParentView** contains two child components: **ChildA** and **ChildB**. They are initialized by the state variable **counter** of **ParentView**. +In the preceding example, ParentView contains two child components: ChildA and ChildB. They are initialized by the state variable counter of ParentView. -- **ChildB** uses **@Link** to establish two-way state binding. When the value of the **counterRef** state variable is changed in **ChildB**, the change is synchronized to **ParentView** and **ChildA**. -- **ChildA** uses **@Prop** to establish one-way state binding from **ParentView** to itself. When **ChildA** changes the state, it is re-rendered, but the change is not updated to **ParentView** or **ChildB**. +- ChildB uses @Link to establish two-way state binding. When the value of the counterRef state variable is changed in ChildB, the change is synchronized to ParentView and ChildA. +- ChildA uses @Prop to establish one-way state binding from ParentView to itself. When ChildA changes the state, it is re-rendered, but the change is not updated to ParentView or ChildB. diff --git a/en/application-dev/ui/ts-component-states-prop.md b/en/application-dev/ui/ts-component-states-prop.md index 06e195c25108ec681807542b30511c40a19b1f66..c70de8031c26bb06c845d4d1e214dc9e1b9fe57a 100644 --- a/en/application-dev/ui/ts-component-states-prop.md +++ b/en/application-dev/ui/ts-component-states-prop.md @@ -1,16 +1,24 @@ -# @Prop +# @Prop -**@Prop** and **@State** have the same semantics but different initialization modes. Variables decorated by **@Prop** must be initialized using the **@State** decorated variable provided by their parent components. The **@Prop** decorated variable can be modified in the component, but the modification is not updated to the parent component; that is, **@Prop** uses unidirectional data binding. -The **@Prop** state data has the following features: +@Prop and @State have the same semantics but different initialization modes. Variables decorated by @Prop must be initialized using the @State decorated variable provided by their parent components. The @Prop decorated variable can be modified in the component, but the modification is not updated to the parent component; that is, @Prop uses one-way data binding. -- **Support for simple types**: Only the following simple types are supported: **number**, **string**, and **boolean**. -- **Private**: Data is accessed only within the component. -- **Support for multiple instances**: A component can have multiple attributes decorated by **@Prop**. -- **Support for initialization with a value passed to the @Prop decorated variable**: When a new instance of the component is created, all **@Prop** decorated variables must be initialized. Initialization inside the component is not supported. -## Example +The @Prop state data has the following features: + +- Support for simple types: The number, string, and boolean types are supported. + +- Private: Data is accessed only within the component. + +- Support for multiple instances: A component can have multiple attributes decorated by @Prop. + +- Support for initialization with a value passed to the @Prop decorated variable: When a new instance of the component is created, all @Prop decorated variables must be initialized. Initialization inside the component is not supported. + + +## Example + + ``` @Entry @Component @@ -29,10 +37,7 @@ struct ParentComponent { }.onClick(() => { this.countDownStartValue -= 1 }) - - // when creatng ChildComponent, the initial value of its @Prop variable must be supplied - // in a named constructor parameter - // also regular costOfOneAttempt (non-Prop) variable is initialied + // When creating a child component, you must provide the initial value of its @Prop decorated variable in the constructor parameter and initialize the regular variable CostOfOneAttump (not Prop). CountDownComponent({ count: this.countDownStartValue, costOfOneAttempt: 2}) } } @@ -61,8 +66,7 @@ struct CountDownComponent { } ``` -In the preceding example, when you press **+1** or **-1**, the status of the parent component changes and the **build** method is executed again. In this case, a new **CountDownComponent** is created. The **countDownStartValue** property of the parent component is used to initialize the **@Prop** decorated variable of the child component. When you touch the **Try again** button of the child component, the value of the **count** variable decorated by **@Prop** is changed. As a result, the **CountDownComponent** is rendered again. However, the change of the **count** value does not affect the **countDownStartValue** value of the parent component. - ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->When a new component instance is created, all its **@Prop** decorated variables must be initialized. +In the preceding example, when you press +1 or -1, the status of the parent component changes and the build method is executed again. In this case, a new CountDownComponent is created. The countDownStartValue property of the parent component is used to initialize the @Prop decorated variable of the child component. When you tap the Try again button of the child component, the value of the @Prop decorated variable count is changed. As a result, the CountDownComponent is rendered again. However, the change of the count value does not affect the countDownStartValue value of the parent component. +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> When a new component instance is created, all its @Prop decorated variables must be initialized. diff --git a/en/application-dev/ui/ts-component-states-state.md b/en/application-dev/ui/ts-component-states-state.md index fa1704e770f7c06b1cb112ed040f97a0313ea1f7..143929758de06064f922e5fc82fa71db3ef0b67b 100644 --- a/en/application-dev/ui/ts-component-states-state.md +++ b/en/application-dev/ui/ts-component-states-state.md @@ -1,16 +1,25 @@ -# @State +# @State -The **@State** decorated variable is the internal state data of the component. When the state data is modified, the** build** method of the component is called to refresh the UI. -The **@State** data has the following features: +The @State decorated variable is the internal state data of the component. When the state data is modified, the build method of the component is called to refresh the UI. -- **Support for multiple types**: The following types are supported: strong types by value and by reference, including **class**, **number**, **boolean**, **string**, as well as arrays of these types, that is, **Array**, **Array**, **Array**, and **Array**. **object** and **any** are not allowed. -- **Support for multiple instances**: Multiple instances can coexist in a component. The internal state data of different instances is independent. -- **Internal private**: An attribute marked with **@State** cannot be directly modified outside the component. Its lifecycle depends on the component where it is located. -- **Local initialization required**: Initial values must be allocated to all **@State** decorated variables through the initialization process. Otherwise, they may become undefined in the framework. -- **Support for setting of initial attribute values based on the state variable name**: When creating a component instance, you can explicitly specify the initial value of the **@State** decorated attribute based on the variable name. -## Simple Example of @State Decorated Attribute +The @State data has the following features: + + +- Support for multiple types: The following types are supported: strong types by value and by reference, including class, number, boolean, string, as well as arrays of these types, that is, Array<class>, Array<string>, Array<boolean>, and Array<number>. object and any are not allowed. + +- Support for multiple instances: Multiple instances can coexist in a component. The internal state data of different instances is independent. + +- Private: An attribute marked with @State can only be accessed within the component. + +- Local initialization required: Initial values must be allocated to all @State decorated variables through the initialization process. Otherwise, they may become undefined in the framework. + +- Support for setting of initial attribute values based on the state variable name: When creating a component instance, you can explicitly specify the initial value of the @State decorated attribute based on the variable name. + + +## Simple Example of @State Decorated Attribute + ``` @Entry @@ -33,7 +42,9 @@ struct MyComponent { } ``` -## Complex Example of @State Decorated Variable + +## Complex Example of @State Decorated Variable + ``` // Customize the status data class. @@ -49,7 +60,7 @@ class Model { struct EntryComponent { build() { Column() { - MyComponent({count: 1, increaseBy: 2}) // MyComponent1 in this document + MyComponent({count: 1, increaseBy: 2}) // MyComponent1 in this document MyComponent({title: {value: 'Hello, World 2'}, count: 7}) //MyComponent2 in this document } } @@ -81,14 +92,16 @@ struct MyComponent { } ``` + In the preceding example: -- Two **@State** decorated variables, **count** and **title**, have been defined for **MyComponent**. If the value of **count** or **title** changes, the **build** method of **MyComponent** needs to be called to render the component again. -- The **EntryComponent** has multiple **MyComponent** instances. The internal status change of the first **MyComponent** does not affect the second **MyComponent**. -- When creating a **MyComponent** instance, initialize the variables in the component based on the variable name. For example: - ``` - MyComponent({title: {value: 'Hello, World 2'}, count: 7}) - ``` +- Two @State decorated variables, count and title, have been defined for MyComponent. If the value of count or title changes, the build method of MyComponent needs to be called to render the component again. +- The EntryComponent has multiple MyComponent instances. The internal status change of the first MyComponent does not affect the second MyComponent. +- When creating a MyComponent instance, initialize the variables in the component based on the variable name. For example: + + ``` + MyComponent({title: {value: 'Hello, World 2'}, count: 7}) + ``` diff --git a/en/application-dev/ui/ts-configuration-with-mandatory-parameters.md b/en/application-dev/ui/ts-configuration-with-mandatory-parameters.md index da3e114f5cdbe795914f5b96b169d10ca3d352bc..7060f4ca5d3069bad685c429b4b9bc7f11fa2aac 100644 --- a/en/application-dev/ui/ts-configuration-with-mandatory-parameters.md +++ b/en/application-dev/ui/ts-configuration-with-mandatory-parameters.md @@ -1,24 +1,27 @@ -# Configuration with Mandatory Parameters +# Configuration with Mandatory Parameters + + +If the API definition of a component contains any mandatory parameter, set the parameters in the parentheses next to the component. Use constants to assign values to the parameters. -If the API definition of a component contains mandatory construction parameters, the parameters must be configured in the brackets **\(\)** next to the component. You can use constants to assign values to parameters. Examples: -Set the mandatory parameter **src** of the **** component as follows: -``` -Image('http://xyz/a.jpg') -``` +- Set the mandatory parameter src of the <Image> component as follows: + + ``` + Image('http://xyz/a.jpg') + ``` -Set the mandatory parameter **content** of the **** component as follows: -``` -Text('123') -``` +- Set the mandatory parameter content of the <Text> component as follows: + + ``` + Text('123') + ``` -You can also use variables or expressions to assign values to parameters. The result type returned by an expression must meet the parameter type requirements. -To pass a variable or expression to construct the **Image** and **Text** components: +You can also use variables or expressions to assign values to parameters. The result type returned by an expression must meet the parameter type requirements. For example, to pass a variable or expression to construct the Image and Text components: ``` // imagePath, where imageUrl is a private data variable defined in the component. @@ -29,4 +32,3 @@ Image('http://' + this.imageUrl) // features of the corresponding language. This specification is not limited. Text(`count: ${this.count}`) ``` - diff --git a/en/application-dev/ui/ts-custom-component-initialization.md b/en/application-dev/ui/ts-custom-component-initialization.md index 42d04f5580804797cbb3ad84eaf1cb20e9abdd4c..15008a60b98bf273a408e4e86386e2487e443513 100644 --- a/en/application-dev/ui/ts-custom-component-initialization.md +++ b/en/application-dev/ui/ts-custom-component-initialization.md @@ -1,199 +1,78 @@ -# Custom Component Initialization +# Initialization of Custom Components' Member Variables -This section describes the rules for initializing component state variables. The member variables of a component can be initialized in either of the following ways: -- Local initialization. For example: - ``` - @State counter: Counter = new Counter() - ``` +- Local initialization. For example: + + ``` + @State counter: Counter = new Counter() + ``` -- Initialization using constructor parameters. For example: - - ``` - MyComponent(counter: $myCounter) - ``` +- Initialization using constructor parameters. For example: + + ``` + MyComponent(counter: $myCounter) + ``` The allowed method depends on the decorator of the state variable, as shown in the following table. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Decorator Type

-

Local Initialization

-

Initialization Using Constructor Parameters

-

@State

-

Mandatory

-

Optional

-

@Prop

-

Forbidden

-

Mandatory

-

@Link

-

Forbidden

-

Mandatory

-

@StorageLink

-

Mandatory

-

Forbidden

-

@StorageProp

-

Mandatory

-

Forbidden

-

@Provide

-

Mandatory

-

Optional

-

@Consume

-

Forbidden

-

Forbidden

-

@ObjectLink

-

Forbidden

-

Mandatory

-

Normal member variable

-

Recommended

-

Optional

-
+ + | Decorator Type | Local Initialization | Initialization Using Constructor Parameters | +| -------- | -------- | -------- | +| @State | Mandatory | Optional | +| @Prop | Forbidden | Mandatory | +| @Link | Forbidden | Mandatory | +| @StorageLink | Mandatory | Forbidden | +| @StorageProp | Mandatory | Forbidden | +| @Provide | Mandatory | Optional | +| @Consume | Forbidden | Forbidden | +| @ObjectLink | Forbidden | Mandatory | +| Normal member variable | Recommended | Optional | + As indicated by the preceding table: -- The **@State** decorated variable needs to be initialized locally. The initial value can be overwritten by the constructor parameter. -- The **@Prop** and **@Link** decorated variables must be initialized only by constructor parameters. + +- The @State decorated variables need to be initialized locally. The initial value can be overwritten by the constructor parameter. + +- The @Prop and @Link decorated variables must be initialized only by constructor parameters. + Comply with the following rules when using constructors to initialize member variables: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

From the Variable in the Parent Component (Below) to the Variable in the Child Component (Right)

-

@State

-

@Link

-

@Prop

-

Normal Variable

-

@State

-

Not allowed

-

Allowed

-

Allowed

-

Allowed

-

@Link

-

Not allowed

-

Allowed

-

Not recommended

-

Allowed

-

@Prop

-

Not allowed

-

Not allowed

-

Allowed

-

Allowed

-

@StorageLink

-

Not allowed

-

Allowed

-

Not allowed

-

Allowed

-

@StorageProp

-

Not allowed

-

Not allowed

-

Not allowed

-

Allowed

-

Normal variable

-

Allowed

-

Not allowed

-

Not allowed

-

Allowed

-
+ + | From the Variable in the Parent Component (Below) to the Variable in the Child Component (Right) | @State | @Link | @Prop | Normal Variable | +| -------- | -------- | -------- | -------- | -------- | +| @State | Not allowed | Allowed | Allowed | Allowed | +| @Link | Not allowed | Allowed | Not recommended | Allowed | +| @Prop | Not allowed | Not allowed | Allowed | Allowed | +| @StorageLink | Not allowed | Allowed | Not allowed | Allowed | +| @StorageProp | Not allowed | Not allowed | Not allowed | Allowed | +| Normal variable | Allowed | Not allowed | Not allowed | Allowed | + As indicated by the preceding table: -- The normal variable of the parent component can be used to initialize the **@State** decorated variable of the child component, but not the **@Link** or **@Prop** decorated variable. -- The **@State** decorated variable of the parent component can be used to initialize the **@Prop**, **@Link** \(using **$**\), or normal variables of the child component, but cannot initialize the **@State** decorated variable of the child component. -- The **@Link** decorated variable of the parent component can initialize the **@Link** decorated or normal variables of the child component. However, initializing the **@State** decorated member of the child component can result in a syntax error. In addition, initializing the **@Prop** decorated variable is not recommended. -- The **@Prop** decorated variable of the parent component can be used to initialize the normal variables or **@Prop** decorated variables of the child component, but not the **@State** or **@Link** decorated variables. -- Passing **@StorageLink** and **@StorageProp** from the parent component to the child component is prohibited. -- In addition to the preceding rules, the TypeScript strong type rules need to be followed. -## Example +- The normal variables of the parent component can be used to initialize the @State decorated variables of the child component, but not the @Link or @Prop decorated variables. +- The @State decorated variable of the parent component can be used to initialize the @Prop, @Link (using $), or normal variables of the child component, but not the @State decorated variables of the child component. + +- The @Link decorated variables of the parent component can be used to initialize the @Link decorated or normal variables of the child component. However, initializing the @State decorated members of the child component can result in a syntax error. In addition, initializing the @Prop decorated variables is not recommended. + +- The @Prop decorated variables of the parent component can be used to initialize the normal variables or @Prop decorated variables of the child component, but not the @State or @Link decorated variables. + +- Passing @StorageLink and @StorageProp from the parent component to the child component is prohibited. + +- In addition to the preceding rules, the TypeScript strong type rules need to be followed. + + +## Example + + ``` @Entry @Component @@ -218,7 +97,7 @@ struct CompA { Row() { CompB({bLink: $aLink, // valid init a @Link with reference of another @Link, bProp: this.aState}) // valid init a @Prop with value of a @State - CompB({aLink: $aState, // invalid: type mismatch expected ref to ClassA, provided reference to boolean + CompB({aLink: $aState, // invalid: type missmatch expected ref to ClassA, provided reference to boolean bProp: false}) // valid init a @Prop by constants value } } @@ -234,4 +113,3 @@ struct CompB { } } ``` - diff --git a/en/application-dev/ui/ts-custom-component-lifecycle-callbacks.md b/en/application-dev/ui/ts-custom-component-lifecycle-callbacks.md index 3fbf56db7d03632f4aff64f276234d24ebba8f3f..874d01b5dde8f80947cfc8626f71b1c55db44258 100644 --- a/en/application-dev/ui/ts-custom-component-lifecycle-callbacks.md +++ b/en/application-dev/ui/ts-custom-component-lifecycle-callbacks.md @@ -1,49 +1,23 @@ -# Custom Component Lifecycle Callbacks +# Custom Component Lifecycle Callbacks + The lifecycle callbacks of a custom component are used to notify users of the lifecycle of the component. These callbacks are private and are invoked by the development framework at a specified time at runtime. They cannot be manually invoked from applications. -## Lifecycle Callback Definition - - - - - - - - - - - - - - - - - - - - - -

Function

-

Description

-

aboutToAppear

-

Invoked after a new instance of the custom component is created and before its build function is executed.

-

You can change state variables in the aboutToAppear function. The change will take effect when you execute the build function next time.

-

aboutToDisappear

-

Invoked before the destructor of the custom component is consumed.

-

Do not change state variables in the aboutToDisappear function as doing this can cause unexpected errors. For example, the modification of the @Link decorated variable may cause unstable application running.

-

onPageShow

-

Invoked when a page is displayed. This callback is used in the routing process or scenarios where the application is switched to the foreground or background. Only the custom components decorated by @Entry take effect.

-

onPageHide

-

Invoked when a page is hidden. This callback is used in the routing process or scenarios where the application is switched to the foreground or background. Only the custom components decorated by @Entry take effect.

-

onBackPress

-

Invoked when a user clicks the back button. Only the custom components decorated by @Entry take effect.

-
  • The value true is returned if the page processes the return logic instead of performing page routing.
  • The value false is returned if the default return logic is used.
  • If no value is returned, the default return logic is used.
-
+## Lifecycle Callback Definition + + | Function | Description | +| -------- | -------- | +| aboutToAppear | Invoked after a new instance of the custom component is created and before its build function is executed. You can change state variables in the aboutToAppear function. The change will take effect when you execute the build function next time. | +| aboutToDisappear | Invoked before the destructor of the custom component is consumed. Do not change state variables in the aboutToDisappear function as doing this can cause unexpected errors. For example, the modification of the @Link decorated variable may cause unstable application running. | +| onPageShow | Invoked when a page is displayed. This callback is used in the routing process or scenarios where the application is switched to the foreground or background. Only the custom components decorated by @Entry take effect. | +| onPageHide | Invoked when a page is hidden. This callback is used in the routing process or scenarios where the application is switched to the foreground or background. Only the custom components decorated by @Entry take effect. | +| onBackPress | Invoked when a user clicks the back button. Only the custom components decorated by @Entry take effect.
- The value true is returned if the page processes the return logic instead of performing page routing.
- The value false is returned if the default return logic is used.
- If no value is returned, the default return logic is used. | + -## Example +## Example + ``` @Component struct CountDownTimerComponent { @@ -72,9 +46,10 @@ struct CountDownTimerComponent { } ``` -The example above shows that lifecycle functions are critical for **CountDownTimerComponent** to manage its timer resources. Similar functions include loading resources asynchronously from the network. +The example above shows that lifecycle functions are critical for CountDownTimerComponent to manage its timer resources. Similar functions include loading resources asynchronously from the network. ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- Promise and asynchronous callback functions can be used in lifecycle functions, for example, network resource getters and timer setters. ->- Do not use **async await** in lifecycle functions. +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - Promise and asynchronous callback functions can be used in lifecycle functions, for example, network resource getters and timer setters. +> +> - Do not use async await in lifecycle functions. diff --git a/en/application-dev/ui/ts-declarative-syntax.md b/en/application-dev/ui/ts-declarative-syntax.md deleted file mode 100644 index 806cf1f72eabbe021f18487f711384494c801503..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-declarative-syntax.md +++ /dev/null @@ -1,15 +0,0 @@ -# Declarative Syntax - -- **[Overview](ts-syntax-intro.md)** - -- **[General UI Description Specifications](ts-general-ui-description-specifications.md)** - -- **[About UI State Management](ts-ui-state-management.md)** - -- **[About Rendering Control Syntax](ts-rending-control-syntax.md)** - -- **[About @Component](ts-a-deep-dive-into-component.md)** - -- **[About Syntactic Sugar](ts-syntactic-sugar.md)** - - diff --git a/en/application-dev/ui/ts-declarative-ui-description-specifications.md b/en/application-dev/ui/ts-declarative-ui-description-specifications.md deleted file mode 100644 index 20de125b2f7d3847e8332ef13b50dfad43e90eb9..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-declarative-ui-description-specifications.md +++ /dev/null @@ -1,13 +0,0 @@ -# Declarative UI Description Specifications - -- **[Parameterless Configuration](ts-parameterless-configuration.md)** - -- **[Configuration with Mandatory Parameters](ts-configuration-with-mandatory-parameters.md)** - -- **[Attribution Configuration](ts-attribution-configuration.md)** - -- **[Event Configuration](ts-event-configuration.md)** - -- **[Child Component Configuration](ts-child-component-configuration.md)** - - diff --git a/en/application-dev/ui/ts-event-configuration.md b/en/application-dev/ui/ts-event-configuration.md index fbaaca289df7e1b8d49101eb10e4ac172c1b5d4a..9f216ead2a25bce5fc16b8bcf1a02420e7fea019 100644 --- a/en/application-dev/ui/ts-event-configuration.md +++ b/en/application-dev/ui/ts-event-configuration.md @@ -1,42 +1,40 @@ -# Event Configuration +# Event Configuration -You can use event methods to configure events supported by components. - -- Example of using a lambda expression to configure the event of a component: - - ``` - // Counter is a private data variable defined in the component. - Button('add counter') - .onClick(() => { - this.counter += 2 - }) - ``` - - -- Example of using an anonymous function expression to configure the event of a component: - In this case, **bind** must be used to ensure that the contained components are referenced by **this** in the function body. +You can use event methods to configure events supported by components. - ``` - // Counter is a private data variable defined in the component. - Button('add counter') - .onClick(function () { - this.counter += 2 - }.bind(this)) - ``` +- Example of using a lambda expression to configure the event of a component: + + ``` + // Counter is a private data variable defined in the component. + Button('add counter') + .onClick(() => { + this.counter += 2 + }) + ``` -- Example of using a component's member function to configure the event of the component: - ``` - myClickHandler(): void { - // do something - } +- When using an anonymous function expression to configure the event of a component, bind must be used to ensure that the contained components are referenced by this in the function body. - ... - - Button('add counter') - .onClick(this.myClickHandler) - ``` + ``` + // Counter is a private data variable defined in the component. + Button('add counter') + .onClick(function () { + this.counter += 2 + }.bind(this)) + ``` +- Example of using a component's member function to configure the event of the component: + + ``` + myClickHandler(): void { + // do something + } + + ... + + Button('add counter') + .onClick(this.myClickHandler) + ``` diff --git a/en/application-dev/ui/ts-framework-directory.md b/en/application-dev/ui/ts-framework-directory.md index 75bf3b9fea9cf4341d98b9c423bbc8cea9427955..ce9ac122086ec353c29c44cc9796a19ed3f1deb5 100644 --- a/en/application-dev/ui/ts-framework-directory.md +++ b/en/application-dev/ui/ts-framework-directory.md @@ -1,19 +1,28 @@ -# Directory Structure +# Directory Structure -The following figure shows the typical directory structure of the **eTS** module \(**entry/src/main**\) for an application with feature abilities \(FAs\). -![](figures/en-us_image_0000001251421931.png) +The following figure shows the typical directory structure of the eTS module (entry/src/main) for an application with feature abilities (FAs). + + +![en-us_image_0000001222967752](figures/en-us_image_0000001222967752.png) + Functions of the files are as follows: -- The Extended TypeScript \(eTS\) files that end with the **.ets** extension describe the UI layouts, styles, event interactions, and page logics. + +- The Extended TypeScript (eTS) files that end with the .ets extension describe the UI layouts, styles, event interactions, and page logics. + Functions of the folders and files are as follows: -- The **app.ets** file manages global application logics and lifecycles. -- The **pages** directory stores all component pages. -- The **common** directory stores common code files, such as custom components and public methods. ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- TypeScript and JavaScript files can be imported as page files. +- The app.ets file manages global application logics and lifecycles. + +- The pages directory stores all component pages. + +- The common directory stores common code files, such as custom components and public methods. + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> +> TypeScript and JavaScript files can be imported as page files. diff --git a/en/application-dev/ui/ts-framework-file-access-rules.md b/en/application-dev/ui/ts-framework-file-access-rules.md index 73e828a9ef8f7aad23b421e220f9b0e7174f6feb..15be5a8bc0e02e7b23f2f5badb582bedfc192414 100644 --- a/en/application-dev/ui/ts-framework-file-access-rules.md +++ b/en/application-dev/ui/ts-framework-file-access-rules.md @@ -1,13 +1,19 @@ -# Rules for Accessing Application Code Files +# Rules for Accessing Application Code Files + The application code files can be accessed in the following ways: -- Use a relative path to reference the code file. For example, if the upper-level directory is **../common/utils/utils.ets**, use **./common/utils/utils.ets** for the current directory. -- Use the root path of the current module to reference the code file, for example, **common/utils/utils.ets**. -- Store common code files in the **common** directory. -## Example +- Use a relative path to reference the code file. For example, if the upper-level directory is ../common/utils/utils.ets, use ./common/utils/utils.ets for the current directory. + +- Use the root path of the current module to reference the code file, for example, common/utils/utils.ets. + +- Store common code files in the common directory. + +## Example + + ``` import { FoodData, FoodList } from "../common/utils/utils.ets"; @@ -29,6 +35,7 @@ struct FoodCategoryList { Example for importing a code file: + ``` //common/utils/utils.ets @@ -64,4 +71,3 @@ export struct FoodList { } } ``` - diff --git a/en/application-dev/ui/ts-framework-file.md b/en/application-dev/ui/ts-framework-file.md deleted file mode 100644 index 2a48d61106d7a0f1d50389bea75e8e2db437db5a..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-framework-file.md +++ /dev/null @@ -1,7 +0,0 @@ -# File Organization - -- **[Directory Structure](ts-framework-directory.md)** - -- **[Rules for Accessing Application Code Files](ts-framework-file-access-rules.md)** - - diff --git a/en/application-dev/ui/ts-framework-js-tag.md b/en/application-dev/ui/ts-framework-js-tag.md index 5f7e115ad2d69803312591f23b2f28f7aee593c5..553e3328fd5580db16fa80f90b13819de111f5f2 100644 --- a/en/application-dev/ui/ts-framework-js-tag.md +++ b/en/application-dev/ui/ts-framework-js-tag.md @@ -1,70 +1,21 @@ -# "js" Tag - -Configure the **"js"** tag in the [config.json](https://developer.harmonyos.com/en/docs/documentation/doc-guides/basic-config-file-overview-0000000000011951) file of your application. The **"js"** tag contains the instance name, page route, and window configuration information. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Tag

-

Type

-

Default Value

-

Mandatory

-

Description

-

name

-

string

-

default

-

Yes

-

Name of the eTS instance.

-

pages

-

Array

-

-

-

Yes

-

Page route information. For details, see "pages".

-

window

-

Object

-

-

-

No

-

Window configuration information. For details, see "window".

-

mode

-

Object

-

-

-

No

-

Running type and syntax style of the JS component. For details, see "mode".

-
- -## pages - -The **"pages"** defines the route information of each page's entry component. Each page consists of the page path and page name. The following is an example: +# "js" Tag + + +Configure the "js" tag in the config.json file of your application. The "js" tag contains the instance name, page route, and window configuration information. + + + | Tag | Type | Default Value | Mandatory | Description | +| -------- | -------- | -------- | -------- | -------- | +| name | string | default | Yes | Name of the eTS instance. | +| pages | Array | - | Yes | Page route information. For details, see ["pages"](#pages). | +| window | Object | - | No | Window configuration information. For details, see ["window"](#window). | +| mode | Object | - | No | Running type and syntax style of the JS component. For details, see ["mode"](#mode). | + + +## pages + +The "pages" defines the route information of each page's entry component. Each page consists of the page path and page name. The following is an example: + ``` { @@ -75,33 +26,22 @@ The **"pages"** defines the route information of each page's entry component. } ``` ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- The first page in the **"pages"** list is the home page of the application. ->- The page name must not be a component name, for example, **Text.ets** or **Button.ets**. ->- Each page file must contain the [page entry component](ts-component-based-entry.md) \(with the @Entry decoration\). - -## window - -The **"window"** configures the view window. The following attributes can be configured: - - - - - - - - - - - - -

Type

-

Default Value

-

Description

-

designWidth

-

-

-

Logical width of the view. The default value is 720. (The default value is 454 for wearables.) The logical width of the view determines the unit size of lpx. For example, if designWidth is 720 and the view width is 1440 physical pixels, 1 lpx is 2 physical pixels. For details, see lpx.

-
+> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - The first page in the "pages" list is the home page of the application. +> +> - The page name must not be a component name, for example, Text.ets or Button.ets. +> +> - Each page file must contain the [page entry component](ts-component-based-entry.md) (with the @Entry decoration). + + +## window + +The "window" configures the view window. The following attributes can be configured: + + | Type | Default Value | Description | +| -------- | -------- | -------- | +| designWidth | - | Logical width of the view. The default value is 720. (The default value is 454 for wearables.) The logical width of the view determines the unit size of lpx. For example, if designWidth is 720 and the view width is 1440 physical pixels, 1 lpx is 2 physical pixels. For details, see [lpx](ts-pixel-units.md). | + ``` { @@ -113,45 +53,25 @@ The **"window"** configures the view window. The following attributes can be c } ``` -## mode - -The **"mode"** configures the running type and syntax style of a JS component. The following attributes are supported: - - - - - - - - - - - - - - - - -

Type

-

Default Value

-

Description

-

type

-

-

-

Running type of the JS component. The options are as follows:

-
  • pageAbility: Run the JS component in ability mode.
  • form: Run the JS component as a service widget.
-

syntax

-

-

-

Syntax type of the JS component. The options are as follows:

-
  • hml: compiled in the .hml, .css, or .js style.
  • ets: compiled in the declarative syntax style.
-
- ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->If **type** is set to **form**, **syntax** cannot be **ets**. - -## Example + +## mode + +The "mode" configures the running type and syntax style of a JS component. The following attributes are supported: + + | Type | Default Value | Description | +| -------- | -------- | -------- | +| type | - | Running type of the JS component. The options are as follows:
- pageAbility: Run the JS component in ability mode.
- form: Run the JS component as a service widget. | +| syntax | - | Syntax type of the JS component. The options are as follows:
- hml: compiled in the .hml, .css, or .js style.
- ets: compiled in the declarative syntax style. | + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> If type is set to form, syntax cannot be ets. + + +## Example config.json: + ``` { "app": { @@ -163,19 +83,19 @@ config.json: "vendor": "example" }, "module": { - "js": [{ - "name": "default", - "pages": [ - "pages/index", - "pages/detail" - ], - "window": { - "designWidth": 720 - }, - "mode": { - "type": "pageAbility", - "syntax": "ets" - }, + "js": [{ + "name": "default", + "pages": [ + "pages/index", + "pages/detail" + ], + "window": { + "designWidth": 720 + }, + "mode": { + "type": "pageAbility", + "syntax": "ets" + }, }], "abilities": [{ ... @@ -183,4 +103,3 @@ config.json: } } ``` - diff --git a/en/application-dev/ui/ts-framework.md b/en/application-dev/ui/ts-framework.md deleted file mode 100644 index ee1e6d359efd49ade99c82e33289ee7fac21ff35..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-framework.md +++ /dev/null @@ -1,13 +0,0 @@ -# Framework Overview - -- **[File Organization](ts-framework-file.md)** - -- **["js" Tag](ts-framework-js-tag.md)** - -- **[Resource Access](ts-resource-access.md)** - -- **[Pixel Units](ts-pixel-units.md)** - -- **[Types](ts-types.md)** - - diff --git a/en/application-dev/ui/ts-function-build.md b/en/application-dev/ui/ts-function-build.md index 5415112733ba0a915822ddc2f94073cca2ada01e..26578d47e765f40f7d4fa0c454f4e0fe2692feb8 100644 --- a/en/application-dev/ui/ts-function-build.md +++ b/en/application-dev/ui/ts-function-build.md @@ -1,10 +1,16 @@ -# build Function +# build Function -The **build** function meets the definition of the **Builder** API and is used to define the declarative UI description of components. +The build function meets the definition of the Builder API and is used to define the declarative UI description of components. Components must comply with the preceding Builder API constraints. Custom or preset components are combined in declarative mode in the build method. The build method is called when a component is created or updated. + + + ``` interface Builder { build: () => void } ``` + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> The build method supports only composite components and uses the rendering control syntax. diff --git a/en/application-dev/ui/ts-general-ui-concepts.md b/en/application-dev/ui/ts-general-ui-concepts.md index fd834881baf8524e1f8c7834031c98dcc4f19a38..db5bd3b1e5e3b476ff8faae504616b099a0cbd31 100644 --- a/en/application-dev/ui/ts-general-ui-concepts.md +++ b/en/application-dev/ui/ts-general-ui-concepts.md @@ -1,8 +1,11 @@ -# Basic Concepts +# Basic Concepts + The TypeScript-based declarative development paradigm provides a wide array of basic components, which can be combined and extended in a declarative manner to describe the UI of an application. It also provides basic data binding and event processing mechanisms to help you implement the application interaction logic. -## HelloWorld Example + +## HelloWorld Example + ``` // An example of displaying Hello World. After you click the button, Hello UI is displayed. @@ -20,7 +23,7 @@ struct Hello { Button() { Text('Click me') .fontColor(Color.Red) - }.onClick(() => { + }.onClick(() => { this.myText = 'UI' }) .width(500) @@ -30,14 +33,19 @@ struct Hello { } ``` -## Basic Concepts + +## Basic Concepts The preceding sample code shows the structure of a simple page. It involves the following basic concepts: -- **Decorator**: a special kind of declaration that can be applied to classes, structures, methods, and variables, and assigns special meanings to them. In the sample code, **@Entry**, **@Component**, and **@State** are decorators. -- **Custom component**: a reusable UI unit, which can be combined with other components. In the sample code, **struct Hello** decorated by **@Component** is a custom component. -- **UI description**: declaratively describes the UI structure. In the sample code, the block of code in the **build\(\)** method provides the UI description. -- **Built-in component**: the default basic or layout component preset in the framework. You can directly invoke these components, such as ****, ****, ****, and **** components in the sample code. -- **Attribute method**: a method used to configure component attributes, such as **fontSize\(\)**, **width\(\)**, **height\(\)**, and **color\(\)**. -- **Event method**: a method used to add the component response logic to an event. The logic is set through an event method, such as **onClick\(\)** for a button. +- Decorator: a special kind of declaration that can be applied to classes, structures, methods, and variables. In the sample code, @Entry, @Component, and @State are decorators. + +- Custom component: a reusable UI unit, which can be combined with other components. In the sample code, struct Hello decorated by @Component is a custom component. + +- UI description: declaratively describes the UI structure. In the sample code, the block of code in the build() method provides the UI description. + +- Built-in component: the default basic or layout component preset in the framework. You can directly invoke these components, such as <Column>, <Text>, <Divider>, and <Button> components in the sample code. + +- Attribute method: a method used to configure component attributes, such as fontSize(), width(), height(), and color(). +- Event method: a method used to add the component response logic to an event. In the sample code, the onClick method is added for the Button component for defining the click response logic. diff --git a/en/application-dev/ui/ts-general-ui-description-specifications.md b/en/application-dev/ui/ts-general-ui-description-specifications.md deleted file mode 100644 index 209c5856b1e8cddf865efe8a72d59b7272ed6af3..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-general-ui-description-specifications.md +++ /dev/null @@ -1,9 +0,0 @@ -# General UI Description Specifications - -- **[Basic Concepts](ts-general-ui-concepts.md)** - -- **[Declarative UI Description Specifications](ts-declarative-ui-description-specifications.md)** - -- **[Componentization](ts-component-based.md)** - - diff --git a/en/application-dev/ui/ts-instantiating-a-struct-without-new-keyword.md b/en/application-dev/ui/ts-instantiating-a-struct-without-new-keyword.md deleted file mode 100644 index d4510ca475164a5806c958570e86f28a64351bed..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-instantiating-a-struct-without-new-keyword.md +++ /dev/null @@ -1,23 +0,0 @@ -# Instantiating a struct Without the new Keyword - -You can omit the **new** keyword when instantiating a **struct**. - -``` -// Definition -@Component -struct MyComponent { - build() { - } -} - -// Use -Column() { - MyComponent() -} - -// Equivalent to -new Column() { - new MyComponent() -} -``` - diff --git a/en/application-dev/ui/ts-managing-application-states-apis.md b/en/application-dev/ui/ts-managing-application-states-apis.md deleted file mode 100644 index 3ce3654cbab58c6402a650c0e24194fdac8ab3f4..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-managing-application-states-apis.md +++ /dev/null @@ -1,9 +0,0 @@ -# APIs - -- **[AppStorage](ts-application-states-appstorage.md)** - -- **[PersistentStorage](ts-application-states-apis-persistentstorage.md)** - -- **[Environment](ts-application-states-apis-environment.md)** - - diff --git a/en/application-dev/ui/ts-managing-application-states.md b/en/application-dev/ui/ts-managing-application-states.md deleted file mode 100644 index be78ab93baf2033ec54d9101b0ef31db93d14ddb..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-managing-application-states.md +++ /dev/null @@ -1,7 +0,0 @@ -# Managing Application States - -- **[APIs](ts-managing-application-states-apis.md)** - -- **[Synchronization Between AppStorage and Components](ts-application-states-storagelink-storageprop.md)** - - diff --git a/en/application-dev/ui/ts-managing-component-states.md b/en/application-dev/ui/ts-managing-component-states.md deleted file mode 100644 index b862e704f6dd254dc39134ceb66bbbe7403e7901..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-managing-component-states.md +++ /dev/null @@ -1,9 +0,0 @@ -# Managing Component States - -- **[@State](ts-component-states-state.md)** - -- **[@Prop](ts-component-states-prop.md)** - -- **[@Link](ts-component-states-link.md)** - - diff --git a/en/application-dev/ui/ts-managing-other-states.md b/en/application-dev/ui/ts-managing-other-states.md deleted file mode 100644 index 07380c64163f2a0b6ce57a80bc243510a7278113..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-managing-other-states.md +++ /dev/null @@ -1,9 +0,0 @@ -# Managing Other States - -- **[@observed and @objectLink](ts-other-states-observed-objectlink.md)** - -- **[@Consume and @Provide](ts-other-states-consume-provide.md)** - -- **[@Watch](ts-other-states-watch.md)** - - diff --git a/en/application-dev/ui/ts-media-resource-type.md b/en/application-dev/ui/ts-media-resource-type.md index 402f387f880e132e046e8c58a0c225b0cf88e628..9143da0dc1cf6d62dfb7ccf402d8c50adf7eec58 100644 --- a/en/application-dev/ui/ts-media-resource-type.md +++ b/en/application-dev/ui/ts-media-resource-type.md @@ -1,45 +1,12 @@ -# Media Resource Types - -- The following table describes the image resource types supported by the development framework. - - - - - - - - - - - - - - - - - - - - - - - - - -

Image Format

-

File Name Extension

-

JPEG

-

.jpg

-

PNG

-

.png

-

GIF

-

.gif

-

SVG

-

.svg

-

WEBP

-

.webp

-

BMP

-

.bmp

-
- - +# Media Resource Types + + +- The following table describes the image resource types supported by the development framework. + | Image Format | File Name Extension | + | -------- | -------- | + | JPEG | .jpg | + | PNG | .png | + | GIF | .gif | + | SVG | .svg | + | WEBP | .webp | + | BMP | .bmp | diff --git a/en/application-dev/ui/ts-other-states-consume-provide.md b/en/application-dev/ui/ts-other-states-consume-provide.md index 51a3624a69b9349b10a0294ccc0cb056cc2834c4..4c4e61f92b05e9008d201a7b0b2a2899825ad179 100644 --- a/en/application-dev/ui/ts-other-states-consume-provide.md +++ b/en/application-dev/ui/ts-other-states-consume-provide.md @@ -1,63 +1,34 @@ -# @Consume and @Provide - -As the data provider, **Provide** can update the data of child nodes and trigger page rendering. After **Consume** detects that the **Provide** data is updated, it will initiate re-rendering of the current view. - -**Table 1** @Provide - - - - - - - - - - - - - - - - - - - -

Type

-

Description

-

Decorator parameters

-

Alias: a constant of the string type. If an alias is specified, implement the data update for this alias. If there is no alias, use the variable name as the alias. @Provide("alias") is recommended.

-

Synchronization mechanism

-

The @Provide decorated variable is similar to the @state variable. You can modify the variable to re-render the page. You can also modify the @Consume decorated variable to modify the @State decorated variable reversely.

-

Initial value

-

The initial value must be set.

-

Page re-rendering scenarios

-

1. Primitive types: boolean, string, and number

-

2. @observed: used to modify the attributes of the @observed decorated class.

-

3. Array: Add, delete, or update elements in an array.

-
- -**Table 2** @Consume - - - - - - - - - - -

Type

-

Description

-

Initial value

-

No default value can be set.

-
- ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->To avoid infinite loops caused by circular reference, exercise caution when using **@Provide** and **@Consume**. - -The description of other attributes is the same as that of **@Provide**. +# @Consume and @Provide + +As the data provider, @Provide can update the data of child nodes and trigger page rendering. After @Consume detects that the @Provide data is updated, it will initiate re-rendering of the current view. + + + Table1 @Provide + +| Name | Description | +| -------- | -------- | +| Decorator parameter | A constant of the string type, which is used to set an alias for a decorated variable. If an alias is specified, implement the data update for this alias. If there is no alias, use the variable name as the alias. @Provide("_alias_") is recommended. | +| Synchronization mechanism | The @Provide decorated variable is similar to the @state variable. You can modify the variable to re-render the page. You can also modify the @Consume decorated variable to modify the @State decorated variable reversely. | +| Initial value | The initial value must be set. | +| Page re-rendering scenarios | The following will trigger page re-rendering:
- Changes of variables in primitive types (boolean, string, and number)
- Changes of the @Observed decorated classes or their attributes
- Adding, deleting, or updatingelements in an array | + + + Table2 @Consume + +| Type | Description | +| -------- | -------- | +| Initial value | No default value can be set. | + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> To avoid infinite loops caused by circular reference, exercise caution when using @Provide and @Consume. + + +The description of other attributes is the same as that of @Provide. + + + ``` @Entry @Component @@ -103,4 +74,3 @@ struct CompC { } } ``` - diff --git a/en/application-dev/ui/ts-other-states-observed-objectlink.md b/en/application-dev/ui/ts-other-states-observed-objectlink.md index b62e6a13e4a7b5dac72ae829bb400cfdca13b9ca..7b68a0ab326f728f511329dc3c4d47971fa244f2 100644 --- a/en/application-dev/ui/ts-other-states-observed-objectlink.md +++ b/en/application-dev/ui/ts-other-states-observed-objectlink.md @@ -1,71 +1,181 @@ -# @observed and @objectLink +# @Observed and @ObjectLink -**@observed** is a decorator used for classes, indicating that the data changes in the object will be managed by the UI page. **@objectLink** is used to decorate the variables that are decorated by **@observed**. +This section introduces to you two new decorators: @Observed and @ObjectLink. + + +- @Observed applies to a class, indicating that the data changes in the class are managed by the UI page, for example, @Observed class ClassA {}. + +- @ObjectLink applies to an object decorated by @Observed, for example, @ObjectLink a: ClassA. + + +## Background + +When you need to set bidirectional synchronization in a child component for a variable (parent_a) of its parent component, you can use @State to decorate the variable (parent_a) in the parent component and use @Link to decorate the corresponding variable (child_a) in the child component. In this way, data can be synchronized between the parent component and the specific child component, and between the parent component and its other child components. As shown below, bidirectional synchronization is configured for variables of ClassA in the parent and child components. If attribute c of the variable in child component 1 has its value changed, the parent component will be notified to synchronize the change. If attribute c in the parent component has its value changed, all child components will be notified to synchronize the change. + +![en-us_image_0000001267647861](figures/en-us_image_0000001267647861.png) + +In the preceding example, full synchronization is performed for a data object. If you want to synchronize partial information of a data object in a parent component, and if the information is a class object, use @ObjectLink and @Observed instead, as shown below. + +![en-us_image_0000001267607881](figures/en-us_image_0000001267607881.png) + + +## Configuration Requirement + +- @Observed applies to classes, and @ObjectLink applies to variables. + +- The variables decorated by @ObjectLink must be of the class type. + - The classes must be decorated by @Observed. + - Parameters of the primitive types are not supported. You can use @Prop to perform unidirectional synchronization. + +- @ObjectLink decorated variables are immutable. + - Attribute changes are allowed. If an object is referenced by multiple @ObjectLink decorated variables, all custom components that have these variables will be notified for re-rendering. + +- Default values cannot be set for @ObjectLink decorated variables. + - The parent component must be initialized with a TypeScript expression that involves variables decorated by @State, @Link, @StorageLink, @Provide, or @Consume. + +- @ObjectLink decorated variables are private variables and can be accessed only within the component. + + +## Examples + + +### Example 1 + + ``` -// Object to be observed -@Observed class ClassA { - static nextID : number = 0; - public id : number; - public c: number; - - constructor(c: number) { - this.id = ClassA.nextID++; - this.c = c; +@Observed +class ClassA { + public name : string; + public c: number; + constructor(c: number, name: string = 'OK') { + this.name = name; + this.c = c; + } +} + +class ClassB { + public a: ClassA; + constructor(a: ClassA) { + this.a = a; + } +} + +@Component +struct ViewA { + label : string = "ep1"; + @ObjectLink a : ClassA; + build() { + Column() { + Text(`ViewA [${this.label}]: a.c=${this.a.c}`) + .fontSize(20) + Button(`+1`) + .width(100) + .margin(2) + .onClick(() => { + this.a.c += 1; + }) + Button(`reset`) + .width(100) + .margin(2) + .onClick(() => { + this.a = new ClassA(0); // ERROR, this.a is immutable + }) } + } } -@Observed class ClassB { - public a: ClassA; +@Entry +@Component +struct ViewB { + @State b : ClassB = new ClassB(new ClassA(10)); + build() { + Flex({direction: FlexDirection.Column, alignItems: ItemAlign.Center}) { + ViewA({label: "ViewA #1", a: this.b.a}) + ViewA({label: "ViewA #2", a: this.b.a}) - constructor(a: ClassA) { - this.a = a; + Button(`ViewB: this.b.a.c += 1` ) + .width(320) + .margin(4) + .onClick(() => { + this.b.a.c += 1; + }) + Button(`ViewB: this.b.a = new ClassA(0)`) + .width(240) + .margin(4) + .onClick(() => { + this.b.a = new ClassA(0); + }) + Button(`ViewB: this.b = new ClassB(ClassA(0))`) + .width(240) + .margin(4) + .onClick(() => { + this.b = new ClassB(new ClassA(0)); + }) } + } } ``` + +### Example 2 + + ``` +var nextID: number = 0; +@Observed +class ClassA { + public name : string; + public c: number; + public id : number; + constructor(c: number, name: string = 'OK') { + this.name = name; + this.c = c; + this.id = nextID++; + } +} + @Component struct ViewA { - @ObjectLink a : ClassA; label : string = "ViewA1"; + @ObjectLink a: ClassA; build() { - Row() { - Button(`ViewA [${this.label}] this.a.c=${this.a.c} +1`) + Row() { + Button(`ViewA [${this.label}] this.a.c= ${this.a.c} +1`) .onClick(() => { - this.a.c += 1; + this.a.c += 1; }) - Button(`ViewA [${this.label}] reset this.a =new ClassA(0)`) - .onClick(() => { - this.a = new ClassA(0); // ERROR, this.a is immutable - }) - } + } } } @Entry -@Component +@Component struct ViewB { - @State b : ClassB = new ClassB(new ClassA(0)); - + @State arrA : ClassA[] = [ new ClassA(0), new ClassA(0) ]; build() { - Column() { - ViewA({label: "ViewA #1", a: this.b.a}) - ViewA({label: "ViewA #2", a: this.b.a}) + Column() { + ForEach (this.arrA, (item) => { + ViewA({label: `#${item.id}`, a: item}) + }, + (item) => item.id.toString() + ) + ViewA({label: `ViewA this.arrA[first]`, a: this.arrA[0]}) + ViewA({label: `ViewA this.arrA[last]`, a: this.arrA[this.arrA.length-1]}) - Button(`ViewB: this.b.a = new ClassA(0)`) + Button(`ViewB: reset array`) + .onClick(() => { + this.arrA = [ new ClassA(0), new ClassA(0) ]; + }) + Button(`ViewB: push`) .onClick(() => { - this.b.a = new ClassA(0); - }) - Button(`ViewB: this.b = new ClassB(ClassA(0))`) + this.arrA.push(new ClassA(0)) + }) + Button(`ViewB: shift`) .onClick(() => { - this.b = new ClassB(new ClassA(0)); - }) + this.arrA.shift() + }) } - } + } } ``` - ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->**@ObjectLink** is used to decorate variables and cannot be initialized. **@Observed** is used to decorate a class. - diff --git a/en/application-dev/ui/ts-other-states-watch.md b/en/application-dev/ui/ts-other-states-watch.md index 5e5c10722f6079f2b4e4d313eadadd1bf3485845..3be75d6ee904334e1a5615cb6eb4d4cc6ff6bf26 100644 --- a/en/application-dev/ui/ts-other-states-watch.md +++ b/en/application-dev/ui/ts-other-states-watch.md @@ -1,7 +1,22 @@ -# @Watch +# @Watch -The application can register a callback through **@Watch**. This callback is triggered when a variable decorated by any of the following decorators changes: **@State**, **@Prop**, **@Link**, **@ObjectLink**, **@Provide**, **@Consume**, **@StorageProp**, and **@StorageLink**. The variables in **@Watch** must be enclosed in **""**. +@Watch is used to listen for changes of state variables. The syntax structure is as follows: + + + +``` +@State @Watch("onChanged") count : number = 0 +``` + + +As shown above, add an @Watch decorator to the target state variable to register an onChanged callback. When the state variable count is changed, the onChanged callback will be triggered. + + +@Watch can be used to listen for changes of variables decorated by @State, @Prop, @Link, @ObjectLink, @Provide, @Consume, @StorageProp, or @StorageLink. + + + ``` @Entry @Component @@ -12,7 +27,7 @@ struct CompA { updateTotal() : number { let sum = 0; this.shopBasket.forEach((i) => { sum += i; }); - // calculate new total shop basket value and apply discount if over 100RMB + // Calculate the total amount of items in the shopping basket. If the amount exceeds CNY100, the specified discount will be applied. this.totalPurchase = (sum < 100) ? sum : 0.9 * sum; return this.totalPurchase; } @@ -31,4 +46,3 @@ struct CompA { } } ``` - diff --git a/en/application-dev/ui/ts-parameterless-configuration.md b/en/application-dev/ui/ts-parameterless-configuration.md index bb08205d3361fc55936efb7b04e3a17f64d5dde3..c8a0939c904c5194dad069887ca7d236a800dd76 100644 --- a/en/application-dev/ui/ts-parameterless-configuration.md +++ b/en/application-dev/ui/ts-parameterless-configuration.md @@ -1,8 +1,7 @@ -# Parameterless Configuration +# Configuration Without Parameters -If the API definition of a component does not contain mandatory parameters, you do not need to configure any content in the parentheses next to the component. -For example, the following **Divider** component does not contain parameters: +If the API definition of a component does not contain mandatory parameters, you do not need to configure any content in the parentheses next to the component. For example, the Divider component does not contain parameters: ``` Column() { @@ -11,4 +10,3 @@ Column() { Text('item 2') } ``` - diff --git a/en/application-dev/ui/ts-pixel-units.md b/en/application-dev/ui/ts-pixel-units.md index 30c64a9b078610a68bea9e2f9ff8d20360fabd74..0a5011500f3bc8a928885035faaf4471fb442b61 100644 --- a/en/application-dev/ui/ts-pixel-units.md +++ b/en/application-dev/ui/ts-pixel-units.md @@ -1,83 +1,34 @@ -# Pixel Units +# Pixel Units + The framework provides four pixel units, with vp as the reference data unit. - - - - - - - - - - - - - - - - - - -

Name

-

Description

-

px

-

Physical pixel unit of the screen.

-

vp

-

Pixels specific to the screen density, which are converted into physical pixels of the screen based on the screen pixel density.

-

fp

-

Font pixel, which is similar to vp and varies according to the system font size.

-

lpx

-

Logical pixel unit of the window. It is the ratio of the actual screen width to the logical width (configured by designWidth). For example, if designWidth is set to 720, then 1lpx is equal to 2px for a screen with an actual width of 1440 physical pixels.

-
-## Pixel Unit Conversion + | Name | Description | +| -------- | -------- | +| px | Physical pixel unit of the screen. | +| vp | Pixels specific to the screen density, which are converted into physical pixels of the screen based on the screen pixel density. | +| fp | Font pixel, which is similar to vp and varies according to the system font size. | +| lpx | Logical pixel unit of the window. It is the ratio of the actual screen width to the logical width (configured by [designWidth](ts-framework-js-tag.md)). For example, if designWidth is set to 720, then 1lpx is equal to 2px for a screen with an actual width of 1440 physical pixels. | + + +## Pixel Unit Conversion Conversion from other pixel units to px is supported. - - - - - - - - - - - - - - - - - - - - - - - - -

API

-

Description

-

vp2px(value : number) : number

-

Converts a value in units of vp to a value in units of px.

-

px2vp(value : number) : number

-

Converts a value in units of px to a value in units of vp.

-

fp2px(value : number) : number

-

Converts a value in units of fp to a value in units of px.

-

px2fp(value : number) : number

-

Converts a value in units of px to a value in units of fp.

-

lpx2px(value : number) : number

-

Converts a value in units of lpx to a value in units of px.

-

px2lpx(value : number) : number

-

Converts a value in units of px to a value in units of lpx.

-
+ | API | Description | +| -------- | -------- | +| vp2px(value : number) : number | Converts a value in units of vp to a value in units of px. | +| px2vp(value : number) : number | Converts a value in units of px to a value in units of vp. | +| fp2px(value : number) : number | Converts a value in units of fp to a value in units of px. | +| px2fp(value : number) : number | Converts a value in units of px to a value in units of fp. | +| lpx2px(value : number) : number | Converts a value in units of lpx to a value in units of px. | +| px2lpx(value : number) : number | Converts a value in units of px to a value in units of lpx. | -## Example +## Example + + ``` @Entry @Component @@ -121,5 +72,4 @@ struct Example { } ``` -![](figures/pixel-unit.gif) - +![en-us_image_0000001267607893](figures/en-us_image_0000001267607893.gif) diff --git a/en/application-dev/ui/ts-rending-control-syntax-foreach.md b/en/application-dev/ui/ts-rending-control-syntax-foreach.md index 58714c0b13c4291c47b2ba80136161406650a5e3..7896c60288171b4a19481b0686b1c761f50be0a6 100644 --- a/en/application-dev/ui/ts-rending-control-syntax-foreach.md +++ b/en/application-dev/ui/ts-rending-control-syntax-foreach.md @@ -1,7 +1,10 @@ -# ForEach +# ForEach -The development framework provides **ForEach** to iterate arrays and create components for each array item. **ForEach** is defined as follows: +The development framework provides ForEach to iterate arrays and create components for each array item. ForEach is defined as follows: + + + ``` ForEach( arr: any[], // Array to be iterated @@ -10,28 +13,48 @@ ForEach( ) ``` ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- Loop rendering uses **ForEach** to automatically generate child components from the provided array. ->- **ForEach** must be used in container components. ->- The first parameter must be an array. An empty array is allowed. If an array is empty, no child component is created. You can set the functions whose return values are of the array type, for example, **arr.slice \(1, 3\)**. The set functions cannot change any state variables including the array itself, such as **Array.splice**, **Array.sort**, and **Array.reverse**. ->- The second parameter is used to generate the lambda function of the child components. It generates one or more child components for a given array item. A single component and its child component list must be contained in the braces \(\{...\}\). ->- The third parameter is optional and used as an anonymous function for key value generation. It generates a unique and stable key value for a given array item. When the position of a subitem in the array is changed, the key value of the subitem cannot be changed. When a subitem in the array is replaced with a new item, the key value of the current item must be different from the key value of the new item. The key-value generator is optional. However, for performance reasons, it is strongly recommended that the generator be provided, so that the development framework can better identify array changes. If the array is reversed while no key-value generator is provided, all nodes in **ForEach** will be rebuilt. ->- The generated child components must be allowed in the parent container component of **ForEach**. The child component generator function can contain the **if/else** conditional statement. In addition, **ForEach** can be contained in the **if/else** conditional statement. ->- The calling sequence of subitem generator functions may be different from that of the data items in the array. During the development, do not assume whether the subitem generator and key value generator functions are executed and the execution sequence. The following is an example of incorrect usage: -> ``` -> ForEach(anArray, item => {Text(`${++counter}. item.label`)}) -> ``` -> Below is an example of correct usage: -> ``` -> ForEach(anArray.map((item1, index1) => { return { i: index1 + 1, data: item1 }; }), -> item => Text(`${item.i}. item.data.label`), -> item => item.data.id.toString()) -> ``` - -## Example + +## ForEach + + +ForEach(arr: any[],itemGenerator: (item: any, index?: number) => void, keyGenerator?: (item: any, index?: number) => string):void + + + Table1 Parameters + +| Name | Type | Mandatory | Default Value | Description | +| -------- | -------- | -------- | -------- | -------- | +| arr | any[] | Yes | - | Must be an array. An empty array is allowed. If an array is empty, no child component is created. You can set the functions whose return values are of the array type, for example, arr.slice (1, 3). The set functions cannot change any state variables including the array itself, such as Array.splice, Array.sort, and Array.reverse. | +| itemGenerator | (item: any, index?: number) => void | Yes | - | Used to generate the lambda function of the child components. It generates one or more child components for a given array item. A single component and its child component list must be contained in braces ({...}) | +| keyGenerator | (item: any, index?: number) => string | No | - | Used as an anonymous parameter for generating a unique and stable key value for a given array item. When the position of a subitem in the array is changed, the key value of the subitem cannot be changed. When a subitem in the array is replaced with a new item, the key value of the current item must be different from that of the new item. This key-value generator is optional. However, for performance reasons, it is strongly recommended that the key-value generator be provided, so that the development framework can better identify array changes. If the array is reversed while no key-value generator is provided, all nodes in ForEach will be rebuilt. | + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - ForEach must be used in container components. +> +> - The generated child components are allowed in the parent container component of ForEach. The child component generator function can contain the if/else conditional statement, and the if/else conditional statement can contain ForEach. +> +> - The calling sequence of subitem generator functions may be different from that of the data items in the array. During the development, do not assume whether the subitem generator and key value generator functions are executed and the execution sequence. The following is an example of incorrect usage: +> +> ``` +> ForEach(anArray, item => {Text(`${++counter}. item.label`)}) +> ``` +> +> Below is an example of correct usage: +> +> +> ``` +> ForEach(anArray.map((item1, index1) => { return { i: index1 + 1, data: item1 }; }), +> item => Text(`${item.i}. item.data.label`), +> item => item.data.id.toString()) +> ``` + + +## Example The following is an example of a simple-type array: + ``` @Entry @Component @@ -57,8 +80,8 @@ struct MyComponent { } ``` -The following is an example of a complex-type array: - + The following is an example of a complex-type array: + ``` class Month { year: number @@ -121,4 +144,3 @@ struct Calendar1 { } } ``` - diff --git a/en/application-dev/ui/ts-rending-control-syntax-if-else.md b/en/application-dev/ui/ts-rending-control-syntax-if-else.md index 22af60153a56496b6f5cfd3dc9b7fd72ef0208d2..6dd0f40247033f4c9fb0756bceaf88d375307ac2 100644 --- a/en/application-dev/ui/ts-rending-control-syntax-if-else.md +++ b/en/application-dev/ui/ts-rending-control-syntax-if-else.md @@ -1,16 +1,23 @@ -# if/else +# if/else -Use **if/else** for conditional rendering. ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- State variables can be used in the **if** conditional statement. ->- You can use the **if** conditional statement to implement rendering of child components. ->- The **if** conditional statement must be used in container components. ->- Some container components limit the type or number of child components. When **if** is placed in these components, the limitation applies to components created in **if** and **else** statements. For example, when **if** is used in the **** component, only the **** component can be used in the **if** conditional statement, and only the **** component can be used in the **** component. +Use if/else for conditional rendering. -## Example -Example of using the **if** conditional statement: +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - State variables can be used in the if conditional statement. +> +> - You can use the if conditional statement to implement rendering of child components. +> +> - The if conditional statement must be used in container components. +> +> - Some container components limit the type or number of child components. When if is placed in these components, the limitation applies to components created in if and else statements. For example, when if is used in the <Grid> component, whose child components can only be <GridItem>, only the <GridItem> component can be used in the if conditional statement. + + +## Example + +Example of using the if conditional statement: + ``` Column() { @@ -20,7 +27,10 @@ Column() { } ``` -Example of using the **if**, **else if**, and **else** conditional statements: + +Example of using the if, else if, and else conditional statements: + + ``` Column() { @@ -35,4 +45,3 @@ Column() { } } ``` - diff --git a/en/application-dev/ui/ts-rending-control-syntax-lazyforeach.md b/en/application-dev/ui/ts-rending-control-syntax-lazyforeach.md index 095ff605e8f14fe9fba9d0d09d585d9c55afa127..86743ca4f46230dce98eddbf0c6c54f6eda71516 100644 --- a/en/application-dev/ui/ts-rending-control-syntax-lazyforeach.md +++ b/en/application-dev/ui/ts-rending-control-syntax-lazyforeach.md @@ -1,8 +1,24 @@ -# LazyForEach +# LazyForEach + + +The development framework provides LazyForEach to iterate data from provided data sources and create corresponding components during each iteration. LazyForEach is defined as follows: + -The development framework provides the **LazyForEach** component to iterate data as required and create corresponding components during each iteration. **LazyForEach** is defined as follows: ``` +LazyForEach( + dataSource: IDataSource, // Data source to be iterated + itemGenerator: (item: any) => void, // child component generator + keyGenerator?: (item: any) => string // (optional) Unique key generator, which is recommended. +): void + +interface IDataSource { + totalCount(): number; // Get total count of data + getData(index: number): any; // Get single data by index + registerDataChangeListener(listener: DataChangeListener): void; // Register listener to listening data changes + unregisterDataChangeListener(listener: DataChangeListener): void; // Unregister listener +} + interface DataChangeListener { onDataReloaded(): void; // Called while data reloaded onDataAdded(index: number): void; // Called while single data added @@ -10,42 +26,75 @@ interface DataChangeListener { onDataDeleted(index: number): void; // Called while single data deleted onDataChanged(index: number): void; // Called while single data changed } -interface IDataSource { - totalCount(): number; // Get total count of data - getData(index: number): any; // Get single data by index - registerDataChangeListener(listener: DataChangeListener): void; // Register listener to listening data changes - unregisterDataChangeListener(listener: DataChangeListener): void; // Unregister listener -} -LazyForEach( - dataSource: IDataSource, // Data source to be iterated - itemGenerator: (item: any) => void, // child component generator - keyGenerator?: (item: any) => string // (optional) Unique key generator, which is recommended. -): void ``` ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- When data is updated through **onDataChanged** of **LazyForEach**, if **itemGenerator** contains a fully static view \(that is, the view does not contain state variables\), the view will not be updated. ->- **LazyForEach** is used to automatically generate child components from the provided data source. ->- **LazyForEach** must be used in the container component. Only the ****, ****, and **** components support on-demand data loading \(that is, only the visible part and a small amount of data before and after the visible part are loaded for caching\). For other components, all data is loaded at a time. ->- The first parameter must be an object inherited from **IDataSource**. You need to implement related APIs. ->- The second parameter is used to generate the lambda function of the child components. It generates one or more child components for a given array item. A single component and its child component list must be contained in the braces \(\{...\}\). ->- The third parameter is optional and used as an anonymous function for key value generation. It generates a unique and stable key value for a given array item. When the position of a subitem in the array is changed, the key value of the subitem cannot be changed. When a subitem in the array is replaced with a new item, the key value of the current item must be different from the key value of the new item. The key-value generator is optional. However, for performance reasons, it is strongly recommended that the generator be provided, so that the development framework can better identify array changes. If the array is reversed while no key-value generator is provided, all nodes in **ForEach** will be rebuilt. ->- The generated child component must be allowed in the parent container component of **LazyForEach**, so that **LazyForEach** can be included in the **if/else** conditional statement. ->- **LazyForEach** must create one and only one child component in each iteration. ->- **ForEach** cannot be used as a child component of **LazyForEach**, and **LazyForEach** does not support nesting. ->- The **if/else** conditional statement is not allowed in **LazyForEach**. ->- The calling sequence of the subitem generator function may be different from that of the data items in the data source. During the development, do not assume whether the subitem generator and key value generator functions are executed and the execution sequence. The following is an example of incorrect usage: -> ``` -> ForEach(dataSource, item => {Text(`${++counter}. item.label`)}) -> ``` -> Below is an example of correct usage: -> ``` -> ForEach(dataSource, -> item => Text(`${item.i}. item.data.label`)), -> item => item.data.id.toString()) -> ``` - -## Example + +## APIs + + +### LazyForEach + +LazyForEach(dataSource: IDataSource, itemGenerator: (item: any) => void, keyGenerator?: (item: any) => string):void + + Table1 Parameters + +| Name | Type | Mandatory | Default Value | Description | +| -------- | -------- | -------- | -------- | -------- | +| dataSource | IDataSource | Yes | - | Object used to implement the IDataSource API. You need to implement related APIs. | +| itemGenerator | (item: any) => void | Yes | - | Used to generate the lambda function of the child components. It generates one or more child components for a given array item. A single component and its child component list must be contained in the braces ({...}) | +| keyGenerator | (item: any) => string | No | - | Used as an anonymous parameter for generating a unique and stable key value for a given array item. When the position of a subitem in the array is changed, the key value of the subitem cannot be changed. When a subitem in the array is replaced with a new item, the key value of the current item must be different from that of the new item. This key-value generator is optional. However, for performance reasons, it is strongly recommended that the key-value generator be provided, so that the development framework can better identify array changes. If the array is reversed while no key-value generator is provided, all nodes in LazyForEach will be rebuilt. | + + + Table2 Description of IDataSource + +| Name | Description | +| -------- | -------- | +| totalCount(): number | Obtains the total number of data records. | +| getData(index: number): any | Obtains the data corresponding to the specified index. | +| registerDataChangeListener(listener: DataChangeListener): void | Registers the data change listener. | +| unregisterDataChangeListener(listener: DataChangeListener): void | Unregisters the data change listener. | + + + Table3 Description of DataChangeListener + +| Name | Description | +| -------- | -------- | +| onDataReloaded(): void | Reloads all data. | +| onDataAdded(index: number): void | Notifies the component that data is added to the position indicated by the specified index. | +| onDataMoved(from: number, to: number): void | Notifies the component that data is moved from the from position to the to position. | +| onDataDeleted(index: number): void | Notifies the component that data is deleted from the position indicated by the specified index. | +| onDataChanged(index: number): void | Notifies the component that data in the position indicated by the specified index is changed. | + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - LazyForEach must be used in the container component. Only the <List>, <Grid>, and <Swiper> components support LazyForEach (that is, only the visible part and a small amount of data before and after the visible part are loaded for caching). For other components, all data is loaded at a time. +> +> - LazyForEach must create one and only one child component in each iteration. +> +> - The generated child component must be in the parent container component of LazyForEach. +> +> - LazyForEach can be included in an if/else conditional statement, but cannot contain an if/else conditional statement. +> +> - For the purpose of high-performance rendering, when the onDataChanged method of the DataChangeListener object is used to update the UI, the component update is triggered only when the state variable is used in the component specified in the UI description of itemGenerator. +> +> - The calling sequence of the subitem generator function may be different from that of the data items in the data source. During the development, do not assume whether the subitem generator and key value generator functions are executed and the execution sequence. The following is an example of incorrect usage: +> +> ``` +> LazyForEach(dataSource, item => {Text(`${++counter}. item.label`)}) +> ``` +> +> Below is an example of correct usage: +> +> +> ``` +> LazyForEach(dataSource, +> item => Text(`${item.i}. item.data.label`)), +> item => item.data.id.toString()) +> ``` + + +## Example + ``` // Basic implementation of IDataSource to handle data listener @@ -141,4 +190,3 @@ struct MyComponent { } } ``` - diff --git a/en/application-dev/ui/ts-rending-control-syntax.md b/en/application-dev/ui/ts-rending-control-syntax.md deleted file mode 100644 index e8626c1a4acc4e4881c7648e973fb9555164f4af..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-rending-control-syntax.md +++ /dev/null @@ -1,9 +0,0 @@ -# About Rendering Control Syntax - -- **[if/else](ts-rending-control-syntax-if-else.md)** - -- **[ForEach](ts-rending-control-syntax-foreach.md)** - -- **[LazyForEach](ts-rending-control-syntax-lazyforeach.md)** - - diff --git a/en/application-dev/ui/ts-resource-access.md b/en/application-dev/ui/ts-resource-access.md deleted file mode 100644 index 3294e7f68de3f762505efa0d18117ae6a35e9e1b..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-resource-access.md +++ /dev/null @@ -1,7 +0,0 @@ -# Resource Access - -- **[Accessing Application Resources](ts-application-resource-access.md)** - -- **[Media Resource Types](ts-media-resource-type.md)** - - diff --git a/en/application-dev/ui/ts-restrictions-for-generators.md b/en/application-dev/ui/ts-restrictions-for-generators.md deleted file mode 100644 index 03e708ccc7e83178c1c39b1f55b49c279b36eb2f..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-restrictions-for-generators.md +++ /dev/null @@ -1,26 +0,0 @@ -# Restrictions on Using TypeScript for Generators - -TypeScript has the following restrictions on generators: - -- Expressions can be used only in character strings \($\{expression\}\), **if** conditions, **ForEach** parameters, and component parameters. -- No expressions should cause any application state variables \(**@State**, **@Link**, and **@Prop**\) to change. Otherwise, undefined and potentially unstable framework behavior may occur. -- You can use **console.log** in the first line of the generator function body so that you can track component re-rendering more easily. Expressions in the log character strings also comply with the preceding restrictions. -- The generator function cannot contain local variables. - -None of the above restrictions apply to anonymous function implementations of event-handling functions \(such as **onClick**\) and to the rest of the UI component description. - -Incorrect: - -``` -build() { - let a: number = 1 // invalid: variable declaration not allowed - console.log(`a: ${a}`) // invalid: console.log only allowed in first line of build - Column() { - Text('Hello ${this.myName.toUpperCase()}') // ok. - ForEach(this.arr.reverse(), ..., ...) // invalid: Array.reverse modifies the @State array varible in place - } - buildSpecial() // invalid: no function calls - Text(this.calcTextValue()) // this function call is ok. -} -``` - diff --git a/en/application-dev/ui/ts-syntactic-sugar-chaining.md b/en/application-dev/ui/ts-syntactic-sugar-chaining.md deleted file mode 100644 index 6cccebeeead49fad7eba642fd668b7b902c7f2e4..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-syntactic-sugar-chaining.md +++ /dev/null @@ -1,13 +0,0 @@ -# Chain Call - -You can configure the UI structure and its attributes and events and separate them with a dot\(.\) to implement chain call. - -``` -Column() { - Image('1.jpg') - .alt('error.jpg') - .width(100) - .height(100) -}.padding(10) -``` - diff --git a/en/application-dev/ui/ts-syntactic-sugar-decorator.md b/en/application-dev/ui/ts-syntactic-sugar-decorator.md deleted file mode 100644 index d2bc0707dcab41db9ba908d8c69905e0d15e85b8..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-syntactic-sugar-decorator.md +++ /dev/null @@ -1,80 +0,0 @@ -# @Decorator - -**@Decorator** can be applied to variable declarations, class definitions, structure definitions, or method definitions. - -Multiple decorator implementations can be superimposed on the target element and written on the same line or multiple lines. It is recommended that the implementation be written on multiple lines. - -In the example below, the elements decorated by **@Component** take on the form of a component, and the variables decorated by **@State** have the meaning of state data. - -``` -@Component -struct MyComponent { - @State count: number = 0 -} -``` - -Multiple decorator implementations can be written on the same line. - -``` -@Entry @Component struct MyComponent { -} -``` - -However, you are advised to write the decorator implementations on multiple lines. - -``` -@Entry -@Component -struct MyComponent { -} -``` - -## Supported Decorators - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Decorator

-

Decorates...

-

Description

-

@Component

-

struct

-

The decorated structure has the component-based capability. The build method must be implemented to update the UI.

-

@Entry

-

struct

-

The decorated component is used as the entry of a page. The component is rendered and displayed when the page is loaded.

-

@State

-

Primitive types, classes, and arrays

-

If the decorated state data is modified, the build method of the component will be called to update the UI.

-

@Prop

-

Primitive types

-

The modified state data is used to establish a unidirectional data dependency between the parent component and the child component. When the data associated with the parent component is modified, the UI of the current component is updated.

-

@Link

-

Primitive types, classes, and arrays

-

This decorator is used for two-way binding between the parent component and the child component. The internal state data of the parent component is used as the data source. Any changes made to one component will be reflected to the other.

-
- diff --git a/en/application-dev/ui/ts-syntactic-sugar-struct.md b/en/application-dev/ui/ts-syntactic-sugar-struct.md deleted file mode 100644 index 3755803f5de09fc94442c2597531366c5d70e964..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-syntactic-sugar-struct.md +++ /dev/null @@ -1,14 +0,0 @@ -# struct - -Components can be implemented based on **struct**s. Components cannot inherit from each other. The **struct**s implemented components can be created and destroyed more quickly than **class** implemented components. - -``` -@Component -struct MyComponent { - @State data: string = '' - - build() { - } -} -``` - diff --git a/en/application-dev/ui/ts-syntactic-sugar.md b/en/application-dev/ui/ts-syntactic-sugar.md index 088e9598c05662fe8f3331c94a4b1980377f432f..4f367db9ee810ccd016780c68e37078b82d8d522 100644 --- a/en/application-dev/ui/ts-syntactic-sugar.md +++ b/en/application-dev/ui/ts-syntactic-sugar.md @@ -1,15 +1,168 @@ -# About Syntactic Sugar +# About Syntactic Sugar -- **[@Decorator](ts-syntactic-sugar-decorator.md)** -- **[Chain Call](ts-syntactic-sugar-chaining.md)** +## Decorators -- **[struct](ts-syntactic-sugar-struct.md)** +A decorator @Decorator can decorate a class, structure, or class attribute. Multiple decorators can be applied to the same target element and defined on a single line or multiple lines. It is recommended that the decorators be defined on multiple lines. -- **[Instantiating a struct Without the new Keyword](ts-instantiating-a-struct-without-new-keyword.md)** +In the example below, the elements decorated by @Component take on the form of a component, and the variables decorated by @State can be used to represent states. -- **[Using a Separate Line for New Component](ts-using-a-separate-line-for-new-component.md)** -- **[Restrictions on Using TypeScript for Generators](ts-restrictions-for-generators.md)** +``` +@Component +struct MyComponent { + @State count: number = 0 +} +``` +Multiple decorators can be defined on a single line, as shown below: + + +``` +@Entry @Component struct MyComponent { +} +``` + +However, you are advised to define the decorators on multiple lines, as shown below: + + +``` +@Entry +@Component +struct MyComponent { +} +``` + + +### Supported Decorators + + | Decorator | Decorates... | Description | +| -------- | -------- | -------- | +| @Component | struct | The decorated structure has the component-based capability. The build method must be implemented to update the UI. | +| @Entry | struct | The decorated component is used as the entry of a page. The component is rendered and displayed when the page is loaded. | +| @Preview | struct | Custom components decorated by @Preview can be previewed in the Previewer of DevEco Studio. When the page is loaded, the custom components decorated by @Preview are created and displayed. | +| @Builder | Methods | In the decorated method, you can use the declarative UI description to quickly generate multiple layouts in a custom component. | +| @Extend | Methods | This decorator adds new attribute functions to a preset component, allowing you to quickly define and reuse the custom style of the component. | +| @CustomDialog | struct | This decorator is used to decorate custom pop-up dialog boxes. | +| @State | Primitive data types, classes, and arrays | If the decorated state data is modified, the build method of the component will be called to update the UI. | +| @Prop | Primitive data types | This decorator is used to establish one-way data binding between the parent and child components. When the data associated with the parent component is modified, the UI of the current component is updated. | +| @Link | Primitive data types, classes, and arrays | This decorator is used to establish two-way data binding between the parent and child components. The internal state data of the parent component is used as the data source. Any changes made to one component will be reflected to the other. | +| @Observed | Classes | This decorator is used to indicate that the data changes in the class will be managed by the UI page. | +| @ObjectLink | Objects of @Observed decorated classes | When the decorated state variable is modified, the parent and sibling components that have the state variable will be notified for UI re-rendering. | +| @Consume | Primitive data types, classes, and arrays | When the @Consume decorated variable detects the update of the @Provide decorated variable, the re-rendering of the current custom component is triggered. | +| @Provide | Primitive data types, classes, and arrays | As the data provider, @Provide can update the data of child nodes and trigger page rendering. | +| @Watch | Variables decorated by @State, @Prop, @Link, @ObjectLink, @Provide, @Consume, @StorageProp, or @StorageLink | This decorator is used to listen for the changes of the state variables. The application can register a callback method through @Watch. | + + +## Chain Call + +You can configure the UI structure and its attributes and events and separate them with a dot(.) to implement chain call. + + +``` +Column() { + Image('1.jpg') + .alt('error.jpg') + .width(100) + .height(100) +}.padding(10) +``` + + +## struct + +Components can be implemented based on structs. Components cannot inherit from each other. The structs implemented components can be created and destroyed more quickly than class implemented components. + + +``` +@Component +struct MyComponent { + @State data: string = '' + + build() { + } +} +``` + + +## Instantiating a struct Without the new Keyword + +You can omit the new keyword when instantiating a struct. + + +``` +// Definition +@Component +struct MyComponent { + build() { + } +} + +// Use +Column() { + MyComponent() +} + +// Equivalent to +new Column() { + new MyComponent() +} +``` + + +## Restrictions on Using TypeScript in Generators + +TypeScript has the following restrictions on generators: + +- Expressions can be used only in character strings (${expression}), if conditions, ForEach parameters, and component parameters. + +- No expressions should cause any application state variables (@State, @Link, and @Prop) to change. Otherwise, undefined and potentially unstable framework behavior may occur. + +- The generator function cannot contain local variables. + +None of the above restrictions apply to anonymous function implementations of event-handling functions (such as onClick) + +Incorrect: + + +``` +build() { + let a: number = 1 // invalid: variable declaration not allowed + Column() { + Text('Hello ${this.myName.toUpperCase()}') // ok. + ForEach(this.arr.reverse(), ..., ...) // invalid: Array.reverse modifies the @State array varible in place + } + buildSpecial() // invalid: no function calls + Text(this.calcTextValue()) // this function call is ok. +} +``` + +## $$ + +$$ supports two-way binding for simple variables and @State, @Link, and @Prop decorated variables. + +Currently, $$ supports only the rendering between the show parameter of the bindPopup attribute and the @State decorated variable, and the checked attribute of the component. + +``` +@Entry +@Component +struct bindPopup { + @State customPopup: boolean = false + build() { + Column() { + Button(){ + Text('Popup') + } + .onClick(()=>{ + this.customPopup = !this.customPopup + }) + .bindPopup( + $$this.customPopup, { + message: "showPopup" + } + ) + } + } +} +``` diff --git a/en/application-dev/ui/ts-syntax-intro.md b/en/application-dev/ui/ts-syntax-intro.md index 87fdf54d31c403eda07675cb8a6d11924a857b94..a1ac7a1d8a25bcc25e0b85ade30d278b1ca91e1c 100644 --- a/en/application-dev/ui/ts-syntax-intro.md +++ b/en/application-dev/ui/ts-syntax-intro.md @@ -1,11 +1,16 @@ -# Overview +# Overview + This section defines the core mechanism and functions of the TypeScript-based declarative development paradigm. It acquaints you with the declarative UI descriptions, componentization mechanisms, UI state management, rendering control syntax, and syntactic sugar. -Follow the provided guidelines for UI development. For details about the components, see [Components](../reference/arkui-js/js-components.md). ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- All examples use the TypeScript \(TS\) language. If you are using another language, comply with the syntax requirements for that language. ->- The components used in the examples are preset in the UI framework and are used only to explain the UI description specifications. ->- Universal attribute and event methods generally apply to all components, and the attribute and event methods within a component apply only to this component. +Follow the provided guidelines for UI development. For details about the components, see components. + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - All examples use the TypeScript (TS) language. If you are using another language, comply with the syntax requirements for that language. +> +> - The components used in the examples are preset in the UI framework and are used only to explain the UI description specifications. +> +> - Universal attribute and event methods generally apply to all components, and the attribute and event methods within a component apply only to this component. diff --git a/en/application-dev/ui/ts-system-resource-access.md b/en/application-dev/ui/ts-system-resource-access.md index fbdeaceeb58762693645cb6e3b4e214516bce045..e3879354d0998ff54cf5d78547dd0d94280e721d 100644 --- a/en/application-dev/ui/ts-system-resource-access.md +++ b/en/application-dev/ui/ts-system-resource-access.md @@ -4,7 +4,7 @@ System resources include colors, rounded corners, fonts, spacing, character strings, and images. By using system resources, you can develop different applications with the same visual style. -To reference a system resource, use the **"$r('sys.type.resource_id')"** format. Wherein: **sys** indicates a system resource; **type** indicates the resource type, which can be **color**, **float**, **string**, or **media**; **resource_id** indicates the resource ID, which is determined when the system resource is provided. For details about available system resource IDs. +To reference a system resource, use the "$r('sys.type.resource_id')" format. Wherein: sys indicates a system resource; type indicates the resource type, which can be color, float, string, or media; resource_id indicates the resource ID, which is determined when the system resource is provided. For details about available system resource IDs. ``` Text('Hello') diff --git a/en/application-dev/ui/ts-types.md b/en/application-dev/ui/ts-types.md index e2c2187fa7283326f39a493f2214498c6eb52162..7a6838d2453d1bcf681e6ae397481653b5074e5e 100644 --- a/en/application-dev/ui/ts-types.md +++ b/en/application-dev/ui/ts-types.md @@ -4,33 +4,33 @@ | Name| Type| Description| | -------- | -------- | -------- | -| Length | string \| number | Length unit. If the input is a number, use **vp**. If the input is a string, explicitly specify the unit, for example, **'10px'**, or specify the length in percentage, for example, **'100%'**.| +| Length | string \| number | Length unit. If the input is a number, use vp. If the input is a string, explicitly specify the unit, for example, '10px', or specify the length in percentage, for example, '100%'.| ## Angle Type | Name| Type| Description| | -------- | -------- | -------- | -| Angle | string \| number | Angle unit. If the input is a number, use **deg**. If the input is a string, use either of the following angle units:
- **deg**: for example, **'100deg'**
- **rad**: for example, **'3.14rad'** | +| Angle | string \| number | Angle unit. If the input is a number, use deg. If the input is a string, use either of the following angle units:
- deg: for example, '100deg'
- rad: for example, '3.14rad' | ## Point Type | Name| Type| Description| | -------- | -------- | -------- | -| Point | [Length, Length] | Coordinates of a point. The first value is the x-axis coordinate, and the second value is the y-axis coordinate.| +| Point | [Length, Length] | Coordinates of a point. The first value is the x-axis coordinate, and the second value is the y-axis coordinate.| ## Color Type -The **Color** type used by component attribute methods is described as follows: +The Color type used by component attribute methods is described as follows: | Name| Type| Description| | -------- | -------- | -------- | -| Color | string \| number \| Color | Color information. If the input is a string, use **rgb** or **rgba** to specify the color. If the input is a number, use Hex format to specify the color. If the input is a **Color** enum, use a color value to specify the color.
- 'rgb(255, 255, 255)'
- 'rgba(255, 255, 255, 1.0)'
- Hex format: 0xrrggbb, 0xaarrggbb, '\#FFFFFF'
- Enum: Color.Black, Color.White | +| Color | string \| number \| Color | Color information. If the input is a string, use rgb or rgba to specify the color. If the input is a number, use Hex format to specify the color. If the input is a Color enum, use a color value to specify the color.
- 'rgb(255, 255, 255)'
- 'rgba(255, 255, 255, 1.0)'
- Hex format: 0xrrggbb, 0xaarrggbb, '\#FFFFFF'
- Enum: Color.Black, Color.White | -The supported **Color** enums are described as follows: +The supported Color enums are described as follows: | Color| Value| Illustration| @@ -49,60 +49,60 @@ The supported **Color** enums are described as follows: ## ColorStop Type -**ColorStop** is used to describe the progressive color stop. +ColorStop is used to describe the progressive color stop. | Name| Type| Description| | -------- | -------- | -------- | -| ColorStop | [Color, number] | Type of the progressive color stop. The first parameter specifies the color value, and the second parameter specifies the ratio of 0 to 1.| +| ColorStop | [Color, number] | Type of the progressive color stop. The first parameter specifies the color value, and the second parameter specifies the ratio of 0 to 1.| ## Resource Type -The **Resource** type is used to reference resources for setting the value of a component attribute. +The Resource type is used to reference resources for setting the value of a component attribute. -You can use **$r** or **$rawfile** to create a **Resource** object. For details, see [Resource Access](ts-application-resource-access.md). +You can use $r or $rawfile to create a Resource object. For details, see [Resource Access](ts-application-resource-access.md). - $r('belonging.type.name') - **belonging**: system or application resource. The value can be **'sys'** or **'app'**. + belonging: system or application resource. The value can be 'sys' or 'app'. - **type**: resource type, which can be **'color'**, **'float'**, **'string'**, or **'media'**. + type: resource type, which can be 'color', 'float', 'string', or 'media'. - **name**: resource name, which is determined during resource definition. + name: resource name, which is determined during resource definition. - $rawfile('filename') - **filename**: name of the file in **resources/rawfile** of the project. + filename: name of the file in resources/rawfile of the project. | Name| Type| Description| | -------- | -------- | -------- | -| Resource | {
readonly id: [number];
readonly type: [number];
readonly params?: any[];
} | **id**: resource ID.
**type**: resource type (enumerated value).
**params**: optional parameters.
After a **Resource** object is created using **$r** or **$rawfile**, modifying attribute values of the object is prohibited.| +| Resource | {
readonly id: [number];
readonly type: [number];
readonly params?: any[];
} | id: resource ID.
type: resource type (enumerated value).
params: optional parameters.
After a Resource object is created using $r or $rawfile, modifying attribute values of the object is prohibited.| ## ResourceStr Type8+ | Name| Type| Description| | -------- | -------- | -------- | -| ResourceStr | string \| Resource| Resource string.| +| ResourceStr | string \| Resource| Resource string.| ## ResourceColor Type8+ | Name| Type| Description| | -------- | -------- | -------- | -| ResourceColor | Color \| number \| string \| Resource | Resource color.| +| ResourceColor | Color \| number \| string \| Resource | Resource color.| ## Font Type8+ | Name| Type| Description| | -------- | -------- | -------- | -| Font | {
size?: Length;
weight?: FontWeight  \| number  \| string;
family?: string  \| Resource;
style?: FontStyle;
} | Text style.
**size**: font size. For the number type, use the unit fp.
**weight**: font weight. For the number type, the value ranges from 100 to 900, at an interval of 100. The default value is 400. A larger value indicates a larger font weight.
**family**: font family. Use commas (,) to separate multiple fonts. The priority of the fonts is the sequence in which they are placed. An example value is **'Arial, sans-serif'**.
**style**: font style.| +| Font | {
size?: Length;
weight?: FontWeight \| number \| string;
family?: string \| Resource;
style?: FontStyle;
} | Text style.
size: font size. For the number type, use the unit fp.
weight: font weight. For the number type, the value ranges from 100 to 900, at an interval of 100. The default value is 400. A larger value indicates a larger font weight.
family: font family. Use commas (,) to separate multiple fonts. The priority of the fonts is the sequence in which they are placed. An example value is 'Arial, sans-serif'.
style: font style.| ## CustomBuilder Type8+ -You can use **CustomBuilder** to define custom UI descriptions in component attribute methods. +You can use CustomBuilder to define custom UI descriptions in component attribute methods. | Name| Type| Description| | -------- | -------- | -------- | -| CustomBuilder | () => any | Builder of component attribute methods for defining custom UI descriptions. This type of method must be decorated by **@Builder**. For details, see [@Builder](ts-component-based-builder.md).| +| CustomBuilder | () => any | Builder of component attribute methods for defining custom UI descriptions. This type of method must be decorated by @Builder. For details, see [@Builder](ts-component-based-builder.md).| ## Example diff --git a/en/application-dev/ui/ts-ui-state-management.md b/en/application-dev/ui/ts-ui-state-management.md deleted file mode 100644 index fd37d287c456038cc1a9709048a71255d8ab6722..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-ui-state-management.md +++ /dev/null @@ -1,11 +0,0 @@ -# About UI State Management - -- **[Basic Concepts](ts-ui-state-mgmt-concepts.md)** - -- **[Managing Component States](ts-managing-component-states.md)** - -- **[Managing Application States](ts-managing-application-states.md)** - -- **[Managing Other States](ts-managing-other-states.md)** - - diff --git a/en/application-dev/ui/ts-ui-state-mgmt-concepts.md b/en/application-dev/ui/ts-ui-state-mgmt-concepts.md index ec3fbe4640e2bbe9c66ca2d4171beb3767fcd5a0..a25d43a5767e9f25f73f7a1bb46903a279451cf3 100644 --- a/en/application-dev/ui/ts-ui-state-mgmt-concepts.md +++ b/en/application-dev/ui/ts-ui-state-mgmt-concepts.md @@ -1,27 +1,27 @@ -# Basic Concepts +# Basic Concepts -In the declarative UI programming paradigm, the UI is a function in the specific application state, and you update a UI by modifying the current application state. -The development framework provides comprehensive application state management capabilities, as shown in the figure below. +In the declarative UI programming paradigm, the UI is a function in the specific application state, and you update a UI by modifying the current application state. The development framework provides comprehensive application state management capabilities, as shown in the figure below. -![](figures/corespec_figures_state-mgmt-overview.png) -## State Variable Decorators +![en-us_image_0000001222967768](figures/en-us_image_0000001222967768.png) -- **@State**: grants a component the state attribute. Each time the **@State** decorated variable changes, the component re-renders and updates the UI. -- **@Link**: allows a component to depend on some state attributes of its parent component. Each time the data in one component is updated, the state of the other component is updated, and the parent and child components are rendered again. +## State Variable Decorators -- **@Prop**: works in a way similar to that of **@Link**. The only difference is that the changes made by a child component are not synchronized to the parent component. +- @State: state attribute of the component. Each time the @State decorated variable changes, the component re-renders and updates the UI. - > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE** - > The state variable name cannot be **id**, for example, **@Prop id:number**. +- @Link: allows a component to depend on some state attributes of its parent component. Each time the data in one component is updated, the state of the other component is updated, and the parent and child components are rendered again. -## Application State Data +- @Prop: works in a way similar to that of @Link. The difference is that the changes made by a child component are not synchronized to the parent component. -**AppStorage** is the central store of the application states used in the entire UI. The UI framework creates a singleton **AppStorage** object for the application and provides the corresponding decorators and APIs for the application. -- **@StorageLink**: works in a way similar to that of **@Consume**. The difference is that the link object with the specified name is obtained from the **AppStorage**. It establishes two-way binding between the UI component and **AppStorage** to synchronize data. -- **@StorageProp**: synchronizes UI component attributes with the **AppStorage** unidirectionally. The value change in the **AppStorage** will trigger an update of the attribute value in the UI component, but the attribute value of the UI component will not cause an update of the attribute value in the **AppStorage**. -- Service logic implementation API: adds, reads, modifies, or deletes the state attributes of applications. The changes made by this API will be synchronized to the UI component for UI update. +## Application State Data +AppStorage is the central store of the application states in the entire UI. The UI framework creates a singleton AppStorage object for the application and provides the corresponding decorators and APIs for the application. + +- @StorageLink: works in a way similar to that of @Consume. The difference is that the link object with the specified name is obtained from the AppStorage. It establishes two-way binding between the UI component and AppStorage to synchronize data. + +- @StorageProp: synchronizes UI component attributes with the AppStorage unidirectionally. That is, the value change in the AppStorage will trigger an update of the corresponding UI component, but the change of the UI component will not cause an update of the attribute value in the AppStorage. + +- Service logic implementation API: adds, reads, modifies, or deletes the state attributes of applications. The changes made by this API will be synchronized to the UI component for UI update. diff --git a/en/application-dev/ui/ts-using-a-separate-line-for-new-component.md b/en/application-dev/ui/ts-using-a-separate-line-for-new-component.md deleted file mode 100644 index 9a220f54a95d24d195d3ab1dad5004f12223feb6..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ts-using-a-separate-line-for-new-component.md +++ /dev/null @@ -1,50 +0,0 @@ -# Using a Separate Line for New Component - -**Semicolons \(;\) can be omitted at the end of each line of code.** - -``` -Column() { - Image('icon.png') - Text('text') -} -``` - -It is equivalent to: - -``` -Column() { - Image('icon.png'); - Text('text'); -} -``` - -**Only one component can be created in a line. An if, else, else if, or ForEach statement must also be in a separate line.** - -Incorrect: - -``` -Column() { - Image('icon.png') Text('text') // invalid, creation of two components in same line -} - -if (this.condi) {Image('icon.png')} // invalid, if and creation a components in same line -``` - -**Built-in container components, if, and ForEach item generator functions must use closed parentheses \(\{\}\) in the case of a single subitem.** - -Incorrect: - -``` -if (this.condi) -Image('icon.png'), // invalid, missing {} -else - Text('text'); -``` - -``` -ForEach(this.arr, - (item) => Image('icon.png'), // invalid, missing {} - (item) => item.id.toString() -} -``` - diff --git a/en/application-dev/ui/ui-arkui-js.md b/en/application-dev/ui/ui-arkui-js.md deleted file mode 100644 index f43f305fc3ddc40343a1d3f7d685a7bf394c04aa..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ui-arkui-js.md +++ /dev/null @@ -1,15 +0,0 @@ -# JavaScript-based Web-Like Development Paradigm - -- **[Overview](ui-js-overview.md)** - -- **[Framework](js-framework.md)** - -- **[Building the UI](ui-js-building-ui.md)** - -- **[Common Component Development Guidelines](ui-js-common-components.md)** - -- **[Animation Development Guidelines](ui-js-animate.md)** - -- **[Custom Components](ui-js-custom-components.md)** - - diff --git a/en/application-dev/ui/ui-arkui-ts.md b/en/application-dev/ui/ui-arkui-ts.md deleted file mode 100644 index e22bf628a98afc6c86be83f65da7c83492d45e51..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ui-arkui-ts.md +++ /dev/null @@ -1,13 +0,0 @@ -# TypeScript-based Declarative Development Paradigm - -- **[Overview](ui-ts-overview.md)** - -- **[Framework Overview](ts-framework.md)** - -- **[Declarative Syntax](ts-declarative-syntax.md)** - -- **[Experiencing the Declarative UI](ui-ts-experiencing-declarative-ui.md)** - -- **[Defining Page Layout and Connection](ui-ts-page-layout-connections.md)** - - diff --git a/en/application-dev/ui/ui-arkui.md b/en/application-dev/ui/ui-arkui.md deleted file mode 100644 index 669dfd6203114becefec73cfbb2914c182036c4c..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ui-arkui.md +++ /dev/null @@ -1,7 +0,0 @@ -# ArkUI - -- **[JavaScript-based Web-Like Development Paradigm](ui-arkui-js.md)** - -- **[TypeScript-based Declarative Development Paradigm](ui-arkui-ts.md)** - - diff --git a/en/application-dev/ui/ui-js-animate-attribute-style.md b/en/application-dev/ui/ui-js-animate-attribute-style.md index 7060d95c005843a954ad0850ac8acf4258743cc3..17e860ab2ee639d02a7e61556715051577f131d3 100644 --- a/en/application-dev/ui/ui-js-animate-attribute-style.md +++ b/en/application-dev/ui/ui-js-animate-attribute-style.md @@ -1,6 +1,7 @@ -# Defining Attribute Style Animations +# Defining Attribute Style Animations -Keyframes is used to scale a component by dynamically setting the width and height of its parent component. Set the **scale** attribute for child components to scale the child and parent components at the same time. Then, set the **opacity** attribute to display or hide the child and parent components. + +Keyframes is used to scale a component by dynamically setting the width and height of its parent component. Set the scale attribute for child components to scale the child and parent components at the same time. Then, set the opacity attribute to display or hide the child and parent components. ``` @@ -78,9 +79,11 @@ text{ } ``` -![](figures/d1.gif) ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->1. The values of **animation** attributes are not sequenced. However, the values of **duration** and **delay** are parsed based on the sequence in which they are displayed. ->2. The **animation-duration** attribute must be set. Otherwise, the duration is 0, which means there is no animation effect. When **animation-fill-mode** is set to **forwards**, the component directly displays the style of the last frame. +![en-us_image_0000001267647889](figures/en-us_image_0000001267647889.gif) + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> 1. The values of animation attributes are not sequenced. However, the values of duration and delay are parsed based on the sequence in which they are displayed. +> +> 2. The animation-duration attribute must be set. Otherwise, the duration is 0, which means there is no animation effect. When animation-fill-mode is set to forwards, the component directly displays the style of the last frame. diff --git a/en/application-dev/ui/ui-js-animate-background-position-style.md b/en/application-dev/ui/ui-js-animate-background-position-style.md index a0be0d599a8020166cd7dc3fc294ad7781e1608f..a92e243b7f9b8d3ec425383a8554fc90e838615a 100644 --- a/en/application-dev/ui/ui-js-animate-background-position-style.md +++ b/en/application-dev/ui/ui-js-animate-background-position-style.md @@ -1,6 +1,7 @@ -# Defining Animations with the background-position Attribute +# Defining Animations with the background-position Attribute -By changing the **background-position** attribute \(where the first value is the position on the x-axis and the second value is the position on the y-axis\), you move a background image. If the background image goes beyond the respective component boundaries, the excess parts will not be displayed. + +By changing the background-position attribute (where the first value is the position on the x-axis and the second value is the position on the y-axis), you move a background image. If the background image goes beyond the respective component boundaries, the excess parts will not be displayed. ``` @@ -74,8 +75,9 @@ By changing the **background-position** attribute \(where the first value is t } ``` -![](figures/q8.gif) ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->The **background-position** attribute can only be used to move background images, but not the background color \(**background-color**\). +![en-us_image_0000001267607873](figures/en-us_image_0000001267607873.gif) + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> The background-position attribute can only be used to move background images, but not the background color (background-color). diff --git a/en/application-dev/ui/ui-js-animate-component.md b/en/application-dev/ui/ui-js-animate-component.md index a81efad3851a78467643141a164977281577df5a..25ce93282ae143540e272f274d938998e9c7c8d6 100644 --- a/en/application-dev/ui/ui-js-animate-component.md +++ b/en/application-dev/ui/ui-js-animate-component.md @@ -1,10 +1,13 @@ -# Component Animation +# Component Animation -Create and run an animation shortcut on the component. For details, see [Universal Methods](../reference/arkui-js/js-components-common-methods.md). -## Obtaining an Animation Object +Create and run an animation shortcut on the component. For details, see [Universal Methods](../reference/arkui-js/js-components-common-methods.md). + + +## Obtaining an Animation Object + +Call the animate method to obtain an animation object, which supports animation attributes, methods, and events. -Call the **animate** method to obtain an **animation** object, which supports animation attributes, methods, and events. ``` @@ -13,6 +16,7 @@ Call the **animate** method to obtain an **animation** object, which support ``` + ``` /* xxx.css */ .container { @@ -29,6 +33,7 @@ Call the **animate** method to obtain an **animation** object, which support } ``` + ``` /* xxx.js */ export default { @@ -57,15 +62,17 @@ export default { } ``` -![](figures/1-14.gif) +![en-us_image_0000001222807812](figures/en-us_image_0000001222807812.gif) + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - When using the animate method, you must pass the keyframes and options parameters. +> - If animate is called multiple times and the replace policy is used, parameters passed to the last call will take effect. ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- When using the **animate** method, you must pass the keyframes and options parameters. ->- If **animate** is called multiple times and the **replace** policy is used, parameters passed to the last call will take effect. -## Setting Animation Parameters +## Setting Animation Parameters + +After obtaining an animation object, you can set its style working on the component by using the keyframes parameter. -After obtaining an **animation** object, you can set its style working on the component by using the keyframes parameter. ``` @@ -74,6 +81,7 @@ After obtaining an **animation** object, you can set its style working on the ``` + ``` /* xxx.css */ .container { @@ -90,6 +98,7 @@ After obtaining an **animation** object, you can set its style working on the } ``` + ``` /* xxx.js */ export default { @@ -134,14 +143,16 @@ export default { } ``` -![](figures/1-15.gif) +![en-us_image_0000001267647897](figures/en-us_image_0000001267647897.gif) ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- The sequence of **translate**, **scale**, and **rotate** affects the animation effect. ->- **transformOrigin** works only for **scale** and **rotate**. +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - The sequence of translate, scale, and rotate affects the animation effect. +> +> - transformOrigin works only for scale and rotate. Set the animation attributes by using the options parameter. + ```
@@ -149,6 +160,7 @@ Set the animation attributes by using the options parameter.
``` + ``` /* xxx.css */ .container { @@ -165,6 +177,7 @@ Set the animation attributes by using the options parameter. } ``` + ``` /* xxx.js */ export default { @@ -174,13 +187,7 @@ export default { onInit() { }, onShow() { - var options = { - duration: 1500, - easing: 'ease-in', - delay: 5, - iterations: 2, - direction: 'normal', - }; + var options = { duration: 1500, easing: 'ease-in', delay: 5, iterations: 2, direction: 'normal', }; var frames = [ { transform: { @@ -201,18 +208,24 @@ export default { } ``` -![](figures/3-16.gif) +![en-us_image_0000001222967796](figures/en-us_image_0000001222967796.gif) ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->**direction**: mode of playing the animation. ->**normal**: plays the animation in forward loop mode. ->**reverse**: plays the animation in reverse loop mode. ->**alternate**: plays the animation in alternating loop mode. When the animation is played for an odd number of times, the playback is in forward direction. When the animation is played for an even number of times, the playback is in reverse direction. ->**alternate-reverse**: plays the animation in reverse alternating loop mode. When the animation is played for an odd number of times, the playback is in reverse direction. When the animation is played for an even number of times, the playback is in forward direction. +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> direction: mode of playing the animation. +> +> normal: plays the animation in forward loop mode. +> +> reverse: plays the animation in reverse loop mode. +> +> alternate: plays the animation in alternating loop mode. When the animation is played for an odd number of times, the playback is in forward direction. When the animation is played for an even number of times, the playback is in reverse direction. +> +> alternate-reverse: plays the animation in reverse alternating loop mode. When the animation is played for an odd number of times, the playback is in reverse direction. When the animation is played for an even number of times, the playback is in forward direction. -## Adding an Event and Calling a Method -Animation objects support animation events and methods. You can achieve the intended animation by adding **start** and **cancel** events and calling the **play**, **pause**, **rewind**, and **stop** methods. +## Adding an Event and Calling a Method + +Animation objects support animation events and methods. You can achieve the intended animation by adding start and cancel events and calling the play, pause, rewind, and stop methods. + ``` @@ -230,6 +243,7 @@ Animation objects support animation events and methods. You can achieve the inte ``` + ``` /* xxx.css */ .container { @@ -262,6 +276,7 @@ button{ } ``` + ``` /* xxx.js */ import prompt from '@system.prompt'; @@ -336,9 +351,10 @@ export default { } ``` -![](figures/111-17.gif) +![en-us_image_0000001223127752](figures/en-us_image_0000001223127752.gif) + +Change the animation status by changing the playStat attribute. -Change the animation status by changing the **playStat** attribute. ``` @@ -354,6 +370,7 @@ Change the animation status by changing the **playStat** attribute. ``` + ``` /* xxx.css */ .container { @@ -386,6 +403,7 @@ button{ } ``` + ``` /* xxx.js */ import prompt from '@system.prompt'; @@ -463,5 +481,4 @@ export default { } ``` -![](figures/1111.gif) - +![en-us_image_0000001267607921](figures/en-us_image_0000001267607921.gif) diff --git a/en/application-dev/ui/ui-js-animate-css.md b/en/application-dev/ui/ui-js-animate-css.md deleted file mode 100644 index c5103fa5fe9b0a6f7535fa815be625dd1b6b0af5..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ui-js-animate-css.md +++ /dev/null @@ -1,9 +0,0 @@ -# CSS Animation - -- **[Defining Attribute Style Animations](ui-js-animate-attribute-style.md)** - -- **[Defining Animations with the transform Attribute](ui-js-animate-transform.md)** - -- **[Defining Animations with the background-position Attribute](ui-js-animate-background-position-style.md)** - - diff --git a/en/application-dev/ui/ui-js-animate-dynamic-effects.md b/en/application-dev/ui/ui-js-animate-dynamic-effects.md index d566b7bee31f6c3a57953b38589861d42e876515..bbd5aae520e9c5e767b132b929f11cb006670f5b 100644 --- a/en/application-dev/ui/ui-js-animate-dynamic-effects.md +++ b/en/application-dev/ui/ui-js-animate-dynamic-effects.md @@ -1,13 +1,17 @@ -# Animation Effect +# Animation Effect -You can set the interpolator to implement the animation effect. For details, see [Animation](../reference/apis/js-apis-basic-features-animator.md). ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->This feature is supported since API version 6. +You can set the interpolator to implement the animation effect. For details, see [Animation](../reference/apis/js-apis-basic-features-animator.md). -## Creating an Animation Object -Use **createAnimator** to create an **animation** object and set the **animation** attributes by using the options parameter. +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> This feature is supported since API version 6. + + +## Creating an Animation Object + +Use createAnimator to create an animation object and set the animation attributes by using the options parameter. + ``` @@ -20,6 +24,7 @@ Use **createAnimator** to create an **animation** object and set the **anim ``` + ``` /* xxx.css */ .container { @@ -40,6 +45,7 @@ button{ } ``` + ``` /* xxx.js */ import animator from '@ohos.animator'; @@ -72,16 +78,20 @@ export default { } ``` -![](figures/22.gif) +![en-us_image_0000001267887885](figures/en-us_image_0000001267887885.gif) ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- When you use **createAnimator** to create an animation object, you must pass the **options** parameter. ->- **begin** indicates the start point of the animation interpolation. If it is not set, the default value **0** is used. ->- **end** indicates the end point of the animation interpolation. If it is not set, the default value **1** is used. +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - When you use createAnimator to create an animation object, you must pass the options parameter. +> +> - begin indicates the start point of the animation interpolation. If it is not set, the default value 0 is used. +> +> - end indicates the end point of the animation interpolation. If it is not set, the default value 1 is used. -## Adding Animation Events and Calling Methods -The **animator** supports events and methods, which you can use to customize the animation effect. Events include **frame**, **cancel**, **repeat**, and **finish**. Methods include **update**, **play**, **pause**, **cancel**, **reverse**, and **finish**. For details about the supported events and methods, see [animator supported events and animator supported APIs](../reference/apis/js-apis-basic-features-animator.md). +## Adding Animation Events and Calling Methods + +The animator supports events and methods, which you can use to customize the animation effect. Events include frame, cancel, repeat, and finish. Methods include update, play, pause, cancel, reverse, and finish. For details about the supported events and methods, see [animator supported events and animator supported APIs](../reference/apis/js-apis-basic-features-animator.md). + ``` @@ -106,6 +116,7 @@ The **animator** supports events and methods, which you can use to customize t ``` + ``` /* xxx.css */ .container { @@ -148,6 +159,7 @@ button{ } ``` + ``` /* xxx.js */ import animator from '@ohos.animator'; @@ -230,8 +242,7 @@ export default { } ``` -![](figures/1-18.gif) - ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->When calling the **update** method, you can use it to update the animation parameters. The input parameters are the same as those of **createAnimator**. +![en-us_image_0000001223287724](figures/en-us_image_0000001223287724.gif) +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> When calling the update method, you can use it to update the animation parameters. The input parameters are the same as those of createAnimator. diff --git a/en/application-dev/ui/ui-js-animate-frame.md b/en/application-dev/ui/ui-js-animate-frame.md index 355cc098f746d1271ab6823578ce30f16a1c9b55..f1cb12abb0f69ce1c76868b4f162621290eeb012 100644 --- a/en/application-dev/ui/ui-js-animate-frame.md +++ b/en/application-dev/ui/ui-js-animate-frame.md @@ -1,11 +1,13 @@ -# Animation Frame +# Animation Frame -## Requesting an Animation Frame -Use the **requestAnimationFrame** method to request frames on a one-by-one basis. This method accepts a callback as an argument. +## Requesting an Animation Frame -When **runframe** calls **requestAnimationFrame**, the **step** callback with the **timestamp** parameter is passed, and this **timestamp** iss assigned to **startTime**. When the difference between the **timestamp** and **startTime** is less than the specified value, **requestAnimationFrame** is called again, and the animation stops. +Use the requestAnimationFrame method to request frames on a one-by-one basis. This method accepts a callback as an argument. +When runframe calls requestAnimationFrame, the step callback with the timestamp parameter is passed, and this timestamp iss assigned to startTime. When the difference between the timestamp and startTime is less than the specified value, requestAnimationFrame is called again, and the animation stops. + + ```
@@ -25,6 +27,7 @@ When **runframe** calls **requestAnimationFrame**, the **step** callback wi
``` + ``` /* xxx.css */ .container { @@ -39,6 +42,7 @@ button{ } ``` + ``` /* xxx.js */ export default { @@ -93,15 +97,17 @@ export default { } ``` -![](figures/3333.gif) +![en-us_image_0000001267767877](figures/en-us_image_0000001267767877.gif) + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> When invoking the callback, the requestAnimationFrame method passes the timestamp as the first parameter, which indicates the time when requestAnimationFrame starts to execute the callback. ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->When invoking the callback, the **requestAnimationFrame** method passes the timestamp as the first parameter, which indicates the time when **requestAnimationFrame** starts to execute the callback. -## Canceling an Animation Frame +## Canceling an Animation Frame -Use the **cancelAnimationFrame** method to cancel frames on a one-by-one basis. When this method is called, the animation frame request sent through **requestAnimationFrame** will be canceled. +Use the cancelAnimationFrame method to cancel frames on a one-by-one basis. When this method is called, the animation frame request sent through requestAnimationFrame will be canceled. + ```
@@ -121,6 +127,7 @@ Use the **cancelAnimationFrame** method to cancel frames on a one-by-one basis
``` + ``` /* xxx.css */ .container { @@ -135,6 +142,7 @@ button{ } ``` + ``` /* xxx.js */ export default { @@ -181,8 +189,7 @@ export default { } ``` -![](figures/4444.gif) - ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->When **cancelAnimationFrame** is called, a parameter that indicates an ID must be passed. +![en-us_image_0000001223127740](figures/en-us_image_0000001223127740.gif) +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> When cancelAnimationFrame is called, a parameter that indicates an ID must be passed. diff --git a/en/application-dev/ui/ui-js-animate-interpolator.md b/en/application-dev/ui/ui-js-animate-interpolator.md deleted file mode 100644 index a3e45d4b072f61ebcdc03ab1a2abe68b043f039b..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ui-js-animate-interpolator.md +++ /dev/null @@ -1,7 +0,0 @@ -# Interpolator Animation - -- **[Animation Effect](ui-js-animate-dynamic-effects.md)** - -- **[Animation Frame](ui-js-animate-frame.md)** - - diff --git a/en/application-dev/ui/ui-js-animate-javascript.md b/en/application-dev/ui/ui-js-animate-javascript.md deleted file mode 100644 index f14e27fb8805e9f56e3e27e677d3f87744e2383f..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ui-js-animate-javascript.md +++ /dev/null @@ -1,7 +0,0 @@ -# JS Animation - -- **[Component Animation](ui-js-animate-component.md)** - -- **[Interpolator Animation](ui-js-animate-interpolator.md)** - - diff --git a/en/application-dev/ui/ui-js-animate-svg.md b/en/application-dev/ui/ui-js-animate-svg.md new file mode 100644 index 0000000000000000000000000000000000000000..7a9cb5ea1147020cec5599008db06d1518eacd4a --- /dev/null +++ b/en/application-dev/ui/ui-js-animate-svg.md @@ -0,0 +1,100 @@ +# Defining Animations for SVG Components + +You can use child components in the <svg> component to animate attributes over time. + +#### Attribute Style Animation + +In the [animate](../reference/arkui-js/js-components-svg-animate.md) child component of the <svg> component, set attributeName to the attribute you want to animate, set from to the animation start value, and set to to the animation end value. + +``` + +
+ + + Hello + + + + + + + + + World + + + + + + + + +
+``` + +![en-us_image_0000001183871404.gif](figures/en-us_image_0000001183871404.gif) + +> ![icon-note.gif](public_sys-resources/icon-note.gif) NOTE: +> When values is also set, the from and to settings do not take effect. + +#### Motion Path Animation + +In the [animateMotion](../reference/arkui-js/js-components-svg-animatemotion.md) child component of the <svg> component, set path to define a shape for the animation. + +``` + +
+ + + + + + + + +
+``` + +![en-us_image_0000001229510983.gif](figures/en-us_image_0000001229510983.gif) + +#### animateTransform Animation + +In the [animateTransform](../reference/arkui-js/js-components-svg-animatetransform.md) child component of the <svg> component, set attributeName to bind the corresponding attribute to the transform attribute, and set type to the animation type, from to the start value, and to to the end value. + +``` + +
+ + + + + + + + + + + + + + + + + + +
+``` + +``` +/* xxx.css */ +.container { + flex-direction: column; + align-items: center; + width: 100%; + height: 100%; + background-color: #F1F3F5; +} +``` + +![en-us_image_0000001182832088.gif](figures/en-us_image_0000001182832088.gif) \ No newline at end of file diff --git a/en/application-dev/ui/ui-js-animate-transform.md b/en/application-dev/ui/ui-js-animate-transform.md index 9ac89180bae2aec0dededa5c0c962fcf0fd8179d..c8d5c6b233b5b263e6614fa836386441486eb870 100644 --- a/en/application-dev/ui/ui-js-animate-transform.md +++ b/en/application-dev/ui/ui-js-animate-transform.md @@ -1,11 +1,14 @@ -# Defining Animations with the transform Attribute +# Defining Animations with the transform Attribute -Set the **transform** attribute for component rotation, scaling, translation, and skewing. -## Designing Static Animation +Set the transform attribute for component rotation, scaling, translation, and skewing. -Create a square and rotate it by 90 degrees to form a rhombus. Cover the lower part of the rhombus with a rectangle to form a roof. Set the **translate** attribute of the rectangle to the coordinate \(150px, -150px\) to form a door, use the **position** attribute to translate the horizontal and vertical axes to the specified coordinates of the parent component \(square\), set the **scale** attribute to scale up the parent and child components together to determine the window size, and use the **skewX** attribute to skew the component and set the coordinate **translate\(200px,-830px\)** to form a chimney. +## Designing Static Animation + +Create a square and rotate it by 90 degrees to form a rhombus. Cover the lower part of the rhombus with a rectangle to form a roof. Set the translate attribute of the rectangle to the coordinate (150px, -150px) to form a door, use the position attribute to translate the horizontal and vertical axes to the specified coordinates of the parent component (square), set the scale attribute to scale up the parent and child components together to determine the window size, and use the skewX attribute to skew the component and set the coordinate translate(200px,-830px) to form a chimney. + + ```
@@ -21,6 +24,7 @@ Create a square and rotate it by 90 degrees to form a rhombus. Cover the lower p
``` + ``` /* xxx.css */ .container { @@ -86,12 +90,14 @@ Create a square and rotate it by 90 degrees to form a rhombus. Cover the lower p } ``` -![](figures/111-13.png) +![en-us_image_0000001267887841](figures/en-us_image_0000001267887841.png) + -## Designing Translation Animation +## Designing Translation Animation Decrease the y-coordinate over a time frame to make the ball bounce back. Gradually decrease the bounce height until it drops to 0. An animation where the ball falls is hereby created. + ```
@@ -100,6 +106,7 @@ Decrease the y-coordinate over a time frame to make the ball bounce back. Gradua
``` + ``` /* xxx.css */ .container { @@ -162,12 +169,14 @@ Decrease the y-coordinate over a time frame to make the ball bounce back. Gradua } ``` -![](figures/q2.gif) +![en-us_image_0000001222967760](figures/en-us_image_0000001222967760.gif) -## Designing Rotation Animation -Set the rotation center around an element in different **transform-origin** positions. Of the **rotate3d** values, the first three values are the rotation vectors of the x-axis, y-axis, and z-axis, respectively; the fourth value is the rotation angle, which can be a negative value to indicate that the rotation is performed counterclockwise. +## Designing Rotation Animation +Set the rotation center around an element in different transform-origin positions. Of the rotate3d values, the first three values are the rotation vectors of the x-axis, y-axis, and z-axis, respectively; the fourth value is the rotation angle, which can be a negative value to indicate that the rotation is performed counterclockwise. + + ```
@@ -187,6 +196,7 @@ Set the rotation center around an element in different **transform-origin** po
``` + ``` /* xxx.css */ .container { @@ -292,17 +302,19 @@ Set the rotation center around an element in different **transform-origin** po } ``` -![](figures/d2.gif) +![en-us_image_0000001222807776](figures/en-us_image_0000001222807776.gif) + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> transform-origin specifies the origin of an element's transformation. If only one value is set, the other value is 50%. If both values are set, the first value indicates the position on the x-axis, and the second value indicates the position on the y-axis. ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->**transform-origin** specifies the origin of an element's transformation. If only one value is set, the other value is **50%**. If both values are set, the first value indicates the position on the x-axis, and the second value indicates the position on the y-axis. -## Designing Scaling Animation +## Designing Scaling Animation -This example implements a ripple animation with the **scale** attribute. Here is the overall procedure: First, use the positioning function to determine the coordinates of the element's position. Then, create multiple components to achieve the overlapping effect. After that, set the **opacity** attribute to hide or display the components. To scale and hide/display a component at the same time, set both the **scale** and **opacity** attributes. Finally, set different animation durations for different components to achieve the diffusion effect. +This example implements a ripple animation with the scale attribute. Here is the overall procedure: First, use the positioning function to determine the coordinates of the element's position. Then, create multiple components to achieve the overlapping effect. After that, set the opacity attribute to hide or display the components. To scale and hide/display a component at the same time, set both the scale and opacity attributes. Finally, set different animation durations for different components to achieve the diffusion effect. -Set the scaling values for the x-axis, y-axis, and z-axis in **scale3d** to implement the animation. +Set the scaling values for the x-axis, y-axis, and z-axis in scale3d to implement the animation. + ```
@@ -318,6 +330,7 @@ Set the scaling values for the x-axis, y-axis, and z-axis in **scale3d** to im
``` + ``` /* xxx.css */ .container { @@ -333,14 +346,12 @@ Set the scaling values for the x-axis, y-axis, and z-axis in **scale3d** to im height: 100px; border-radius: 50px; background:linear-gradient(#dcaec1, #d3a8e3); - z-index: 1; - position: absolute; + z-index: 1; position: absolute; } .ripple{ margin-top: 400px; margin-left: 40%; - position: absolute; - z-index: 0; + position: absolute; z-index: 0; width: 100px; height: 100px; border-radius: 50px; @@ -406,15 +417,17 @@ text{ } ``` -![](figures/d3.gif) +![en-us_image_0000001267887837](figures/en-us_image_0000001267887837.gif) + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> After the transform attributes are set, the child element changes with the parent element. Value changing of other attributes (such as height and width) of the parent element will not affect the child element. ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->After the **transform** attributes are set, the child element changes with the parent element. Value changing of other attributes \(such as **height** and **width**\) of the parent element will not affect the child element. -## Setting matrix +## Setting matrix -The **matrix** attribute defines a transformation matrix with six input parameters: **scaleX**, **skewY**, **skewX**, **scaleY**, **translateX**, and **translateY**. In the following example, **matrix** is set to **matrix\(1,0,0,1,0,200\)** to skew and translate the component. +The matrix attribute defines a transformation matrix with six input parameters: scaleX, skewY, skewX, scaleY, translateX, and translateY. In the following example, matrix is set to matrix(1,0,0,1,0,200) to skew and translate the component. + ```
@@ -422,6 +435,7 @@ The **matrix** attribute defines a transformation matrix with six input parame
``` + ``` /* xxx.css */ .container{ @@ -451,12 +465,14 @@ The **matrix** attribute defines a transformation matrix with six input parame } ``` -![](figures/q3.gif) +![en-us_image_0000001267767853](figures/en-us_image_0000001267767853.gif) -## Integrating transform Attributes -You can set multiple **transform** attributes at the same time to apply different transformations to a component. The following example applies the **scale**, **translate**, and **rotate** attributes simultaneously. +## Integrating transform Attributes +You can set multiple transform attributes at the same time to apply different transformations to a component. The following example applies the scale, translate, and rotate attributes simultaneously. + + ```
@@ -468,6 +484,7 @@ You can set multiple **transform** attributes at the same time to apply differ
``` + ``` /* xxx.css */ .container{ @@ -514,8 +531,7 @@ You can set multiple **transform** attributes at the same time to apply differ /* Use change1 and change2 for comparison. */ @keyframes change1{ 0%{ - transform: translate(0,0); - transform: rotate(0deg) + transform: translate(0,0); transform: rotate(0deg) } 100%{ transform: translate(0,500px); @@ -559,10 +575,11 @@ You can set multiple **transform** attributes at the same time to apply differ } ``` -![](figures/d4.gif) - ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->1. When multiple **transform** attributes are set, the later one overwrites the previous one. To apply multiple transform styles at the same time, use the shorthand notation; that is, write multiple style values in one **transform**, for example, **transform: scale\(1\) rotate\(0\) translate\(0,0\)**. ->2. When using the shorthand notion, note that the animation effect varies according to the sequence of the style values. ->3. The style values in the **transform** attribute used when the animation starts and ends must be in one-to-one mapping. Only the styles that have value mappings are played. +![en-us_image_0000001223127712](figures/en-us_image_0000001223127712.gif) +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> 1. When multiple transform attributes are set, the later one overwrites the previous one. To apply multiple transform styles at the same time, use the shorthand notation; that is, write multiple style values in one transform, for example, transform: scale(1) rotate(0) translate(0,0). +> +> 2. When using the shorthand notion, **NOTE** that the animation effect varies according to the sequence of the style values. +> +> 3. The style values in the transform attribute used when the animation starts and ends must be in one-to-one mapping. Only the styles that have value mappings are played. diff --git a/en/application-dev/ui/ui-js-animate.md b/en/application-dev/ui/ui-js-animate.md deleted file mode 100644 index 0da19180580713ad664d48637de5853d79892002..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ui-js-animate.md +++ /dev/null @@ -1,7 +0,0 @@ -# Animation Development Guidelines - -- **[CSS Animation](ui-js-animate-css.md)** - -- **[JS Animation](ui-js-animate-javascript.md)** - - diff --git a/en/application-dev/ui/ui-js-building-ui-animation.md b/en/application-dev/ui/ui-js-building-ui-animation.md index b9c7f025bfb1d4a75ad1aa04c65cd43fd5abaaf9..c6f7c0cdf8a1903ff8d66a18a0f2ae91e60451b0 100644 --- a/en/application-dev/ui/ui-js-building-ui-animation.md +++ b/en/application-dev/ui/ui-js-building-ui-animation.md @@ -1,16 +1,21 @@ -# Developing Animations +# Developing Animations -Animations are classified into [Static Animation](#section456613911492) and [Continuous Animation](#section17836125204914). -## Static Animation +Animations are classified into [Static Animation](#static-animation) and [Continuous Animation](#continuous-animation). + + +## Static Animation The transform attributes are the core of the static animation. A static animation can transform in the following three ways and only once in each way at a time: -- **translate**: Moves a specified component horizontally or vertically. -- **scale**: Scales a specified component horizontally or vertically to the required scale. -- **rotate**: Rotates a specified component by a specified angle along the horizontal axis, vertical axis, or center point. +- translate: Moves a specified component horizontally or vertically. + +- scale: Scales a specified component horizontally or vertically to the required scale. + +- rotate: Rotates a specified component by a specified angle along the horizontal axis, vertical axis, or center point. + +For more information, see [Component Methods](../reference/arkui-js/js-components-common-methods.md). The following is an example: -For more information, see [Component Methods](../reference/arkui-js/js-components-common-methods.md). The following is an example: ``` @@ -21,6 +26,7 @@ For more information, see [Component Methods](../reference/arkui-js/js-componen ``` + ``` /* xxx.css */ .container { @@ -51,22 +57,30 @@ For more information, see [Component Methods](../reference/arkui-js/js-componen } ``` -**Figure 1** Static animation -![](figures/static-animation.png "static-animation") -## Continuous Animation + figure1 Static animation + + ![en-us_image_0000001223127724](figures/en-us_image_0000001223127724.png) + + +## Continuous Animation The static animation has only the start and end states. To set the transition state and conversion effect, use continuous animations. The core of a continuous animation is animation attributes, which define the start and end states of the animation and the curve of time and speed. Animation attributes can implement the following effects: -- **animation-name**: Background color, opacity, width, height, and transformation type applied to the element after the animation is executed -- **animation-delay** and **animation-duration**: Element delay and duration after the animation is executed -- **animation-timing-function**: Speed curve of an animation, which makes the animation more fluent -- **animation-iteration-count**: Number of animation playback times -- **animation-fill-mode**: Whether to restore the initial state after the animation is executed +- animation-name: Background color, opacity, width, height, and transformation type applied to the element after the animation is executed + +- animation-delay and animation-duration: Element delay and duration after the animation is executed + +- animation-timing-function: Speed curve of an animation, which makes the animation more fluent + +- animation-iteration-count: Number of animation playback times + +- animation-fill-mode: Whether to restore the initial state after the animation is executed + +To use the animation attributes, you need to define a @keyframes rule in the .css file, set the animation transition effect in @keyframes, and invoke the effect through a style class in the .hml file. The following is an example for animation-name: -To use the animation attributes, you need to define a @keyframes rule in the **.css** file, set the animation transition effect in @keyframes, and invoke the effect through a style class in the **.hml** file. The following is an example for **animation-name**: ``` @@ -82,6 +96,7 @@ To use the animation attributes, you need to define a @keyframes rule in the ** ``` + ``` /* xxx.css */ .item-container { @@ -131,6 +146,7 @@ To use the animation attributes, you need to define a @keyframes rule in the ** } ``` + ``` // xxx.js export default { @@ -147,6 +163,6 @@ export default { } ``` -**Figure 2** Continuous animation effect -![](figures/continuous-animation-effect.gif "continuous-animation-effect") - + figure2 Continuous animation effect + + ![en-us_image_0000001223287696](figures/en-us_image_0000001223287696.gif) diff --git a/en/application-dev/ui/ui-js-building-ui-component.md b/en/application-dev/ui/ui-js-building-ui-component.md index bb5970bd4af8f46805433d2af2626efc8d1a5123..50b3fccf7a613a43117c879be4005c98ba822c92 100644 --- a/en/application-dev/ui/ui-js-building-ui-component.md +++ b/en/application-dev/ui/ui-js-building-ui-component.md @@ -1,50 +1,21 @@ -# Component Overview +# Component Overview -Components are the core of a UI page. Each component can provide visible and interactive functional units that are independent from each other. This is achieved by data and method encapsulation. You can use and reuse any component anywhere as needed. For details about how to use the components, see [Components](../reference/arkui-js/js-components-common-attributes.md). -You can also customize a new component through proper combination of components to make the development simple and easy. For details about how to customize components, see [Custom Components](ui-js-custom-components.md). +Components are the core of a UI page. Each component can provide visible and interactive functional units that are independent from each other. This is achieved by data and method encapsulation. You can use and reuse any component anywhere as needed. For details about how to use the components, see [Universal Attributes](../reference/arkui-js/js-components-common-attributes.md). -## Classification -Components can be classified into the following types based on their functions. +You can also customize a new component through proper combination of components to make the development simple and easy. For details about how to customize components, see [Custom Components](ui-js-custom-components.md). + - - - - - - - - - - - - - - - - - - - - - - - - -

Type

-

Components

-

Container

-

badge, dialog, div, form, list, list-item, list-item-group, panel, popup, refresh, stack, stepper, stepper-item, swiper, tabs, tab-bar, tab-content

-

Basic

-

button, chart, divider, image, image-animator, input, label, marquee, menu, option, picker, picker-view, piece, progress, qrcode, rating, richtext, search, select, slider, span, switch, text, textarea, toolbar, toolbar-item, toggle

-

Media

-

video

-

Canvas

-

canvas

-

Grid

-

grid-container, grid-row, grid-col

-

SVG

-

svg, rect, circle, ellipse, path, line, polyline, polygon, text, tspan, textPath, animate, animateMotion, animateTransform

-
+## Classification + +Components can be classified into the following types based on their functions. + | Type | Components | +| -------- | -------- | +| Container | badge, dialog, div, form, list, list-item, list-item-group, panel, popup, refresh, stack, stepper, stepper-item, swiper, tabs, tab-bar, tab-content | +| Basic | button, chart, divider, image, image-animator, input, label, marquee, menu, option, picker, picker-view, piece, progress, qrcode, rating, richtext, search, select, slider, span, switch, text, textarea, toolbar, toolbar-item, toggle | +| Media | video | +| Canvas | canvas | +| Grid | grid-container, grid-row, grid-col | +| SVG | svg, rect, circle, ellipse, path, line, polyline, polygon, text, tspan, textPath, animate, animateMotion, animateTransform | diff --git a/en/application-dev/ui/ui-js-building-ui-event.md b/en/application-dev/ui/ui-js-building-ui-event.md index e5d66d95647911209d229a3811cdc249c7ddeea7..02b1d1a13b6358ce5cef34373bdbe971b345a3fb 100644 --- a/en/application-dev/ui/ui-js-building-ui-event.md +++ b/en/application-dev/ui/ui-js-building-ui-event.md @@ -1,28 +1,33 @@ -# Defining Events +# Defining Events + Events mainly include gesture events for touchscreen devices. -## Gesture Events -A gesture represents a semantic action \(for example, tap, drag, or longpress\) that can trigger one or more events. A gesture lifecycle may consist of multiple events from the start to the end of the gesture. Supported events: +## Gesture Events + +A gesture represents a semantic action (for example, tap, drag, or longpress) that can trigger one or more events. A gesture lifecycle may consist of multiple events from the start to the end of the gesture. Supported events: + + Touch +- touchstart: Triggered when the touch starts + +- touchmove: Triggered when the touch moves -**Touch** +- touchcancel: Triggered when the touch is interrupted, for example, by an incoming call notification or pop-up message -- **touchstart**: Triggered when the touch starts -- **touchmove**: Triggered when the touch moves -- **touchcancel**: Triggered when the touch is interrupted, for example, by an incoming call notification or pop-up message -- **touchend**: Triggered when the touch ends +- touchend: Triggered when the touch ends -**Click** +Click -**click**: Triggered when a user taps the screen quickly. +click: Triggered when a user taps the screen quickly. -**Longpress** +Longpress -**longpress**: Triggered when a user keeps tapping the screen at the same position for a while. +longpress: Triggered when a user keeps tapping the screen at the same position for a while. The following is an example: + ```
@@ -47,6 +52,7 @@ The following is an example:
``` + ``` /* xxx.css */ .container { @@ -70,6 +76,7 @@ The following is an example: } ``` + ``` // xxx.js export default { @@ -101,4 +108,3 @@ export default { }, } ``` - diff --git a/en/application-dev/ui/ui-js-building-ui-interactions.md b/en/application-dev/ui/ui-js-building-ui-interactions.md index 87cd80eb5a7fbba63ddf2675bbcf4b99f6ce11e4..564e4ca6ab305962d19967d28a0ef9725e7e6dca 100644 --- a/en/application-dev/ui/ui-js-building-ui-interactions.md +++ b/en/application-dev/ui/ui-js-building-ui-interactions.md @@ -1,18 +1,20 @@ -# Adding Interactions +# Adding Interactions -You can make the UI interactive by binding events to components. This section describes how to bind ****, ****, and **** components to click events to build a thumb up button, as shown in the following figure. + You can make the UI interactive by binding events to components. This section describes how to bind <div>, <text>, and <image> components to click events to build a thumb up button, as shown in the following figure. + figure1 Thumb up button effect -**Figure 1** Thumb up button effect +![en-us_image_0000001267647901](figures/en-us_image_0000001267647901.gif) -![](figures/zan.gif) +The thumb up button is implemented by binding a click event to a <div> component. The <div> component contains an <image> component and a <text> component. -The thumb up button is implemented by binding a click event to a **** component. The **** component contains an **** component and a **** component. -- The **** component is used to display unselected and selected \(highlighted\) thumbs up images. The click event function alternately updates the paths of the images that are liked and not liked. -- The **** component is used to display the number of thumbs up. The number is updated in the function of the click event. +- The <image> component is used to display unselected and selected (highlighted) thumbs up images. The click event function alternately updates the paths of the images that are liked and not liked. -The click event calls the **likeClick\(\)** function defined in the **.js** file. You can change the value of **isPressed** to update the image component. If the value of **isPressed** is **true**, the number of thumbs up is incremented by 1. The **likeClick\(\)** function takes effect on the **** component in the **.hml** file. The style of each child component for the thumbs up button is set in the **.css** file. The following is an example: +- The <text> component is used to display the number of thumbs up. The number is updated in the function of the click event. + + +The click event calls the likeClick() function defined in the .js file. You can change the value of isPressed to update the image component. If the value of isPressed is true, the number of thumbs up is incremented by 1. The likeClick() function takes effect on the <div> component in the .hml file. The style of each child component for the thumbs up button is set in the .css file. The following is an example: ``` @@ -71,5 +73,5 @@ export default { } ``` - ArkUI also provides many form components, such as switches, tags, and pickers, for you to flexibly lay out pages and improve their interactions with users. For details, see [Container Components](../reference/arkui-js/js-components-container.md). +ArkUI also provides many form components, such as switches, tags, and pickers, for you to flexibly lay out pages and improve their interactions with users. For details, see Container Components. diff --git a/en/application-dev/ui/ui-js-building-ui-layout-comment.md b/en/application-dev/ui/ui-js-building-ui-layout-comment.md index e11cabf09e0a19428dfba30e8d196aed318537df..f23830faca115ffaaae5e9d60520c7d0d435e19d 100755 --- a/en/application-dev/ui/ui-js-building-ui-layout-comment.md +++ b/en/application-dev/ui/ui-js-building-ui-layout-comment.md @@ -1,8 +1,10 @@ -# Adding a Comment +# Adding a Comment + After a user enters a comment and clicks the submit button, the content is displayed in the comment area. The user can click the delete button to delete the current comment and enter another comment again. -To set such a comment area on a page, you need to associate a click event with ****, ****, and ****. You can use the **** component to obtain the comment entered by a user, use the **** component to display the comment, and use **commentText** to mark the **** component \(controlled by the **if** attribute\). Associate the click event with the **** component that contains **Done** and **Delete** to update the **commentText** and **inputValue**. The following is an example: + +To set such a comment area on a page, you need to associate a click event with <div>, <text>, and <input>. You can use the <input> component to obtain the comment entered by a user, use the <text> component to display the comment, and use commentText to mark the <text> component (controlled by the if attribute). Associate the click event with the <text> component that contains Done and Delete to update the commentText and inputValue. The following is an example: ``` @@ -19,6 +21,8 @@ To set such a comment area on a page, you need to associate a click event with ``` + + ``` /* xxx.css */ .container { @@ -60,6 +64,8 @@ To set such a comment area on a page, you need to associate a click event with } ``` + + ``` // xxx.js export default { @@ -75,4 +81,3 @@ export default { }, } ``` - diff --git a/en/application-dev/ui/ui-js-building-ui-layout-external-container.md b/en/application-dev/ui/ui-js-building-ui-layout-external-container.md index 2c6b781adbe2d144c5bfb576575cefa1927dafc9..4bd2fd37d55bd30e68aab90acc68b0d82756a403 100644 --- a/en/application-dev/ui/ui-js-building-ui-layout-external-container.md +++ b/en/application-dev/ui/ui-js-building-ui-layout-external-container.md @@ -1,10 +1,13 @@ -# Adding a Container +# Adding a Container -To assemble the basic elements of a page, you need a container component. The ****, ****, and **** components are commonly used for laying out page elements. You can use **** as the container in a page with simple layout. **** supports a variety of child components required to build the page. -## +To assemble the basic elements of a page, you need a container component. The <div>, <list>, and <tabs> components are commonly used for laying out page elements. You can use <div> as the container in a page with simple layout. <div> supports a variety of child components required to build the page. + + +## <List> + +If you use <div> repeatedly to render a complex page, frame freezing may occur. In this case, use the <list> component instead of <div> to lay out list items, which provides a smooth list scrolling. **NOTE** that <list> supports only <list-item> as it child components. The following is an example: -If you use **** repeatedly to render a complex page, frame freezing may occur. In this case, use the **** component instead of **** to lay out list items, which provides a smooth list scrolling. Note that **** supports only **** as it child components. The following is an example: ``` @@ -15,6 +18,7 @@ If you use **** repeatedly to render a complex page, frame freezing may ``` + ``` /* xxx.css */ .desc-text { @@ -23,6 +27,7 @@ If you use **** repeatedly to render a complex page, frame freezing may } ``` + ``` // xxx.js export default { @@ -32,11 +37,13 @@ export default { } ``` -To shorten the sample code, the list contains only one **** component that holds only one **** component. In practice, a **** has multiple **** components, and a **** has multiple child components. +To shorten the sample code, the list contains only one <list-item> component that holds only one <text> component. In practice, a <list> has multiple <list-item> components, and a <list-item> has multiple child components. -## -If your page needs to be dynamically loaded, use the **** component. This component supports the change event, which is triggered after tab switching. A **** component can hold only one **** and one ****. The following is an example: +## <Tabs> + +If your page needs to be dynamically loaded, use the <tabs> component. This component supports the change event, which is triggered after tab switching. A <tabs> component can hold only one <tab-bar> and one <tab-content>. The following is an example: + ``` @@ -54,6 +61,7 @@ If your page needs to be dynamically loaded, use the **** component. Th ``` + ``` // xxx.js export default { @@ -65,5 +73,4 @@ export default { } ``` -The **** component is used to display the tab content, which vertically fills the remaining space of the **** component by default. - +The <tab-content> component is used to display the tab content, which vertically fills the remaining space of the <tabs> component by default. diff --git a/en/application-dev/ui/ui-js-building-ui-layout-image.md b/en/application-dev/ui/ui-js-building-ui-layout-image.md index 8c9026d467b0dc746ff6fd51c7b62cf5a0caccee..63e8f07dff27f8f33106c0db6c817d7e38276c3f 100644 --- a/en/application-dev/ui/ui-js-building-ui-layout-image.md +++ b/en/application-dev/ui/ui-js-building-ui-layout-image.md @@ -1,8 +1,10 @@ -# Adding an Image +# Adding an Image -Generally, the [****](../reference/arkui-js/js-components-basic-image.md) component is used to add images on a page. The method of using this component is similar to that of using the **** component. -To reference images via the **** component, you must create the **common** directory under **js** \> **default**, and then store the image files in the **common** directory. For details about the directory structure, see [Directory Structure](js-framework-file.md). The following sample code shows you how to add an image and set its style. +Generally, the [<image>](../reference/arkui-js/js-components-basic-image.md)component is used to add images on a page. The method of using this component is similar to that of using the <text> component. + + +To reference images via the <image> component, you must create the common directory under jsdefault, and then store the image files in the common directory. For details about the directory structure, see [Directory Structure](js-framework-file.md). The following sample code shows you how to add an image and set its style. ``` @@ -26,4 +28,3 @@ export default { }, } ``` - diff --git a/en/application-dev/ui/ui-js-building-ui-layout-intro.md b/en/application-dev/ui/ui-js-building-ui-layout-intro.md index 7ee7f04d95087af0266e0d896ed0c2e9698b0c30..14c6e5f3a16ba09a07c5948c717d8c89828b97f2 100644 --- a/en/application-dev/ui/ui-js-building-ui-layout-intro.md +++ b/en/application-dev/ui/ui-js-building-ui-layout-intro.md @@ -1,26 +1,32 @@ -# Layout Description +# Layout Description + The baseline width for page design is 720 logical pixels. The display width of a page element depends on the ratio of the screen width to the baseline width. + For example, when the width of a component is 100 px, its display width is converted as follows: + On a screen with the width of 720 physical pixels, the display width is 100 physical pixels. On a screen with the width of 1440 physical pixels, the display width is 200 physical pixels. Basic page elements include title, text, and image areas. Each basic element may contain multiple sub-elements. You can add components, such as buttons, switches, and progress bars, to these elements and sub-elements as required. When setting the layout, you need to consider the following for each basic element: -- Size and arrangement -- Overlapping with other elements -- Alignment, padding, and margin -- Sub-elements and their positions -- Container components and their types -You can disassemble elements on the page first and then implement them in sequence. This reduces visual confusion and logical conflicts caused by element nesting and improves code readability for easier modification. For example, as shown below, you disassemble the page elements and elements in the comment area. +- Size and arrangement + +- Overlapping with other elements + +- Alignment, padding, and margin + +- Sub-elements and their positions -**Figure 1** Page layout -![](figures/page-layout.png "page-layout") +- Container components and their types -**Figure 2** Layout of the comment area + You can disassemble elements on the page first and then implement them in sequence. This reduces visual confusion and logical conflicts caused by element nesting and improves code readability for easier modification. For example, as shown below, you disassemble the page elements and elements in the comment area. + figure1 Page layout + ![en-us_image_0000001222967792](figures/en-us_image_0000001222967792.png) -![](figures/figures3.png) + figure2 Layout of the comment area +![en-us_image_0000001267767889](figures/en-us_image_0000001267767889.png) diff --git a/en/application-dev/ui/ui-js-building-ui-layout-text.md b/en/application-dev/ui/ui-js-building-ui-layout-text.md index 141eb9f25b8a6c65c83c0fd288099d1bd4f0b3cb..f01820f6f73fc45cc660813f108aa352209d0bdb 100644 --- a/en/application-dev/ui/ui-js-building-ui-layout-text.md +++ b/en/application-dev/ui/ui-js-building-ui-layout-text.md @@ -1,6 +1,9 @@ -# Adding Title and Paragraph Text +# Adding Title and Paragraph Text + + +The <text> component is most commonly used to display text in title and paragraph areas. You can set attributes and styles for a <text> component and add the text to be displayed between the <text> and </text> tags. For details about the attributes and styles, see [text](../reference/arkui-js/js-components-basic-text.md). The following is an example of adding title and paragraph text on a page: + -The **** component is most commonly used to display text in title and paragraph areas. You can set attributes and styles for a **** component and add the text to be displayed between the **** and **** tags. For details about the attributes and styles, see [text](../reference/arkui-js/js-components-basic-text.md). The following is an example of adding title and paragraph text on a page: ``` @@ -11,6 +14,8 @@ The **** component is most commonly used to display text in title and p ``` + + ``` /* xxx.css */ .container { @@ -31,6 +36,8 @@ The **** component is most commonly used to display text in title and p } ``` + + ``` // xxx.js export default { @@ -41,4 +48,3 @@ export default { }, } ``` - diff --git a/en/application-dev/ui/ui-js-building-ui-layout.md b/en/application-dev/ui/ui-js-building-ui-layout.md deleted file mode 100644 index 154a22bb6af4f3b7060f169d46b11135a54fbb88..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ui-js-building-ui-layout.md +++ /dev/null @@ -1,13 +0,0 @@ -# Building the Layout - -- **[Layout Description](ui-js-building-ui-layout-intro.md)** - -- **[Adding Title and Paragraph Text](ui-js-building-ui-layout-text.md)** - -- **[Adding an Image](ui-js-building-ui-layout-image.md)** - -- **[Adding a Comment](ui-js-building-ui-layout-comment.md)** - -- **[Adding a Container](ui-js-building-ui-layout-external-container.md)** - - diff --git a/en/application-dev/ui/ui-js-building-ui-routes.md b/en/application-dev/ui/ui-js-building-ui-routes.md index e5eaa8dfb6679f50140551eb1437c1bc9df84261..4fcdb531fd87488f639df54d3d8aef5a016d799c 100644 --- a/en/application-dev/ui/ui-js-building-ui-routes.md +++ b/en/application-dev/ui/ui-js-building-ui-routes.md @@ -1,16 +1,23 @@ -# Defining Page Routes +# Defining Page Routes -Many applications consist of more than one page. For example, in a music application, a user taps a song on a music list page, and then needs to jump to the playback page of the song. You need to link these pages through page routing to implement redirection as required. -The page router finds the target page based on the page URI. The following describes how to switch between two pages: +An application generally consist of more than one page. For example, in a music application, a user taps a song on a music list page to jump to the playback page of the song. You need to link these pages through the page router to implement redirection as required. -1. In the **Project** window of DevEco Studio, choose **entry \> src \> main** \> **js** \> **default**. Right-click the **pages** folder and choose **New****JS Page** from the shortcut menu to create the **detail** page. -2. Call **router.push\(\)** to navigate users to the **detail** page. -3. Call **router.back\(\)** to navigate users to the **index** page. -## Building the Page Layout +The page router finds the target page based on the page URI. The following describes how to implement redirection between two pages: + + +1. In the “Project“ window of DevEco Studio, choose entry > src > mainjsdefault. Right-click the pages folder and choose NewJS Page from the shortcut menu to create the detail page. + +2. Call router.push() to navigate users to the detail page. + +3. Call router.back() to navigate users to the index page. + + +## Building the Page Layout + +The index and detail pages each contains a <text> component that specifies the current page, and a <button> component that implements the switching between two pages. Example code in .hml files is as follows: -The **index** and **detail** pages each contains a **** component that specifies the current page, and a **** component that implements the switching between two pages. Example code in **.hml** files is as follows: ``` @@ -20,6 +27,7 @@ The **index** and **detail** pages each contains a **** component t ``` + ```
@@ -28,9 +36,11 @@ The **index** and **detail** pages each contains a **** component t
``` -## Setting Page Styles -Set styles for the **index** and **detail** pages. Centers the **** and **** components and spaces the two components with 50 pixels. The CSS code for the two pages is as follows: +## Setting Page Styles + +Set styles for the index and detail pages. Center the <text> and <button> components and space the two components with 50 pixels. The CSS code for the two pages is as follows: + ``` /* index.css */ @@ -47,9 +57,11 @@ Set styles for the **index** and **detail** pages. Centers the **** } ``` -## Setting the Switch -To make the **launch** method of the **** component take effect, the redirection logic needs to be implemented in the **.js** file of the page. Call **router.push\(\)** to add the page URI to the route stack, that is, to jump to the page specified by the URI. You need to import the router module before calling the router method. The sample code is as follows: +## Implementing Redirection + +To make the launch method of the <button> component take effect, the redirection logic needs to be implemented in the .js file of the page. Call router.push() to add the page URI to the route stack, that is, to jump to the page specified by the URI. You need to import the router module before calling the router method. The sample code is as follows: + ``` // index.js @@ -63,6 +75,7 @@ export default { } ``` + ``` // detail.js import router from '@system.router'; @@ -73,8 +86,8 @@ export default { } ``` -The following figure shows the effect. +The figure below shows the effect. -**Figure 1** Page routing -![](figures/page-routing.png "page-routing") + figure1 Page routing + ![en-us_image_0000001222967784](figures/en-us_image_0000001222967784.png) diff --git a/en/application-dev/ui/ui-js-building-ui.md b/en/application-dev/ui/ui-js-building-ui.md deleted file mode 100644 index e689826b459549da5facd7ac28402c502d0479ee..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ui-js-building-ui.md +++ /dev/null @@ -1,15 +0,0 @@ -# Building the UI - -- **[Component Overview](ui-js-building-ui-component.md)** - -- **[Building the Layout](ui-js-building-ui-layout.md)** - -- **[Adding Interactions](ui-js-building-ui-interactions.md)** - -- **[Developing Animations](ui-js-building-ui-animation.md)** - -- **[Defining Events](ui-js-building-ui-event.md)** - -- **[Defining Page Routes](ui-js-building-ui-routes.md)** - - diff --git a/en/application-dev/ui/ui-js-common-components.md b/en/application-dev/ui/ui-js-common-components.md deleted file mode 100644 index 14a90b7ded028c890c3e3ec9ca359898e75667a5..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ui-js-common-components.md +++ /dev/null @@ -1,26 +0,0 @@ -# Common Component Development Guidelines - ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->The sample code provided in this document is applicable to the 720 px screen width on the phones. - -- **[Text](ui-js-components-text.md)** - -- **[Input](ui-js-components-input.md)** - -- **[Button](ui-js-components-button.md)** - -- **[List](ui-js-components-list.md)** - -- **[Picker](ui-js-components-picker.md)** - -- **[Dialog](ui-js-components-dialog.md)** - -- **[Form](ui-js-components-form.md)** - -- **[Stepper](ui-js-components-stepper.md)** - -- **[Tabs](ui-js-component-tabs.md)** - -- **[Image](ui-js-components-images.md)** - - diff --git a/en/application-dev/ui/ui-js-component-tabs.md b/en/application-dev/ui/ui-js-component-tabs.md index d29186ddca5ea240ad27dd237e0cc7c605324894..0e20aaea35129a98b219d5eaac252dfda7e420d4 100644 --- a/en/application-dev/ui/ui-js-component-tabs.md +++ b/en/application-dev/ui/ui-js-component-tabs.md @@ -1,16 +1,19 @@ -# Tabs +# <tabs> Development -The **** component is a common UI component for navigation. It allows quick access to different functions of an app. For details, see [tabs](../reference/arkui-js/js-components-container-tabs.md). -## Creating Tabs +The <tabs> component is a common UI component for navigation. It allows quick access to different functions of an app. For details, see [tabs](../reference/arkui-js/js-components-container-tabs.md). + + +## Creating Tabs + +Create a <tabs> component in the .hml file under pages/index. -Create a **** component in the **.hml** file under **pages/index**. ```
- + item1 item2 @@ -26,6 +29,7 @@ Create a **** component in the **.hml** file under **pages/index**.
``` + ``` /* xxx.css */ .container { @@ -42,11 +46,13 @@ Create a **** component in the **.hml** file under **pages/index**. } ``` -![](figures/3-9.gif) +![en-us_image_0000001223287676](figures/en-us_image_0000001223287676.gif) + -## Setting the Tabs Orientation +## Setting the Tabs Orientation + +By default, the active tab of a <tabs> component is the one with the specified index. To show the <tabs> vertically, set the vertical attribute to true. -By default, the active tab of a **** component is the one with the specified **index**. To show the **** vertically, set the **vertical** attribute to **true**. ``` @@ -68,9 +74,10 @@ By default, the active tab of a **** component is the one with the spec ``` -![](figures/29.gif) +![en-us_image_0000001222967756](figures/en-us_image_0000001222967756.gif) + +Set the mode attribute to enable the child components of the to be evenly distributed. Set the scrollable attribute to disable scrolling of the . -Set the **mode** attribute to enable the child components of the **** to be evenly distributed. Set the **scrollable** attribute to disable scrolling of the ****. ``` @@ -92,11 +99,12 @@ Set the **mode** attribute to enable the child components of the ** ``` -![](figures/30.gif) +![en-us_image_0000001267647857](figures/en-us_image_0000001267647857.gif) + -## Setting the Style +## Setting the Style -Set the background color, border, and tab-content layout of the **** component. + Set the background color, border, and tab-content layout of the <tabs> component. ``` @@ -118,17 +126,18 @@ Set the background color, border, and tab-content layout of the **** co ``` + ``` /* xxx.css */ .container { flex-direction: column; justify-content: flex-start; align-items: center; - background-color:#F1F3F5; + background-color:#F1F3F5; } .tabs{ margin-top: 20px; - border: 1px solid #2262ef; + border: 1px solid #2262ef; width: 99%; padding: 10px; } @@ -141,16 +150,17 @@ Set the background color, border, and tab-content layout of the **** co margin-top: 10px; height: 300px; color: blue; - justify-content: center; - align-items: center; + justify-content: center; align-items: center; } ``` -![](figures/31.gif) +![en-us_image_0000001267767857](figures/en-us_image_0000001267767857.gif) + + +## Displaying the Tab Index -## Displaying the Tab Index +Add the change event for the <tabs> component to display the index of the current tab after tab switching. -Add the **change** event for the **** component to display the index of the current tab after tab switching. ``` @@ -172,6 +182,7 @@ Add the **change** event for the **** component to display the index ``` + ``` /* index.js */ import prompt from '@system.prompt'; @@ -184,17 +195,19 @@ export default { } ``` -![](figures/32.gif) +![en-us_image_0000001222807772](figures/en-us_image_0000001222807772.gif) + ->![](../public_sys-resources/icon-note.gif) **NOTE:** -> ->- A **** can wrap at most one [****](../reference/arkui-js/js-components-container-tab-bar.md) and at most one [****](../reference/arkui-js/js-components-container-tab-content.md). +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - A <tabs> can wrap at most one [](../reference/arkui-js/js-components-container-tab-bar.md) and at most one [](../reference/arkui-js/js-components-container-tab-content.md). -## Example Scenario + +## Example Scenario In this example, you can switch between tabs and the active tab has the title text in red with an underline below. -Use the ****, ****, and **** components to implement tab switching. Then define the arrays and attributes. Add the **change** event to change the attribute values in the arrays so that the active tab has a different font color and an underline. +Use the <tabs>, , and components to implement tab switching. Then define the arrays and attributes. Add the change event to change the attribute values in the arrays so that the active tab has a different font color and an underline. + ``` @@ -224,10 +237,11 @@ Use the ****, ****, and **** components to im ``` + ``` /* xxx.css */ .container{ - background-color:#F1F3F5; +background-color:#F1F3F5; } .tab_bar { width: 100%; @@ -256,6 +270,7 @@ Use the ****, ****, and **** components to im } ``` + ``` /* index.js */ import prompt from '@system.prompt'; @@ -299,5 +314,4 @@ export default { } ``` -![](figures/33.gif) - +![en-us_image_0000001267607885](figures/en-us_image_0000001267607885.gif) diff --git a/en/application-dev/ui/ui-js-components-button.md b/en/application-dev/ui/ui-js-components-button.md index 7910632641df5d614ea8409a818507b72ece5eca..1507ce9c9843bb535efbb8cbd8ebafde66bd93e5 100644 --- a/en/application-dev/ui/ui-js-components-button.md +++ b/en/application-dev/ui/ui-js-components-button.md @@ -1,10 +1,13 @@ -# Button +# <button> Development -The **** component can be used to set a capsule, circle, text, arc, or download button. For details, see [button](../reference/arkui-js/js-components-basic-button.md). -## Creating a Component +The<button>component can be used to set a capsule, circle, text, arc, or download button. For details, see [button](../reference/arkui-js/js-components-basic-button.md). + + +## Creating a <button> Component + +Create a <button> component in the .hml file under pages/index. -Create a **** component in the **.hml** file under **pages/index**. ``` @@ -13,6 +16,7 @@ Create a **** component in the **.hml** file under **pages/index** ``` + ``` /* xxx.css */ .container { @@ -23,11 +27,12 @@ Create a **** component in the **.hml** file under **pages/index** } ``` -![](figures/3-2.png) +![en-us_image_0000001267887821](figures/en-us_image_0000001267887821.png) -## Setting the Button Type -Set the **type** attribute of the **** component to **button**, **date**, or any of the supported values. +## Setting the Button Type + +Set the type attribute of the <input> component to button, date, or any of the supported values. ``` @@ -61,15 +66,21 @@ Set the **type** attribute of the **** component to **button**, ** } ``` -![](figures/05-3.png) ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- For capsule buttons, border-related styles are not supported. ->- For circle buttons, text-related styles are not supported. ->- For text buttons, the text size is adaptive, and **radius**, **width**, and **height** cannot be set. The **background-color** style is not supported when the background is completely transparent. ->- If the icon used by the **** component is from the cloud, you must declare the **ohos.permission.INTERNET** permission in the **config.json** file under the **resources** folder. +![en-us_image_0000001222967744](figures/en-us_image_0000001222967744.png) + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - For capsule buttons, border-related styles are not supported. +> +> - For circle buttons, text-related styles are not supported. +> +> - For text buttons, the text size is adaptive, and radius, width, and height cannot be set. The background-color style is not supported when the background is completely transparent. +> +> - If the icon used by the<button>component is from the cloud, you must declare the ohos.permission.INTERNET permission in the config.json file under the resources folder. -Sample code for declaring the **ohos.permission.INTERNET** permission in the **config.json** file under the **resources** folder: + +Sample code for declaring the ohos.permission.INTERNET permission in the config.json file under the resources folder: ``` @@ -80,9 +91,11 @@ Sample code for declaring the **ohos.permission.INTERNET** permission in the } ``` -## Showing the Download Progress -Add the **progress** method to the **** component to display the download progress in real time. +## Showing the Download Progress + +Add the progress method to the<button>component to display the download progress in real time. + ``` @@ -91,6 +104,7 @@ Add the **progress** method to the **** component to display the do ``` + ``` /* xxx.css */ .container { @@ -106,6 +120,7 @@ Add the **progress** method to the **** component to display the do } ``` + ``` // xxx.js import prompt from '@system.prompt'; @@ -136,7 +151,7 @@ export default { clearInterval(this.intervalId); this.intervalId = null; }, - setProgress(e) { + setProgress(e) { if(this.isPaused){ prompt.showToast({ message: "Download started" @@ -154,13 +169,14 @@ export default { } ``` -![](figures/34.gif) +![en-us_image_0000001223287652](figures/en-us_image_0000001223287652.gif) ->![](../public_sys-resources/icon-note.gif) **NOTE:** +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: > ->- The **setProgress** method supports only buttons of the download type. +> The setProgress method supports only buttons of the download type. + -## Example Scenario +## Example Scenario Switch between the button types for different types of text. @@ -262,5 +278,5 @@ export default { } ``` -![](figures/21.gif) +![en-us_image_0000001222967740](figures/en-us_image_0000001222967740.gif) diff --git a/en/application-dev/ui/ui-js-components-dialog.md b/en/application-dev/ui/ui-js-components-dialog.md index eecd6e02fa0141e82aedbee04009a15181aae0d8..0c5c1303dbaa51e7c2d3987788cded4d51be8906 100644 --- a/en/application-dev/ui/ui-js-components-dialog.md +++ b/en/application-dev/ui/ui-js-components-dialog.md @@ -1,16 +1,17 @@ -# Dialog +# <dialog> Development -The **** component is custom pop-up container for showing critical information or calling for an action. For details, see [dialog](../reference/arkui-js/js-components-container-dialog.md). -## Creating a Component +The <dialog> component is custom pop-up container for showing critical information or calling for an action. For details, see [dialog](../reference/arkui-js/js-components-container-dialog.md). -Create a **** component in the **.hml** file under **pages/index** and add **** components to trigger the ****. The **** component supports only the **width**, **height**, **margin**, **margin-\[left|top|right|bottom\]**, and **margin-\[start|end\]** styles. + +## Creating a <dialog> Component + + Create a <dialog> component in the .hml file under pages/index and add <button> components to trigger the <dialog>. The <dialog> component supports only the width, height, margin, margin-[left|top|right|bottom], and margin-[start|end] styles. ```
- -
+
this is a dialog
@@ -18,6 +19,7 @@ Create a **** component in the **.hml** file under **pages/index**
``` + ``` /* xxx.css */ .doc-page { @@ -49,6 +51,7 @@ button{ } ``` + ``` /* xxx.js */ export default { @@ -59,11 +62,12 @@ export default { } ``` -![](figures/5-5.gif) +![en-us_image_0000001267767893](figures/en-us_image_0000001267767893.gif) -## Setting Dialog Box Response -Add a **cancel** event that is triggered when a user touches a non-dialog area to cancel the pop-up dialog box. Add the **show** and **close** methods to display and close the dialog box, respectively. +## Setting Dialog Box Response + +Add a cancel event that is triggered when a user touches a non-dialog area to cancel the pop-up dialog box. Add the show and close methods to display and close the dialog box, respectively. ``` @@ -125,16 +129,22 @@ export default { } ``` -![](figures/38.gif) ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- This component supports only one child component. ->- Attributes and styles of a **** component cannot be dynamically updated. ->- The **** component does not support the **focusable** and **click-effect** attributes. +![en-us_image_0000001223287720](figures/en-us_image_0000001223287720.gif) + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - This component supports only one child component. +> +> - Attributes and styles of a <dialog> component cannot be dynamically updated. +> +> - The <dialog> component does not support the focusable and click-effect attributes. + + +## Example Scenario -## Example Scenario -Use the **** component to implement a schedule. When the dialog box is open, use the [****](../reference/arkui-js/js-components-basic-textarea.md) component to add an event and touch the OK button to obtain the current time and save the input text. The events in the calendar are displayed in a list. +Use the <dialog> component to implement a schedule. When the dialog box is open, use the [<textarea>](../reference/arkui-js/js-components-basic-textarea.md) component to add an event and touch the OK button to obtain the current time and save the input text. The events in the calendar are displayed in a list. ``` @@ -292,5 +302,5 @@ export default { } ``` -![](figures/6.gif) +![en-us_image_0000001223127756](figures/en-us_image_0000001223127756.gif) diff --git a/en/application-dev/ui/ui-js-components-form.md b/en/application-dev/ui/ui-js-components-form.md index 19c05e7189c0c438173966e138b541694da3fff3..734d3dc510a597d08c5dda4d31e8c6d2b18436be 100644 --- a/en/application-dev/ui/ui-js-components-form.md +++ b/en/application-dev/ui/ui-js-components-form.md @@ -1,23 +1,26 @@ -# Form +# <form> Development -The **** component allows the content in [****](../reference/arkui-js/js-components-basic-input.md) components to be submitted and reset. For details, see [form](../reference/arkui-js/js-components-container-form.md). ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->This component is supported since API version 6. +The <form> component allows the content in [<input>](../reference/arkui-js/js-components-basic-input.md)components to be submitted and reset. For details, see [form](../reference/arkui-js/js-components-container-form.md). -## Creating a Component -Create a **** component in the **.hml** file under **pages/index**. +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> This component is supported since API version 6. + + +## Creating a <form> Component + + Create a <form> component in the .hml file under pages/index. ```
-
- +
``` + ``` /* xxx.css */ .container { @@ -28,11 +31,12 @@ Create a **** component in the **.hml** file under **pages/index**. } ``` -![](figures/11.png) +![en-us_image_0000001267887873](figures/en-us_image_0000001267887873.png) -## Zooming In or Out on a Form -To implement the zoom effect after a form is clicked, add the **click-effect** attribute to the **** component. For values of **click-effect**, see [Universal Attributes](../reference/arkui-js/js-components-common-attributes.md). +## Zooming In or Out on a Form + + To implement the zoom effect after a form is clicked, add the click-effect attribute to the <form> component. For values of click-effect, see [Universal Attributes](../reference/arkui-js/js-components-common-attributes.md). ``` @@ -43,9 +47,11 @@ To implement the zoom effect after a form is clicked, add the **click-effect**
``` -## Setting the Form Style -Add the **background-color** and **border** attributes. +## Setting the Form Style + + +Add the background-color and border attributes. ``` /* xxx.css */ @@ -62,11 +68,13 @@ Add the **background-color** and **border** attributes. } ``` -![](figures/7.gif) -## Adding Response Events +![en-us_image_0000001267607913](figures/en-us_image_0000001267607913.gif) + -To submit or reset a form, add the **submit** and **reset** events. +## Adding Response Events + + To submit or reset a form, add the submit and reset events. ``` @@ -88,6 +96,7 @@ To submit or reset a form, add the **submit** and **reset** events. ``` + ``` /* xxx.js */ import prompt from '@system.prompt'; @@ -105,13 +114,16 @@ export default{ } ``` -![](figures/8-6.gif) -## Example Scenario +![en-us_image_0000001267767885](figures/en-us_image_0000001267767885.gif) + + +## Example Scenario Select an option and submit or reset the form data. -Create [****](../reference/arkui-js/js-components-basic-input.md) components, set their **type** attribute to **checkbox** and **radio**, and use the **onsubmit** and **onreset** events of the **** component to submit and reset the form data. +Create [<input>](../reference/arkui-js/js-components-basic-input.md) (en-us_topic_0000001173324647.xml) components, set their type attribute to checkbox and radio, and use the onsubmit and onreset events of the <form> component to submit and reset the form data. + ``` @@ -148,6 +160,7 @@ Create [****](../reference/arkui-js/js-components-basic-input.md) comp ``` + ``` /* index.css */ .container { @@ -165,6 +178,7 @@ label{ } ``` + ``` /* xxx.js */ import prompt from '@system.prompt'; @@ -182,5 +196,4 @@ export default { } ``` -![](figures/9.gif) - +![en-us_image_0000001222967788](figures/en-us_image_0000001222967788.gif) diff --git a/en/application-dev/ui/ui-js-components-images.md b/en/application-dev/ui/ui-js-components-images.md index a74db3749a3673fd691a013822ff71096792c1e6..3497b09ad3d4f5c437ece54b573d7ec7e7cd8222 100644 --- a/en/application-dev/ui/ui-js-components-images.md +++ b/en/application-dev/ui/ui-js-components-images.md @@ -1,10 +1,12 @@ -# Image +# <image> Development -The **** component is used to render and display images. For details, see [image](../reference/arkui-js/js-components-basic-image.md). -## Creating an Component +The <image> component is used to render and display images. For details, see [image](../reference/arkui-js/js-components-basic-image.md). -Create an **** component in the **.hml** file under **pages/index**. + +## Creating an <image> Component + + Create an <image> component in the .hml file under pages/index. ``` @@ -13,6 +15,7 @@ Create an **** component in the **.hml** file under **pages/index** ``` + ``` /* xxx.css */ .container { @@ -23,11 +26,12 @@ Create an **** component in the **.hml** file under **pages/index** } ``` -![](figures/10-10.png) +![en-us_image_0000001223127736](figures/en-us_image_0000001223127736.png) -## Setting the Image Style -Set the **width**, **height**, and **object-fit** attributes to define the width, height, and scale type of an image. +## Setting the Image Style + +Set the width, height, and object-fit attributes to define the width, height, and scale type of an image. ``` @@ -42,11 +46,10 @@ Set the **width**, **height**, and **object-fit** attributes to define the w flex-direction: column; align-items: center; justify-content: center; - background-color:#F1F3F5; +background-color:#F1F3F5; } image{ - width: 80%; - height: 500px; + width: 80%; height: 500px; border: 5px solid saddlebrown; border-radius: 20px; object-fit: contain; @@ -55,11 +58,13 @@ image{ } ``` -![](figures/7-11.png) -## Display Multiple Images +![en-us_image_0000001222807796](figures/en-us_image_0000001222807796.png) -Define a **for** loop to display multiple images cyclically. Set **option** to specify the image scale style. For details about the scale styles, see the description of object-fit. + +## Display Multiple Images + + Define a for loop to display multiple images cyclically. Set option to specify the image scale style. For details about the scale styles, see the description of object-fit. ``` @@ -81,6 +86,7 @@ Define a **for** loop to display multiple images cyclically. Set **option** ``` + ``` /* xxx.css */ .page-container { @@ -114,6 +120,7 @@ Define a **for** loop to display multiple images cyclically. Set **option** } ``` + ``` /* index.js */ export default { @@ -129,11 +136,14 @@ export default { } ``` -![](figures/34-12.gif) -## Loading Images +![en-us_image_0000001267767873](figures/en-us_image_0000001267767873.gif) + + +## Loading Images + +When an image is successfully loaded, the complete event is triggered, and the loaded image is returned. If an exception occurs during image loading, the error event is triggered, and the image loading failure is printed. -When an image is successfully loaded, the **complete** event is triggered, and the loaded image is returned. If an exception occurs during image loading, the **error** event is triggered, and the image loading failure is printed. ``` @@ -147,6 +157,7 @@ When an image is successfully loaded, the **complete** event is triggered, and ``` + ``` /* xxx.css */ .container{ @@ -163,6 +174,7 @@ When an image is successfully loaded, the **complete** event is triggered, and } ``` + ``` /* index.js */ import prompt from '@system.prompt'; @@ -184,11 +196,12 @@ export default { } ``` -![](figures/111.gif) +![en-us_image_0000001267887865](figures/en-us_image_0000001267887865.gif) -## Example Scenario -In this example you touch and hold an image to gradually hide it. After the image is completely hidden, it will show in its original setting. Set a **setInterval** timer to change the image opacity at a specified interval so that it is hidden gradually. When the opacity changes to **0**, the timer is cleared and the opacity is set to **1**. +## Example Scenario + + In this example you touch and hold an image to gradually hide it. After the image is completely hidden, it will show in its original setting. Set a setInterval timer to change the image opacity at a specified interval so that it is hidden gradually. When the opacity changes to 0, the timer is cleared and the opacity is set to 1. ``` @@ -204,6 +217,7 @@ In this example you touch and hold an image to gradually hide it. After the imag ``` + ``` /* xxx.css */ .page-container { @@ -211,6 +225,7 @@ In this example you touch and hold an image to gradually hide it. After the imag align-self: center; justify-content: center; background-color:#F1F3F5; + background-color: #F1F3F5; } .content{ flex-direction:column; @@ -229,13 +244,10 @@ In this example you touch and hold an image to gradually hide it. After the imag justify-content: space-between; } .testimage { - width: 100%; - height: 400px; - object-fit: scale-down; - border-radius: 20px; -} + width: 100%; height: 400px; object-fit: scale-down; border-radius: 20px;} ``` + ``` /* index.js */ import prompt from '@system.prompt'; @@ -263,5 +275,4 @@ export default { } ``` -![](figures/17.gif) - +![en-us_image_0000001267607905](figures/en-us_image_0000001267607905.gif) diff --git a/en/application-dev/ui/ui-js-components-input.md b/en/application-dev/ui/ui-js-components-input.md index f98b669ebe7560b969e287548b9567451ef25985..559cca5401092490afd8ea1e841ae6d3b8809bba 100644 --- a/en/application-dev/ui/ui-js-components-input.md +++ b/en/application-dev/ui/ui-js-components-input.md @@ -1,20 +1,22 @@ -# Input +# Development -The **** component provides an interactive way to receive user input of various types, including **date**, **checkbox**, and **button**. For details, see [input](../reference/arkui-js/js-components-basic-input.md). -## Creating an Component +The component provides an interactive way to receive user input of various types, including date, checkbox, and button. For details, see [input](../reference/arkui-js/js-components-basic-input.md). + + +## Creating an Component + +Create an component in the .hml file under pages/index. -Create an **** component in the **.hml** file under **pages/index**. ```
- - Please enter the content - + Please enter the content
``` + ``` /* xxx.css */ .container { @@ -25,11 +27,13 @@ Create an **** component in the **.hml** file under **pages/index** } ``` -![](figures/2.png) +![en-us_image_0000001222807768](figures/en-us_image_0000001222807768.png) + + +## Setting the Input Type -## Setting the Input Type +Set the type attribute of the component to button, date, or any of the supported values. -Set the **type** attribute of the **** component to **button**, **date**, or any of the supported values. ``` @@ -51,6 +55,7 @@ Set the **type** attribute of the **** component to **button**, ** ``` + ``` /* xxx.css */ .container { @@ -83,6 +88,7 @@ Set the **type** attribute of the **** component to **button**, ** } ``` + ``` // xxx.js export default { @@ -92,15 +98,19 @@ export default { } ``` -![](figures/18.gif) ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- For wearables, the input type can only be **button**, **radio**, or **checkbox**. ->- The settings of **checked** take effect only when the input type is set to **checkbox** or **radio**. The default value of **checked** is **false**. +![en-us_image_0000001223287672](figures/en-us_image_0000001223287672.gif) + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - For wearables, the input type can only be button, radio, or checkbox. +> +> - The settings of checked take effect only when the input type is set to checkbox or radio. The default value of checked is false. -## Event Binding -Add the **search** and **translate** events to the **** component. +## Event Binding + + Add the search and translate events to the component. ``` @@ -113,6 +123,7 @@ Add the **search** and **translate** events to the **** component. ``` + ``` /* xxx.css */ .content { @@ -134,6 +145,7 @@ text{ } ``` + ``` // xxx.js import prompt from '@system.prompt' @@ -153,11 +165,13 @@ export default { } ``` -![](figures/36.gif) +![en-us_image_0000001267647853](figures/en-us_image_0000001267647853.gif) -## Setting the Input Error Message -Add the **showError** method to the **** component to display an error message in the event of incorrect input. +## Setting the Input Error Message + +Add the showError method to the component to display an error message in the event of incorrect input. + ``` @@ -168,6 +182,7 @@ Add the **showError** method to the **** component to display an err ``` + ``` /* xxx.css */ .content { @@ -187,6 +202,7 @@ Add the **showError** method to the **** component to display an err } ``` + ``` // xxx.js import prompt from '@system.prompt' @@ -203,13 +219,9 @@ import prompt from '@system.prompt' }, buttonClick(e){ if(this.value.length > 6){ - this.$element("input").showError({ - error: 'Up to 6 characters are allowed.' - }); + this.$element("input").showError({ error: 'Up to 6 characters are allowed.' }); }else if(this.value.length == 0){ - this.$element("input").showError({ - error:this.value + 'This field cannot be left empty.' - }); + this.$element("input").showError({ error:this.value + 'This field cannot be left empty.' }); }else{ prompt.showToast({ message: "success " @@ -219,15 +231,18 @@ import prompt from '@system.prompt' } ``` -![](figures/19.gif) +![en-us_image_0000001223127708](figures/en-us_image_0000001223127708.gif) + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - This method is available when the input type is set to text, email, date, time, number, or password. ->![](../public_sys-resources/icon-note.gif) **NOTE:** -> ->- This method is available when the input type is set to **text**, **email**, **date**, **time**, **number**, or **password**. -## Example Scenario +## Example Scenario + + +Enter information by using the component of the type that suits your needs. + -Enter information by using the **** component of the type that suits your needs. ``` @@ -257,6 +272,8 @@ Enter information by using the **** component of the type that suits y ``` + + ``` /* xxx.css */ .container { @@ -285,6 +302,8 @@ label { } ``` + + ``` // xxx.js import prompt from '@system.prompt'; @@ -301,5 +320,5 @@ export default { } ``` -![](figures/4.gif) +![en-us_image_0000001222807760](figures/en-us_image_0000001222807760.gif) diff --git a/en/application-dev/ui/ui-js-components-list.md b/en/application-dev/ui/ui-js-components-list.md index 6e45758d530697b6793bfbfe18c9fe5dde6a2120..a62d6b67594e3dd2819a513042ba3800dd1dcc75 100644 --- a/en/application-dev/ui/ui-js-components-list.md +++ b/en/application-dev/ui/ui-js-components-list.md @@ -1,16 +1,18 @@ -# List +# <list> Development -The **** component provides a list container that presents a series of list items arranged in a column with the same width. Lists can be used for presenting the same type of data in a multiple and coherent row style. For details, see [list](../reference/arkui-js/js-components-container-list.md). -## Creating a Component +The <list> component provides a list container that presents a series of list items arranged in a column with the same width. Lists can be used for presenting the same type of data in a multiple and coherent row style. For details, see [list](../reference/arkui-js/js-components-container-list.md). + + +## Creating a <list> Component + +Create a <list> component in the .hml file under pages/index. -Create a **** component in the **.hml** file under **pages/index**. ```
- - + @@ -18,6 +20,7 @@ Create a **** component in the **.hml** file under **pages/index**.
``` + ``` /* xxx.css */ .container { @@ -32,15 +35,18 @@ Create a **** component in the **.hml** file under **pages/index**. } ``` -![](figures/5.png) +![en-us_image_0000001223287680](figures/en-us_image_0000001223287680.png) ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- **** is a child component of the **** component and is used to group items in a list. It can have a **** nested inside, but not ****. ->- **** is a child component of the **** component and is used to display items in a list. +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - <list-item-group> is a child component of the <list> component and is used to group items in a list. It can have a <list-item> nested inside, but not <list>. +> +> - <list-item> is a child component of the <list> component and is used to display items in a list. -## Adding a Scrollbar -To display a scrollbar on the right side of the screen, set **scrollbar** to **on**. The side scrollbar can be used to scroll a long list or the screen up or down. +## Adding a Scrollbar + +To display a scrollbar on the right side of the screen, set scrollbar to on. The side scrollbar can be used to scroll a long list or the screen up or down. + ``` @@ -56,6 +62,7 @@ To display a scrollbar on the right side of the screen, set **scrollbar** to ``` + ``` /* index.css */ .container { @@ -74,11 +81,13 @@ To display a scrollbar on the right side of the screen, set **scrollbar** to } ``` -![](figures/24.gif) +![en-us_image_0000001223287684](figures/en-us_image_0000001223287684.gif) + + +## Adding a Side Index Bar -## Adding a Side Index Bar +Set a custom indexer component to add an index bar at the right boundary of a list. By default, an alphabetical indexer is used. -Set a custom **indexer** component to add an index bar at the right boundary of a list. By default, an alphabetical indexer is used. ``` @@ -89,9 +98,10 @@ Set a custom **indexer** component to add an index bar at the right boundary o ``` + ``` /* index.css */ -.container { +.container{ flex-direction: column; background-color: #F1F3F5; } @@ -102,15 +112,18 @@ Set a custom **indexer** component to add an index bar at the right boundary o } ``` -![](figures/00.png) +![en-us_image_0000001223127716](figures/en-us_image_0000001223127716.png) + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - This indexer attribute is valid only when flex-direction is set to column and columns is set to 1. +> +> - You must include "\#" when using a customized indexer. ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- This **indexer** attribute is valid only when **flex-direction** is set to **column** and **columns** is set to **1**. ->- You must include **"\#"** when using a customized indexer. -## Collapsing or Expanding a List +## Collapsing or Expanding a List + +To allow a <list> component to collapse and expand, add groupcollapse and groupexpand events. -To allow a **** component to collapse and expand, add **groupcollapse** and **groupexpand** events. ``` @@ -132,6 +145,7 @@ To allow a **** component to collapse and expand, add **groupcollapse* ``` + ``` /* index.css */ .doc-page { @@ -152,6 +166,7 @@ margin-top:30px; } ``` + ``` // xxx.js import prompt from '@system.prompt'; @@ -183,21 +198,18 @@ export default { } ``` -![](figures/8-4.gif) +![en-us_image_0000001267887845](figures/en-us_image_0000001267887845.gif) + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - The groupcollapse and groupexpand events can be used only by the list-item-group component. ->![](../public_sys-resources/icon-note.gif) **NOTE:** -> ->- The **groupcollapse** and **groupexpand** events can be used only by the **list-item-group** component. -## Example Scenario +## Example Scenario Search for contacts by using an alphabetical indexer. ``` -``` - -```
Contacts @@ -294,5 +306,5 @@ export default { } ``` -![](figures/27.gif) +![en-us_image_0000001267767861](figures/en-us_image_0000001267767861.gif) diff --git a/en/application-dev/ui/ui-js-components-picker.md b/en/application-dev/ui/ui-js-components-picker.md index 6d4f4131e62832db16054273b3d7052ada0ad5be..6771d67b18ff6bc44b6ba9ccc3783058d2d74fcc 100644 --- a/en/application-dev/ui/ui-js-components-picker.md +++ b/en/application-dev/ui/ui-js-components-picker.md @@ -1,20 +1,22 @@ -# Picker +# <picker> Development -The **** component supports common, date, time, data and time, and multi-column text selectors. For details, see [picker](../reference/arkui-js/js-components-basic-picker.md). -## Creating a Component +The <picker> component supports common, date, time, data and time, and multi-column text selectors. For details, see [picker](../reference/arkui-js/js-components-basic-picker.md). + + +## Creating a <picker> Component + +Create a <picker> component in the .hml file under pages/index. -Create a **** component in the **.hml** file under **pages/index**. ```
- - picker - + picker
``` + ``` /* index.css */ .container { @@ -25,11 +27,13 @@ Create a **** component in the **.hml** file under **pages/index** } ``` -![](figures/20211008-184455(welinkpc).gif) +![en-us_image_0000001223287716](figures/en-us_image_0000001223287716.gif) + -## Setting the Picker Type +## Setting the Picker Type + +Set the type attribute of the <picker> component. For example, set it to date. -Set the **type** attribute of the **** component. For example, set it to **date**. ``` @@ -39,6 +43,7 @@ Set the **type** attribute of the **** component. For example, set
``` + ``` /* index.css */ .container { @@ -52,6 +57,7 @@ Set the **type** attribute of the **** component. For example, set } ``` + ``` // xxx.js export default { @@ -63,15 +69,18 @@ export default { } ``` -![](figures/20211217-130837(welinkpc).gif) +![en-us_image_0000001267647893](figures/en-us_image_0000001267647893.gif) + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - When setting the value range of a common selector, you must use the data binding mode. +> +> - The lunarswitch attribute of the date selector is only supported on phones and tablets. ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- When setting the value range of a common selector, you must use the data binding mode. ->- The **lunarswitch** attribute of the date selector is only supported on phones and tablets. -## Setting the Time Format +## Setting the Time Format + +Set the hours attribute to specify the time format used by the time selector. Available values include 12 and 24, indicating the 12-hour format and 24-hour format, respectively. -Set the **hours** attribute to specify the time format used by the time selector. Available values include **12** and **24**, indicating the 12-hour format and 24-hour format, respectively. ``` @@ -81,6 +90,7 @@ Set the **hours** attribute to specify the time format used by the time select
``` + ``` /* index.css */ .container { @@ -96,15 +106,18 @@ Set the **hours** attribute to specify the time format used by the time select } ``` -![](figures/25.gif) +![en-us_image_0000001222807808](figures/en-us_image_0000001222807808.gif) + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - When hours is set to 12, the time is displayed in 12-hour format and distinguished by a.m. and p.m. +> +> - When hours is set to 24, the time is displayed in 24-hour format. + ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- When **hours** is set to **12**, the time is displayed in 12-hour format and distinguished by a.m. and p.m. ->- When **hours** is set to **24**, the time is displayed in 24-hour format. +## Adding Response Events -## Adding Response Events +To confirm and cancel selection, add change and cancel events. -To confirm and cancel selection, add **change** and **cancel** events. ``` @@ -114,6 +127,7 @@ To confirm and cancel selection, add **change** and **cancel** events.
``` + ``` /* index.css */ .container { @@ -131,6 +145,7 @@ To confirm and cancel selection, add **change** and **cancel** events. } ``` + ``` // xxx.js import prompt from '@system.prompt'; @@ -150,11 +165,13 @@ export default { } ``` -![](figures/26.gif) +![en-us_image_0000001223127748](figures/en-us_image_0000001223127748.gif) + + +## Example Scenario -## Example Scenario -Implement a health check-in application by using the **** component. +Implement a health check-in application by using the <picker> component. ``` @@ -277,5 +294,5 @@ export default { } ``` -![](figures/qqqq.gif) +![en-us_image_0000001267887877](figures/en-us_image_0000001267887877.gif) diff --git a/en/application-dev/ui/ui-js-components-stepper.md b/en/application-dev/ui/ui-js-components-stepper.md index cab1e9ae62f36ef4570d294f9a64f0cd1f231f62..d9a13be87c74e1e602c5352f6f324cf5d08ed6ea 100644 --- a/en/application-dev/ui/ui-js-components-stepper.md +++ b/en/application-dev/ui/ui-js-components-stepper.md @@ -1,19 +1,22 @@ -# Stepper +# <stepper> Development -When multiple steps are required to complete a task, you can use the **** component to navigate your users through the whole process. For details, see [stepper](../reference/arkui-js/js-components-container-stepper.md). ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->This component is supported since API version 5. +When multiple steps are required to complete a task, you can use the <stepper> component to navigate your users through the whole process. For details, see [stepper](../reference/arkui-js/js-components-container-stepper.md). -## Creating a Component -Create a **** component in the **.hml** file under **pages/index**. +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> This component is supported since API version 5. + + +## Creating a <stepper> Component + +Create a <stepper> component in the .hml file under pages/index. + ```
- - + Step 1 @@ -23,6 +26,7 @@ Create a **** component in the **.hml** file under **pages/index*
``` + ``` /* xxx.css */ .container { @@ -38,11 +42,13 @@ text{ } ``` -![](figures/2-7.gif) +![en-us_image_0000001223287656](figures/en-us_image_0000001223287656.gif) + -## Setting the Index +## Setting the Index + +Set index to the index value of the step that you want to display by default. -Set **index** to the index value of the step that you want to display by default. ``` @@ -61,6 +67,7 @@ Set **index** to the index value of the step that you want to display by defau ``` + ``` /* index.css */ .container { @@ -74,9 +81,10 @@ text{ } ``` -![](figures/10.gif) +![en-us_image_0000001267767837](figures/en-us_image_0000001267767837.gif) + +Set the label attribute to customize the button text for the <stepper-item>. -Set the **label** attribute to customize the button text for the ****. ``` @@ -98,6 +106,7 @@ Set the **label** attribute to customize the button text for the ** ``` + ``` /* index.css */ .container { @@ -111,14 +120,12 @@ text{ } ``` + ``` /* index.js */ export default { data: { - label_1:{ - nextLabel: 'NEXT', - status: 'normal' - }, + label_1:{ nextLabel: 'NEXT', status: 'normal' }, label_2:{ prevLabel: 'BACK', nextLabel: 'NEXT', @@ -133,11 +140,12 @@ export default { } ``` -![](figures/11-8.gif) +![en-us_image_0000001267767841](figures/en-us_image_0000001267767841.gif) -## Setting the Style -By default, the **** component fills entire space of its container. The sample code below shows how to set the border and background color using the **border** and **background-color** attributes. +## Setting the Style + + By default, the <stepper> component fills entire space of its container. The sample code below shows how to set the border and background color using the border and background-color attributes. ``` @@ -152,6 +160,7 @@ By default, the **** component fills entire space of its container. ``` + ``` /* index.css */ .container { @@ -165,8 +174,7 @@ By default, the **** component fills entire space of its container. height: 300px; } .stepperClass{ - border:1px solid silver ; - background-color: white; + border:1px solid silver ; background-color: white; } text{ width: 100%; @@ -175,14 +183,16 @@ text{ } ``` -![](figures/02.png) +![en-us_image_0000001223287668](figures/en-us_image_0000001223287668.png) -## Adding Events -The **** component supports the **finish**, **change**, **next**, **back**, and **skip** events. +## Adding Events -- When the **change** and **next** or **back** events exist at the same time, the **next** or **back** event is executed before the **change** event. -- Before resetting the **index** attribute, you must remove the current value. Otherwise, the value change cannot be detected. +The <stepper> component supports the finish, change, next, back, and skip events. + +- When the change and next or back events exist at the same time, the next or back event is executed before the change event. + +- Before resetting the index attribute, you must remove the current value. Otherwise, the value change cannot be detected. ``` @@ -205,6 +215,7 @@ The **** component supports the **finish**, **change**, **next**, ``` + ``` /* xxx.css */ .doc-page { @@ -231,6 +242,7 @@ button{ } ``` + ``` /* index.js */ import prompt from '@system.prompt'; @@ -272,13 +284,15 @@ export default { } ``` -![](figures/37.gif) +![en-us_image_0000001267607869](figures/en-us_image_0000001267607869.gif) + -## Example Scenario +## Example Scenario Select the options displayed on the page. Your selection will be shown in real time. Click the next button to dynamically change the font color and font size on the page. -Use the **** component to navigate through the steps. Create a [****](../reference/arkui-js/js-components-basic-toggle.md) component to implement the functions of selection and displaying the selection result. Then use the [****](../reference/arkui-js/js-components-basic-select.md) component to dynamically change the font color or size of the selected options. +Use the <stepper> component to navigate through the steps. Create a [<toggle>](../reference/arkui-js/js-components-basic-toggle.md) component to implement the functions of selection and displaying the selection result. Then use the [<select>](../reference/arkui-js/js-components-basic-select.md) component to dynamically change the font color or size of the selected options. + ```
@@ -321,6 +335,7 @@ Use the **** component to navigate through the steps. Create a [**<
``` + ``` /* xxx.css */ .container { @@ -340,6 +355,7 @@ Use the **** component to navigate through the steps. Create a [**< } ``` + ``` /* index.js */ import prompt from '@system.prompt'; @@ -382,5 +398,4 @@ export default { } ``` -![](figures/28.gif) - +![en-us_image_0000001267887817](figures/en-us_image_0000001267887817.gif) diff --git a/en/application-dev/ui/ui-js-components-text.md b/en/application-dev/ui/ui-js-components-text.md index 99942a3c164a191a8dff423bce1965e22bd49c93..68fc3006a34b48456df5a99ebbbcf39fd338f5d4 100644 --- a/en/application-dev/ui/ui-js-components-text.md +++ b/en/application-dev/ui/ui-js-components-text.md @@ -1,23 +1,27 @@ -# Text +# <text> Development -The **** component is used to display a piece of textual information. For details, see [text](../reference/arkui-js/js-components-basic-text.md). -## Creating a Component +The <text> component is used to display a piece of textual information. For details, see [text](../reference/arkui-js/js-components-basic-text.md). + + +## Creating a <text> Component + +Create a <text> component in the .hml file under pages/index. -Create a **** component in the **.hml** file under **pages/index**. ```
- - Hello World - + Hello World
``` + ``` /* xxx.css */ .container { + width: 100%; + height: 100%; flex-direction: column; align-items: center; justify-content: center; @@ -25,141 +29,174 @@ Create a **** component in the **.hml** file under **pages/index**. } ``` -![](figures/01.png) +![en-us_image_0000001222807780](figures/en-us_image_0000001222807780.png) -## Setting the Text Style and Attributes -- Adding a text style +## Setting the Text Style and Attributes -Set the **color**, **font-size**, and **allow-scale** attributes. +- Adding a text style -``` - -
- - This is a passage - -
-``` -![](figures/01-0.png) + Set the color, font-size, allow-scale, word-spacing, and text-valign attributes to apply the color, size, zoom, spacing, and vertical alignment styles to the text. -- Adding a text modifier + ``` + +
+ + This is a passage + + + This is a passage + +
+ ``` + + + + ``` + /* xxx.css */ + .container { + width: 100%; + height: 100%; + flex-direction: column; + align-items: center; + justify-content: center; + background-color: #F1F3F5; + } + ``` -Set the **text-decoration** attribute to add an underline, overline, line-through, or a combination of lines to selected text. For values of **text-decoration**, see [Text Style](../reference/arkui-js/js-components-basic-text.md). -``` - -
- - This is a passage - - - This is a passage - -
-``` + ![en-us_image_0000001222967764](figures/en-us_image_0000001222967764.png) -``` -/* xxx.css */ -.container { - flex-direction: column; - align-items: center; - justify-content: center; -} -text{ - font-size: 50px; -} -``` +- Adding a text modifier -![](figures/3.png) -- Hiding text content + Set the text-decoration attribute to add a line to selected text. Set the text-decoration-color attribute to apply specific color to the added line. For values of text-decoration, see [Text Style](../reference/arkui-js/js-components-basic-text.md). -Set the **text-overflow** attribute to **ellipsis** so that overflowed text is displayed as an ellipsis. + ``` + +
+ + This is a passage + + + This is a passage + +
+ ``` + + ``` + /* xxx.css */ + .container { + width: 100%; + height: 100%; + flex-direction: column; + align-items: center; + justify-content: center; + } + text{ + font-size: 50px; + } + ``` -``` - -
- - This is a passage - -
-``` -``` -/* xxx.css */ -.container { - flex-direction: column; - align-items: center; - background-color: #F1F3F5; - justify-content: center; -} -.text{ - width: 200px; - max-lines: 1; - text-overflow:ellipsis; -} -``` + ![en-us_image_0000001223287688](figures/en-us_image_0000001223287688.png) ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- **text-overflow** must be used together with **max-lines**. ->- **max-lines** indicates the maximum number of lines in the text. +- Hiding text content -![](figures/05.png) -- Setting the text line breaking mode + Set the text-overflow attribute to ellipsis so that overflowed text is displayed as an ellipsis. -Set the **word-break** attribute to specify how to break lines of text. For values of **word-break**, see [Text Styles](../reference/arkui-js/js-components-basic-text.md). - -``` - -
-
- - Welcome to the world - - - Welcome to the world + ``` + +
+ + This is a passage
-
-``` + ``` + + ``` + /* xxx.css */ + .container { + width: 100%; + height: 100%; + flex-direction: column; + align-items: center; + background-color: #F1F3F5; + justify-content: center; + } + .text{ + width: 200px; + max-lines: 1; + text-overflow:ellipsis; + } + ``` + + + > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: + > - text-overflow must be used together with max-lines. + > + > - max-lines indicates the maximum number of lines in the text. -``` -/* xxx.css */ -.container { - background-color: #F1F3F5; - flex-direction: column; - align-items: center; - justify-content: center; -} -.content{ - width: 50%; - flex-direction: column; - align-items: center; - justify-content: center; -} -.text1{ - height: 200px; - border:1px solid #1a1919; - margin-bottom: 50px; - text-align: center; - word-break: break-word; - font-size: 40px; -} -.text2{ - height: 200px; - border:1px solid #0931e8; - text-align: center; - word-break: break-all; - font-size: 40px; -} -``` -![](figures/8.png) +![en-us_image_0000001267647865](figures/en-us_image_0000001267647865.png) -- Setting the [****](../reference/arkui-js/js-components-basic-span.md) child component + +- Setting the text line breaking mode + + + Set the word-break attribute to specify how to break lines of text. For values of word-break, see [Text Styles](../reference/arkui-js/js-components-basic-text.md). + + ``` + +
+
+ + Welcome to the world + + + Welcome to the world + +
+
+ ``` + + ``` + /* xxx.css */ + .container { + background-color: #F1F3F5; + flex-direction: column; + align-items: center; + justify-content: center; + } + .content{ + width: 50%; + flex-direction: column; + align-items: center; + justify-content: center; + } + .text1{ + height: 200px; + border:1px solid #1a1919; + margin-bottom: 50px; + text-align: center; + word-break: break-word; + font-size: 40px; + } + .text2{ + height: 200px; + border:1px solid #0931e8; + text-align: center; + word-break: break-all; + font-size: 40px; + } + ``` + + + ![en-us_image_0000001267767865](figures/en-us_image_0000001267767865.png) + +- Setting the [<span>](../reference/arkui-js/js-components-basic-span.md)child component ``` @@ -168,47 +205,45 @@ Set the **word-break** attribute to specify how to break lines of text. For va This is a passage - This - - 1 - - is a - - 1 - - passage + This 1 is a 1 passage
``` -![](figures/01-1.png) ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- When the **** child component is used to form a text paragraph, incorrect **** attribute settings \(for example, setting of **font-weight** to **1000**\) will result in abnormal display of the text paragraph. ->- When the **** child component is being used, do not include any text you want to show in the **** component, as such text will not be displayed if you do so. +![en-us_image_0000001223127720](figures/en-us_image_0000001223127720.png) -## Example Scenario -Use the **** component to display text content through data binding. Use the **** child component to hide or display text content by setting the **show** attribute. +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**: +> - When the <span> child component is used to form a text paragraph, incorrect <span> attribute settings (for example, setting of font-weight to 1000) will result in abnormal display of the text paragraph. +> +> - When the <span> child component is being used, do not include any text you want to show in the <text> component, as such text will not be displayed if you do so. + + +## Example Scenario + +Use the <text> component to display text content through data binding. Use the <span> child component to hide or display text content by setting the show attribute. + + + ``` + +
+
+ + {{ content }} + + +
+ + {{ content }} + + 1 + + Hide clip + +
+ ``` -``` - -
-
- - {{ content }} - - -
- - {{ content }} - - 1 - - Hide clip - -
-``` ``` /* xxx.css */ @@ -226,6 +261,7 @@ Use the **** component to display text content through data binding. Us } ``` + ``` // xxx.js export default { @@ -240,5 +276,4 @@ export default { } ``` -![](figures/1.gif) - +![en-us_image_0000001267887849](figures/en-us_image_0000001267887849.gif) diff --git a/en/application-dev/ui/ui-js-custom-components.md b/en/application-dev/ui/ui-js-custom-components.md index 1799c5b51a44cfc754851dc129c239609155bdb6..c2a5c96faa10df363c415c32ec9e80db9a752560 100644 --- a/en/application-dev/ui/ui-js-custom-components.md +++ b/en/application-dev/ui/ui-js-custom-components.md @@ -1,100 +1,106 @@ -# Custom Components +# Custom Components -The ArkUI that uses the JavaScript-based web-like development paradigm supports custom components for you to extend existing components. You can encapsulate custom private attributes and events into new components to reuse them multiple times in your project. This also improves code readability. The following is an example: -- **Building a custom component** +The ArkUI that uses the JavaScript-based web-like development paradigm supports custom components for you to extend existing components. You can encapsulate custom private attributes and events into new components to reuse them multiple times in your project. This also improves code readability. The following is an example: - ``` - -
- {{title}} - Click to view the hidden text. - hello world -
- ``` - ``` - /* comp.css */ - .item { - width: 700px; - flex-direction: column; - height: 300px; - align-items: center; - margin-top: 100px; - } - .text-style { - width: 100%; - text-align: center; - font-weight: 500; - font-family: Courier; - font-size: 36px; - } - .title-style { - font-weight: 500; - font-family: Courier; - font-size: 50px; - color: #483d8b; - } - ``` +- Building a custom component + + ``` + +
+ {{title}} + Click to view the hidden text. + hello world +
+ ``` - ``` - // comp.js - export default { - props: { - title: { - default: 'title', - }, - showObject: {}, - }, - data() { - return { - showObj: this.showObject, - }; - }, - childClicked () { - this.$emit('eventType1', {text: 'Receive the parameters from the child component.'}); - this.showObj = !this.showObj; - }, - } - ``` + + ``` + /* comp.css */ + .item { + width: 700px; + flex-direction: column; + height: 300px; + align-items: center; + margin-top: 100px; + } + .text-style { + width: 100%; + text-align: center; + font-weight: 500; + font-family: Courier; + font-size: 36px; + } + .title-style { + font-weight: 500; + font-family: Courier; + font-size: 50px; + color: #483d8b; + } + ``` -- **Introducing the custom component** + + ``` + // comp.js + export default { + props: { + title: { + default: 'title', + }, + showObject: {}, + }, + data() { + return { + showObj: this.showObject, + }; + }, + childClicked () { + this.$emit('eventType1', {text: 'Receive the parameters from the child component.'}); + this.showObj = !this.showObj; + }, + } + ``` - ``` - - -
- Parent component: {{text}} - -
- ``` +- Introducing the custom component + + ``` + + +
+ Parent component: {{text}} + +
+ ``` - ``` - /* xxx.css */ - .container { - background-color: #f8f8ff; - flex: 1; - flex-direction: column; - align-content: center; - } - ``` + + ``` + /* xxx.css */ + .container { + background-color: #f8f8ff; + flex: 1; + flex-direction: column; + align-content: center; + } + ``` - ``` - // xxx.js - export default { - data: { - text: 'Start' - isShow: false, - }, - textClicked (e) { - this.text = e.detail.text; - }, - } - ``` + + ``` + // xxx.js + export default { + data: { + text: 'Start' + isShow: false, + }, + textClicked (e) { + this.text = e.detail.text; + }, + } + ``` -In this example, the parent component passes the customized attribute through **title** to the child component, and the child component receives the attribute value in **props**. The child component passes **text** to the parent through the bound event, and the passed value is obtained via **e.detail**. To successfully bind the child component event to the parent component, ensure that the event name meet the requirements for event binding. For details, see [Basic Usage of Custom Components](../reference/arkui-js/js-components-custom-basic-usage.md). The following figures show how the custom component works. +In this example, the parent component passes the customized attribute through title to the child component, and the child component receives the attribute value in props. The child component passes text to the parent through the bound event, and the passed value is obtained via e.detail. To successfully bind the child component event to the parent component, ensure that the event name meet the requirements for event binding. For details, see [Basic Usage of Custom Components](../reference/arkui-js/js-components-custom-basic-usage.md). The following figures show how the custom component works. -**Figure 1** Running effect -![](figures/running-effect.png "running-effect") + figure1 Running effect + ![en-us_image_0000001222807816](figures/en-us_image_0000001222807816.png) diff --git a/en/application-dev/ui/ui-js-overview.md b/en/application-dev/ui/ui-js-overview.md index 7d9da6ca4f2bb6ff1edde7c22e8f4616febaa06e..39612e9d878502f3a855b24dae62eee1ea8b5436 100644 --- a/en/application-dev/ui/ui-js-overview.md +++ b/en/application-dev/ui/ui-js-overview.md @@ -1,35 +1,29 @@ -# Overview +# Overview - ArkUI with the JavaScript-based web-like development paradigm provides UI components \(basic, container, canvas, and more\) and standard CSS animation capabilities. -## Basic Capabilities +The web-like development paradigm uses the classical three-stage programming model, in which OpenHarmony Markup Language (HML) is used for building layouts, CSS for defining styles, and JavaScript for adding processing logic. UI components are associated with data through one-way data-binding. This means that when data changes, the UI automatically updates with the new data. This development paradigm has a low learning curve for frontend web developers, allowing them to quickly transform existing web applications into ArkUI applications. It could be helpful if you are developing small- and medium-sized applications with simple UIs. -- **Web-like development paradigm** - ArkUI supports languages that are similar to those for web development, such as HTML and CSS. You can use them to describe the page layout and style, and use JavaScript \(conforming to the ECMAScript specification\) for page behavior. With ArkUI, you can configure the UI in an intuitive manner, eliminating the need to code for UI state switching. +## Overall Architecture +ArkUI with the JavaScript-based web-like development paradigm consists of the following layers: application layer, frontend framework layer, engine layer, and porting layer. -## Overall Structure - ArkUI with the JavaScript-based web-like development paradigm consists of the following layers: application layer, frontend framework layer, engine layer, and porting layer. +![en-us_image_0000001223127696](figures/en-us_image_0000001223127696.png) -![](figures/zh-cn_image_0000001077953992.png) +- Application -- **Application** + Contains applications with FAs you developed. The FA application in this document refers to the application with FAs developed using JavaScript. - Contains applications with FAs you developed. The FA application in this document refers to the application with FAs developed using JavaScript. +- Framework -- **Framework** + Parses UI pages and provides the Model-View-ViewModel (MVVM), page routing, custom components and more for front end development. - Parses UI pages and provides the Model-View-ViewModel \(MVVM\), page routing, custom components and more for front end development. +- Engine -- **Engine** - - Accomplishes animation parsing, Document Object Model \(DOM\) building, layout computing, rendering command building and drawing, and event management. - -- **Porting Layer** - - Abstracts the platform layer to provide abstract interfaces to connect to the platform. For example, event interconnection, rendering pipeline interconnection, and lifecycle interconnection. + Accomplishes animation parsing, Document Object Model (DOM) building, layout computing, rendering command building and drawing, and event management. +- Porting Layer + Abstracts the platform layer to provide abstract interfaces to connect to the platform. For example, event interconnection, rendering pipeline interconnection, and lifecycle interconnection. diff --git a/en/application-dev/ui/ui-ts-building-category-grid-layout.md b/en/application-dev/ui/ui-ts-building-category-grid-layout.md index 534482f62ed38279b90570e1e32bcba6b1849173..9a2e8febf63fcff3a00531ea4d31a348b1523e75 100644 --- a/en/application-dev/ui/ui-ts-building-category-grid-layout.md +++ b/en/application-dev/ui/ui-ts-building-category-grid-layout.md @@ -1,371 +1,373 @@ -# Building a Food Category Grid Layout +# Building a Food Category Grid Layout -The diet application allows food on the home page to display in list or grid mode. You can implement switching between food categories through tabs in grid mode. - -1. Import the **Category** enumeration type to the **FoodCategoryList** page. - - ``` - import { Category, FoodData } from '../model/FoodData' - ``` - -2. Create the **FoodCategoryList** and **FoodCategory** components. The **FoodCategoryList** component is used as the entry component of the new page, and the **initializeOnStartup** method is invoked in the entry component. - - ``` - @Component - struct FoodList { - private foodItems: FoodData[] - build() { - ...... - } - } - - @Component - struct FoodCategory { - private foodItems: FoodData[] - build() { - ...... - } - } - - @Entry - @Component - struct FoodCategoryList { - private foodItems: FoodData[] = initializeOnStartup() - build() { - ...... - } - } - ``` - -3. Create the **showList** member variable in the **FoodCategoryList** component to control the rendering switchover between the list layout and grid layout. The conditional rendering statement **if...else...** is required. - - ``` - @Entry - @Component - struct FoodCategoryList { - private foodItems: FoodData[] = initializeOnStartup() - private showList: boolean = false - - build() { - Stack() { - if (this.showList) { - FoodList({ foodItems: this.foodItems }) - } else { - FoodCategory({ foodItems: this.foodItems }) - } - } - } - } - ``` - -4. In the upper right corner of the page, create an icon for switching between the list and grid layouts. Set the stack alignment mode to **TopEnd**, top-bottom alignment. Create an image component, and set the click event, that is, negation of **showList**. - - ``` - @Entry - @Component - struct FoodCategoryList { - private foodItems: FoodData[] = initializeOnStartup() - private showList: boolean = false - - build() { - Stack({ alignContent: Alignment.TopEnd }) { - if (this.showList) { - FoodList({ foodItems: this.foodItems }) - } else { - FoodCategory({ foodItems: this.foodItems }) - } - Image($r('app.media.Switch')) - .height(24) - .width(24) - .margin({ top: 15, right: 10 }) - .onClick(() => { - this.showList = !this.showList - }) - }.height('100%') - } - } - ``` - -5. Add the **@State** decorator. After you click the switch tab in the upper right corner, the page does not change. This is because the **showList** does not have state data and its change does not trigger the page refresh. You need to add the **@State** decorator to make it state data. The change of the **@State** decorator will cause re-rendering of the component where the decorator is located. - - ``` - @Entry - @Component - struct FoodCategoryList { - private foodItems: FoodData[] = initializeOnStartup() - @State private showList: boolean = false - - build() { - Stack({ alignContent: Alignment.TopEnd }) { - if (this.showList) { - FoodList({ foodItems: this.foodItems }) - } else { - FoodCategory({ foodItems: this.foodItems }) - } - Image($r('app.media.Switch')) - .height(24) - .width(24) - .margin({ top: 15, right: 10 }) - .onClick(() => { - this.showList = !this.showList - }) - }.height('100%') - } - } - - ``` - - When you click the switch icon, the **FoodList** component is displayed. When you click the switch icon again, the **FoodList** component is hidden. - - ![](figures/video_2021-10-22_103503.gif) - -6. Create a tab to display all food categories \(**All**\). Create the **** component and its child component **TabContent** in the **FoodCategory** component, and set **tabBar** to **All**. Set the width of the **TabBars** to 280 and the layout mode to **Scrollable**. This means that the **TabBars** can be scrolled when the total length exceeds 280. The **** component is a container component that allows users to switch between content views through tabs. Each tab page corresponds to a **TabContent**. - - ``` - @Component - struct FoodCategory { - private foodItems: FoodData[] - build() { - Stack() { - Tabs() { - TabContent() {}.tabBar('All') - } - .barWidth(280) - .barMode(BarMode.Scrollable) - } - } - } - ``` - - ![](figures/en-us_image_0000001204538065.png) - -7. Create the **FoodGrid** component to function as a child component of the **TabContent** component. - ``` - @Component - struct FoodGrid { - private foodItems: FoodData[] - build() {} - } - - @Component - struct FoodCategory { - private foodItems: FoodData[] - build() { - Stack() { - Tabs() { - TabContent() { - FoodGrid({ foodItems: this.foodItems }) - }.tabBar('All') - } - .barWidth(280) - .barMode(BarMode.Scrollable) - } - } - } - ``` - -8. Implement a 2 x 6 grid layout \(12 food data resources in total\). Create a **Grid** component, and set **columnsTemplate** to **\('1fr 1fr'\)**, **rowsTemplate** to **\('1fr 1fr 1fr 1fr 1fr 1fr'\)**, and both **rowsGap** and **columnsGap** to **8**. Create a **Scroll** component so that it can be slid. - - ``` - @Component - struct FoodGrid { - private foodItems: FoodData[] - build() { - Scroll() { - Grid() { - ForEach(this.foodItems, (item: FoodData) => { - GridItem() {} - }, (item: FoodData) => item.id.toString()) - } - .rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr') - .columnsTemplate('1fr 1fr') - .columnsGap(8) - .rowsGap(8) - } - .scrollBar(BarState.Off) - .padding({left: 16, right: 16}) - } - } - ``` - -9. Create a **FoodGridItem** component to display the food image, name, and calories and implement the UI layout. The **FoodGridItem** component is a child component of the **GridItem** component. The height of each **FoodGridItem** is **184**, and the line spacing is **8**. The total height of the **Grid** component is calculated as follows: \(184 + 8\) x 6 – 8 = 1144. - - ``` - @Component - struct FoodGridItem { - private foodItem: FoodData - build() { - Column() { - Row() { - Image(this.foodItem.image) - .objectFit(ImageFit.Contain) - .height(152) - .width('100%') - }.backgroundColor('#FFf1f3f5') - Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { - Text(this.foodItem.name) - .fontSize(14) - .flexGrow(1) - .padding({ left: 8 }) - Text(this.foodItem.calories + 'kcal') - .fontSize(14) - .margin({ right: 6 }) - } - .height(32) - .width('100%') - .backgroundColor('#FFe5e5e5') - } - .height(184) - .width('100%') - } - } - - @Component - struct FoodGrid { - private foodItems: FoodData[] - build() { - Scroll() { - Grid() { - ForEach(this.foodItems, (item: FoodData) => { - GridItem() { - FoodGridItem({foodItem: item}) - } - }, (item: FoodData) => item.id.toString()) - } - .rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr') - .columnsTemplate('1fr 1fr') - .columnsGap(8) - .rowsGap(8) - .height(1144) - } - .scrollBar(BarState.Off) - .padding({ left: 16, right: 16 }) - } - } - ``` - - ![](figures/video_2021-10-21_105602.gif) - -10. Create the **Category.Vegetable**, **Category.Fruit**, **Category.Nut**, **Category.SeaFood**, and **Category.Dessert** tabs. - - ``` - @Component - struct FoodCategory { - private foodItems: FoodData[] - build() { - Stack() { - Tabs() { - TabContent() { - FoodGrid({ foodItems: this.foodItems }) - }.tabBar('All') - - TabContent() { - FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Vegetable)) }) - }.tabBar('Vegetable') - - TabContent() { - FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Fruit)) }) - }.tabBar('Fruit') - - TabContent() { - FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Nut)) }) - }.tabBar('Nut') - - TabContent() { - FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Seafood)) }) - }.tabBar('Seafood') - - TabContent() { - FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Dessert)) }) - }.tabBar('Dessert') - } - .barWidth(280) - .barMode(BarMode.Scrollable) - } - } - } - ``` - -11. Set the number of rows and height of grids for different food categories. Because the number of foods varies according to the category, the **''1fr 1fr 1fr 1fr 1fr 1fr '** constant cannot be used to set the number of rows to 6. - - Create member variables **gridRowTemplate** and **HeightValue**, and set the number of grid rows and height by using these member variables. - - ``` - @Component - struct FoodGrid { - private foodItems: FoodData[] - private gridRowTemplate : string = '' - private heightValue: number - build() { - Scroll() { - Grid() { - ForEach(this.foodItems, (item: FoodData) => { - GridItem() { - FoodGridItem({foodItem: item}) - } - }, (item: FoodData) => item.id.toString()) - } - .rowsTemplate(this.gridRowTemplate) - .columnsTemplate('1fr 1fr') - .columnsGap(8) - .rowsGap(8) - .height(this.heightValue) - } - .scrollBar(BarState.Off) - .padding({left: 16, right: 16}) - } - } - ``` - - Invoke the **aboutToAppear** API to calculate the number of rows \(**gridRowTemplate**\) and height \(**heightValue**\). - - ``` - aboutToAppear() { - var rows = Math.round(this.foodItems.length / 2); - this.gridRowTemplate = '1fr '.repeat(rows); - this.heightValue = rows * 192 - 8; - } - ``` - - The custom component provides two lifecycle callbacks: **aboutToAppear** and **aboutToDisappear**. **aboutToAppear** is executed after the custom component is created and before the **build** method of the custom component is executed. **aboutToDisappear** is executed when the custom component is deinitialized. - - ![](figures/en-us_image_0000001215113569.png) - - ``` - @Component - struct FoodGrid { - private foodItems: FoodData[] - private gridRowTemplate : string = '' - private heightValue: number - - aboutToAppear() { - var rows = Math.round(this.foodItems.length / 2); - this.gridRowTemplate = '1fr '.repeat(rows); - this.heightValue = rows * 192 - 8; - } - - build() { - Scroll() { - Grid() { - ForEach(this.foodItems, (item: FoodData) => { - GridItem() { - FoodGridItem({foodItem: item}) - } - }, (item: FoodData) => item.id.toString()) - } - .rowsTemplate(this.gridRowTemplate) - .columnsTemplate('1fr 1fr') - .columnsGap(8) - .rowsGap(8) - .height(this.heightValue) - } - .scrollBar(BarState.Off) - .padding({left: 16, right: 16}) - } - } - ``` - - ![](figures/video_2021-10-21_105956.gif) +The diet application allows food on the home page to display in list or grid mode. You can implement switching between food categories through tabs in grid mode. +1. Import the Category enumeration type to the FoodCategoryList page. + + ``` + import { Category, FoodData } from '../model/FoodData' + ``` + +2. Create the FoodCategoryList and FoodCategory components. The FoodCategoryList component is used as the entry component of the new page, and the initializeOnStartup method is invoked in the entry component. + + ``` + @Component + struct FoodList { + private foodItems: FoodData[] + build() { + ...... + } + } + + @Component + struct FoodCategory { + private foodItems: FoodData[] + build() { + ...... + } + } + + @Entry + @Component + struct FoodCategoryList { + private foodItems: FoodData[] = initializeOnStartup() + build() { + ...... + } + } + ``` + +3. Create the showList member variable in the FoodCategoryList component to control the rendering switchover between the list layout and grid layout. The conditional rendering statement if...else... is required. + + ``` + @Entry + @Component + struct FoodCategoryList { + private foodItems: FoodData[] = initializeOnStartup() + private showList: boolean = false + + build() { + Stack() { + if (this.showList) { + FoodList({ foodItems: this.foodItems }) + } else { + FoodCategory({ foodItems: this.foodItems }) + } + } + } + } + ``` + +4. In the upper right corner of the page, create an icon for switching between the list and grid layouts. Set the stack alignment mode to TopEnd, top-bottom alignment. Create an image component, and set the click event, that is, negation of showList. + + ``` + @Entry + @Component + struct FoodCategoryList { + private foodItems: FoodData[] = initializeOnStartup() + private showList: boolean = false + + build() { + Stack({ alignContent: Alignment.TopEnd }) { + if (this.showList) { + FoodList({ foodItems: this.foodItems }) + } else { + FoodCategory({ foodItems: this.foodItems }) + } + Image($r('app.media.Switch')) + .height(24) + .width(24) + .margin({ top: 15, right: 10 }) + .onClick(() => { + this.showList = !this.showList + }) + }.height('100%') + } + } + ``` + +5. Add the @State decorator. After you click the switch tab in the upper right corner, the page does not change. This is because the showList does not have state data and its change does not trigger the page refresh. You need to add the @State decorator to make it state data. The change of the @State decorator will cause re-rendering of the component where the decorator is located. + + ``` + @Entry + @Component + struct FoodCategoryList { + private foodItems: FoodData[] = initializeOnStartup() + @State private showList: boolean = false + + build() { + Stack({ alignContent: Alignment.TopEnd }) { + if (this.showList) { + FoodList({ foodItems: this.foodItems }) + } else { + FoodCategory({ foodItems: this.foodItems }) + } + Image($r('app.media.Switch')) + .height(24) + .width(24) + .margin({ top: 15, right: 10 }) + .onClick(() => { + this.showList = !this.showList + }) + }.height('100%') + } + } + + ``` + + When you click the switch icon, the FoodList component is displayed. When you click the switch icon again, the FoodList component is hidden. + + ![en-us_image_0000001222807800](figures/en-us_image_0000001222807800.gif) + +6. Create a tab to display all food categories (All). Create the component and its child component TabContent in the FoodCategory component, and set tabBar to All. Set the width of the TabBars to 280 and the layout mode to Scrollable. This means that the TabBars can be scrolled when the total length exceeds 280. The component is a container component that allows users to switch between content views through tabs. Each tab page corresponds to a TabContent. + + ``` + @Component + struct FoodCategory { + private foodItems: FoodData[] + build() { + Stack() { + Tabs() { + TabContent() {}.tabBar('All') + } + .barWidth(280) + .barMode(BarMode.Scrollable) + } + } + } + ``` + + ![en-us_image_0000001267647881](figures/en-us_image_0000001267647881.png) + +7. Create the FoodGrid component to function as a child component of the TabContent component. + + ``` + @Component + struct FoodGrid { + private foodItems: FoodData[] + build() {} + } + + @Component + struct FoodCategory { + private foodItems: FoodData[] + build() { + Stack() { + Tabs() { + TabContent() { + FoodGrid({ foodItems: this.foodItems }) + }.tabBar('All') + } + .barWidth(280) + .barMode(BarMode.Scrollable) + } + } + } + ``` + +8. Implement a 2 x 6 grid layout (12 food data resources in total). Create a Grid component, and set columnsTemplate to ('1fr 1fr'), rowsTemplate to ('1fr 1fr 1fr 1fr 1fr 1fr'), and both rowsGap and columnsGap to 8. Create a Scroll component so that it can be slid. + + ``` + @Component + struct FoodGrid { + private foodItems: FoodData[] + build() { + Scroll() { + Grid() { + ForEach(this.foodItems, (item: FoodData) => { + GridItem() {} + }, (item: FoodData) => item.id.toString()) + } + .rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr') + .columnsTemplate('1fr 1fr') + .columnsGap(8) + .rowsGap(8) + } + .scrollBar(BarState.Off) + .padding({left: 16, right: 16}) + } + } + ``` + +9. Create a FoodGridItem component to display the food image, name, and calories and implement the UI layout. The FoodGridItem component is a child component of the GridItem component. The height of each FoodGridItem is 184, and the line spacing is 8. The total height of the Grid component is calculated as follows: (184 + 8) x 6 – 8 = 1144. + + ``` + @Component + struct FoodGridItem { + private foodItem: FoodData + build() { + Column() { + Row() { + Image(this.foodItem.image) + .objectFit(ImageFit.Contain) + .height(152) + .width('100%') + }.backgroundColor('#FFf1f3f5') + Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { + Text(this.foodItem.name) + .fontSize(14) + .flexGrow(1) + .padding({ left: 8 }) + Text(this.foodItem.calories + 'kcal') + .fontSize(14) + .margin({ right: 6 }) + } + .height(32) + .width('100%') + .backgroundColor('#FFe5e5e5') + } + .height(184) + .width('100%') + } + } + + @Component + struct FoodGrid { + private foodItems: FoodData[] + build() { + Scroll() { + Grid() { + ForEach(this.foodItems, (item: FoodData) => { + GridItem() { + FoodGridItem({foodItem: item}) + } + }, (item: FoodData) => item.id.toString()) + } + .rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr') + .columnsTemplate('1fr 1fr') + .columnsGap(8) + .rowsGap(8) + .height(1144) + } + .scrollBar(BarState.Off) + .padding({ left: 16, right: 16 }) + } + } + ``` + + ![en-us_image_0000001223287708](figures/en-us_image_0000001223287708.gif) + +10. Create the Category.Vegetable, Category.Fruit, Category.Nut, Category.SeaFood, and Category.Dessert tabs. + + ``` + @Component + struct FoodCategory { + private foodItems: FoodData[] + build() { + Stack() { + Tabs() { + TabContent() { + FoodGrid({ foodItems: this.foodItems }) + }.tabBar('All') + + TabContent() { + FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Vegetable)) }) + }.tabBar('Vegetable') + + TabContent() { + FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Fruit)) }) + }.tabBar('Fruit') + + TabContent() { + FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Nut)) }) + }.tabBar('Nut') + + TabContent() { + FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Seafood)) }) + }.tabBar('Seafood') + + TabContent() { + FoodGrid({ foodItems: this.foodItems.filter(item => (item.category === Category.Dessert)) }) + }.tabBar('Dessert') + } + .barWidth(280) + .barMode(BarMode.Scrollable) + } + } + } + ``` + +11. Set the number of rows and height of grids for different food categories. Because the number of foods varies according to the category, the ''1fr 1fr 1fr 1fr 1fr 1fr ' constant cannot be used to set the number of rows to 6. + Create member variables gridRowTemplate and HeightValue, and set the number of grid rows and height by using these member variables. + + + ``` + @Component + struct FoodGrid { + private foodItems: FoodData[] + private gridRowTemplate : string = '' + private heightValue: number + build() { + Scroll() { + Grid() { + ForEach(this.foodItems, (item: FoodData) => { + GridItem() { + FoodGridItem({foodItem: item}) + } + }, (item: FoodData) => item.id.toString()) + } + .rowsTemplate(this.gridRowTemplate) + .columnsTemplate('1fr 1fr') + .columnsGap(8) + .rowsGap(8) + .height(this.heightValue) + } + .scrollBar(BarState.Off) + .padding({left: 16, right: 16}) + } + } + ``` + + Invoke the aboutToAppear API to calculate the number of rows (gridRowTemplate) and height (heightValue). + + + ``` + aboutToAppear() { + var rows = Math.round(this.foodItems.length / 2); + this.gridRowTemplate = '1fr '.repeat(rows); + this.heightValue = rows * 192 - 8; + } + ``` + + The custom component provides two lifecycle callbacks: aboutToAppear and aboutToDisappear. aboutToAppear is executed after the custom component is created and before the build method of the custom component is executed. aboutToDisappear is executed when the custom component is deinitialized. + + ![en-us_image_0000001267647885](figures/en-us_image_0000001267647885.png) + + + ``` + @Component + struct FoodGrid { + private foodItems: FoodData[] + private gridRowTemplate : string = '' + private heightValue: number + + aboutToAppear() { + var rows = Math.round(this.foodItems.length / 2); + this.gridRowTemplate = '1fr '.repeat(rows); + this.heightValue = rows * 192 - 8; + } + + build() { + Scroll() { + Grid() { + ForEach(this.foodItems, (item: FoodData) => { + GridItem() { + FoodGridItem({foodItem: item}) + } + }, (item: FoodData) => item.id.toString()) + } + .rowsTemplate(this.gridRowTemplate) + .columnsTemplate('1fr 1fr') + .columnsGap(8) + .rowsGap(8) + .height(this.heightValue) + } + .scrollBar(BarState.Off) + .padding({left: 16, right: 16}) + } + } + ``` + + ![en-us_image_0000001267887869](figures/en-us_image_0000001267887869.gif) diff --git a/en/application-dev/ui/ui-ts-building-category-list-layout.md b/en/application-dev/ui/ui-ts-building-category-list-layout.md index 7aff7b7bbffbc5386d82886a410b0cdd3715471d..78c21c0a62c8c3d3d450867052c35168b62cbbc0 100644 --- a/en/application-dev/ui/ui-ts-building-category-list-layout.md +++ b/en/application-dev/ui/ui-ts-building-category-list-layout.md @@ -1,259 +1,261 @@ -# Building a Food Category List Layout +# Building a Food Category List Layout -Use the **List** component and **ForEach** loop to build the food category list layout. -1. Create a page file named **FoodCategoryList.ets** in the **pages** directory, rename the **index.ets** file **FoodDetail.ets**, and add the renamed file to the **"pages"** tag in the **config.json** file. The first page under the tag is the home page. +Use the List component and ForEach loop to build the food category list layout. - ``` - "js": [ - { - "pages": [ - "pages/FoodCategoryList", - "pages/FoodDetail" - ], - ] - ``` -2. Create a **List** component named **FoodList** as the page entry point. Then, add a **ListItem** component named **FoodListItem** as its child component. The **List** component is used to display data of the same type. Its child component **** is used to display specific items in the list. +1. Create a page file named FoodCategoryList.ets in the pages directory, rename the index.ets file FoodDetail.ets, and add the renamed file to the "pages" tag in the config.json file. The first page under the tag is the home page. + + ``` + "js": [ + { + "pages": [ + "pages/FoodCategoryList", + "pages/FoodDetail" + ], + ] + ``` - ``` - @Component - struct FoodListItem { - build() {} - } - - @Entry - @Component - struct FoodList { - build() { - List() { - ListItem() { - FoodListItem() - } - } - } - } - ``` +2. Create a List component named FoodList as the page entry point. Then, add a ListItem component named FoodListItem as its child component. The List component is used to display data of the same type. Its child component is used to display specific items in the list. + + ``` + @Component + struct FoodListItem { + build() {} + } + + @Entry + @Component + struct FoodList { + build() { + List() { + ListItem() { + FoodListItem() + } + } + } + } + ``` -3. Import the **FoodData** class and **initializeOnStartup** method. +3. Import the FoodData class and initializeOnStartup method. + + ``` + import { FoodData } from '../model/FoodData' + import { initializeOnStartup } from '../model/FoodDataModels' + ``` - ``` - import { FoodData } from '../model/FoodData' - import { initializeOnStartup } from '../model/FoodDataModels' - ``` +4. Configure the FoodList and FoodListItem components to pass values. Create a member variable named foodItems of the FoodData[] type in the FoodList component and invoke the initializeOnStartup method to assign a value to the variable. Create a member variable foodItem of the FoodData type in the FoodListItem component. Pass the foodItems[0] of the first element in the parent foodItems array as a parameter to FoodListItem. + + ``` + import { FoodData } from '../model/FoodData' + import { initializeOnStartup } from '../model/FoodDataModels' + + @Component + struct FoodListItem { + private foodItem: FoodData + build() {} + } + + @Entry + @Component + struct FoodList { + private foodItems: FoodData[] = initializeOnStartup() + build() { + List() { + ListItem() { + FoodListItem({ foodItem: this.foodItems[0] }) + } + } + } + } + ``` -4. Configure the **FoodList** and **FoodListItem** components to pass values. Create a member variable named **foodItems** of the **FoodData\[\]** type in the **FoodList** component and invoke the **initializeOnStartup** method to assign a value to the variable. Create a member variable **foodItem** of the **FoodData** type in the **FoodListItem** component. Pass the **foodItems\[0\]** of the first element in the parent **foodItems** array as a parameter to **FoodListItem**. +5. Declare the UI layout of the FoodListItem child component. Create a Flex component, including the food image thumbnail, food name, and calories in the food. + + ``` + import { FoodData } from '../model/FoodData' + import { initializeOnStartup } from '../model/FoodDataModels' + + @Component + struct FoodListItem { + private foodItem: FoodData + build() { + Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { + Image(this.foodItem.image) + .objectFit(ImageFit.Contain) + .height(40) + .width(40) + .backgroundColor('#FFf1f3f5') + .margin({ right: 16 }) + Text(this.foodItem.name) + .fontSize(14) + .flexGrow(1) + Text(this.foodItem.calories + ' kcal') + .fontSize(14) + } + .height(64) + .margin({ right: 24, left:32 }) + } + } + + @Entry + @Component + struct FoodList { + private foodItems: FoodData[] = initializeOnStartup() + build() { + List() { + ListItem() { + FoodListItem({ foodItem: this.foodItems[0] }) + } + } + } + } + ``` - ``` - import { FoodData } from '../model/FoodData' - import { initializeOnStartup } from '../model/FoodDataModels' - - @Component - struct FoodListItem { - private foodItem: FoodData - build() {} - } - - @Entry - @Component - struct FoodList { - private foodItems: FoodData[] = initializeOnStartup() - build() { - List() { - ListItem() { - FoodListItem({ foodItem: this.foodItems[0] }) - } - } - } - } - ``` + ![en-us_image_0000001267887833](figures/en-us_image_0000001267887833.png) -5. Declare the UI layout of the **FoodListItem** child component. Create a **Flex** component, including the food image thumbnail, food name, and calories in the food. +6. Create two FoodListItem objects. Create two FoodListItem objects in the List component and pass the first element this.foodItems[0] and the second element foodItem: this.foodItems[1] to the FoodListItem. + + ``` + import { FoodData } from '../model/FoodData' + import { initializeOnStartup } from '../model/FoodDataModels' + + @Component + struct FoodListItem { + private foodItem: FoodData + build() { + Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { + Image(this.foodItem.image) + .objectFit(ImageFit.Contain) + .height(40) + .width(40) + .backgroundColor('#FFf1f3f5') + .margin({ right: 16 }) + Text(this.foodItem.name) + .fontSize(14) + .flexGrow(1) + Text(this.foodItem.calories + ' kcal') + .fontSize(14) + } + .height(64) + .margin({ right: 24, left:32 }) + } + } + + @Entry + @Component + struct FoodList { + private foodItems: FoodData[] = initializeOnStartup() + build() { + List() { + ListItem() { + FoodListItem({ foodItem: this.foodItems[0] }) + } + ListItem() { + FoodListItem({ foodItem: this.foodItems[1] }) + } + } + } + } + ``` - ``` - import { FoodData } from '../model/FoodData' - import { initializeOnStartup } from '../model/FoodDataModels' - - @Component - struct FoodListItem { - private foodItem: FoodData - build() { - Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { - Image(this.foodItem.image) - .objectFit(ImageFit.Contain) - .height(40) - .width(40) - .backgroundColor('#FFf1f3f5') - .margin({ right: 16 }) - Text(this.foodItem.name) - .fontSize(14) - .flexGrow(1) - Text(this.foodItem.calories + ' kcal') - .fontSize(14) - } - .height(64) - .margin({ right: 24, left:32 }) - } - } - - @Entry - @Component - struct FoodList { - private foodItems: FoodData[] = initializeOnStartup() - build() { - List() { - ListItem() { - FoodListItem({ foodItem: this.foodItems[0] }) - } - } - } - } - ``` + ![en-us_image_0000001267767849](figures/en-us_image_0000001267767849.png) - ![](figures/en-us_image_0000001204776353.png) +7. Import ForEach so that you do not need to create FoodListItem objects one by one. + + ``` + ForEach( + arr: any[], // Array to be iterated + itemGenerator: (item: any) => void, // child component generator + keyGenerator?: (item: any) => string // (optional) Unique key generator, which is recommended. + ) + ``` -6. Create two **FoodListItem** objects. Create two **FoodListItem** objects in the **List** component and pass the first element **this.foodItems\[0\]** and the second element **foodItem: this.foodItems\[1\]** to the **FoodListItem**. + The ForEach group has three parameters. The first parameter is the array to be traversed, the second parameter is the lambda function for generating child components, and the third parameter is the key value generator. The third parameter is optional. Yet, for performance reasons, it is strongly recommended that you provide it. keyGenerator enables the development framework to better recognize array changes without having to rebuild all nodes after item changes. - ``` - import { FoodData } from '../model/FoodData' - import { initializeOnStartup } from '../model/FoodDataModels' - - @Component - struct FoodListItem { - private foodItem: FoodData - build() { - Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { - Image(this.foodItem.image) - .objectFit(ImageFit.Contain) - .height(40) - .width(40) - .backgroundColor('#FFf1f3f5') - .margin({ right: 16 }) - Text(this.foodItem.name) - .fontSize(14) - .flexGrow(1) - Text(this.foodItem.calories + ' kcal') - .fontSize(14) - } - .height(64) - .margin({ right: 24, left:32 }) - } - } - - @Entry - @Component - struct FoodList { - private foodItems: FoodData[] = initializeOnStartup() - build() { - List() { - ListItem() { - FoodListItem({ foodItem: this.foodItems[0] }) - } - ListItem() { - FoodListItem({ foodItem: this.foodItems[1] }) - } - } - } - } - ``` + Traverse the foodItems array to cyclically create the ListItem component. Pass each item in foodItems as a parameter to the FoodListItem component. - ![](figures/en-us_image_0000001204537865.png) + + ``` + ForEach(this.foodItems, item => { + ListItem() { + FoodListItem({ foodItem: item }) + } + }, item => item.id.toString()) + ``` -7. Import **ForEach** so that you do not need to create **FoodListItem** objects one by one. + The code is as follows: - ``` - ForEach( - arr: any[], // Array to be iterated - itemGenerator: (item: any) => void, // child component generator - keyGenerator?: (item: any) => string // (optional) Unique key generator, which is recommended. - ) - ``` - - The **ForEach** group has three parameters. The first parameter is the array to be traversed, the second parameter is the lambda function for generating child components, and the third parameter is the key value generator. The third parameter is optional. Yet, for performance reasons, it is strongly recommended that you provide it. **keyGenerator** enables the development framework to better recognize array changes without having to rebuild all nodes after item changes. - - Traverse the **foodItems** array to cyclically create the **ListItem** component. Pass each item in **foodItems** as a parameter to the **FoodListItem** component. - - ``` - ForEach(this.foodItems, item => { - ListItem() { - FoodListItem({ foodItem: item }) - } - }, item => item.id.toString()) - ``` - - The code is as follows: - - ``` - import { FoodData } from '../model/FoodData' - import { initializeOnStartup } from '../model/FoodDataModels' - - @Component - struct FoodListItem { - private foodItem: FoodData - build() { - Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { - Image(this.foodItem.image) - .objectFit(ImageFit.Contain) - .height(40) - .width(40) - .backgroundColor('#FFf1f3f5') - .margin({ right: 16 }) - Text(this.foodItem.name) - .fontSize(14) - .flexGrow(1) - Text(this.foodItem.calories + ' kcal') - .fontSize(14) - } - .height(64) - .margin({ right: 24, left:32 }) - } - } - - @Entry - @Component - struct FoodList { - private foodItems: FoodData[] = initializeOnStartup() - build() { - List() { - ForEach(this.foodItems, item => { - ListItem() { - FoodListItem({ foodItem: item }) - } - }, item => item.id.toString()) - } - } - } - ``` - -8. Add a title for the **FoodList**. - - ``` - @Entry - @Component - struct FoodList { - private foodItems: FoodData[] = initializeOnStartup() - build() { - Column() { - Flex({justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center}) { - Text('Food List') - .fontSize(20) - .margin({ left:20 }) - } - .height('7%') - .backgroundColor('#FFf1f3f5') - List() { - ForEach(this.foodItems, item => { - ListItem() { - FoodListItem({ foodItem: item }) - } - }, item => item.id.toString()) - } - .height('93%') - } - } - } - ``` - - ![](figures/en-us_image_0000001169678922.png) + + ``` + import { FoodData } from '../model/FoodData' + import { initializeOnStartup } from '../model/FoodDataModels' + + @Component + struct FoodListItem { + private foodItem: FoodData + build() { + Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { + Image(this.foodItem.image) + .objectFit(ImageFit.Contain) + .height(40) + .width(40) + .backgroundColor('#FFf1f3f5') + .margin({ right: 16 }) + Text(this.foodItem.name) + .fontSize(14) + .flexGrow(1) + Text(this.foodItem.calories + ' kcal') + .fontSize(14) + } + .height(64) + .margin({ right: 24, left:32 }) + } + } + + @Entry + @Component + struct FoodList { + private foodItems: FoodData[] = initializeOnStartup() + build() { + List() { + ForEach(this.foodItems, item => { + ListItem() { + FoodListItem({ foodItem: item }) + } + }, item => item.id.toString()) + } + } + } + ``` +8. Add a title for the FoodList. + + ``` + @Entry + @Component + struct FoodList { + private foodItems: FoodData[] = initializeOnStartup() + build() { + Column() { + Flex({justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center}) { + Text('Food List') + .fontSize(20) + .margin({ left:20 }) + } + .height('7%') + .backgroundColor('#FFf1f3f5') + List() { + ForEach(this.foodItems, item => { + ListItem() { + FoodListItem({ foodItem: item }) + } + }, item => item.id.toString()) + } + .height('93%') + } + } + } + ``` + ![en-us_image_0000001267607877](figures/en-us_image_0000001267607877.png) diff --git a/en/application-dev/ui/ui-ts-building-data-model.md b/en/application-dev/ui/ui-ts-building-data-model.md index 2068f1e12080202c598480f2fedae47462ad4baf..633fb0e94d63dc21ee993a87f768a0df5cd299ff 100644 --- a/en/application-dev/ui/ui-ts-building-data-model.md +++ b/en/application-dev/ui/ui-ts-building-data-model.md @@ -1,99 +1,99 @@ -# Building a Food Data Model +# Building a Food Data Model -On the created page, we use various items to describe food, such as food names, calories, proteins, fats, carbohydrates, and vitamin C. This form of coding is impractical in actual development. Therefore, you need to create food data models to store and manage data in a unified manner. - -![](figures/en-us_image_0000001215433095.png) - -1. Create a folder named **model** and create a file named **FoodData.ets** therein. - - ![](figures/en-us_image_0000001195119619.png) - -2. Define a food data storage model, **FoodData**, and an enum variable, **Category**. The **FoodData** class contains the food ID, name, category, image, calories, protein, fat, carbohydrates, and vitamin C attributes. - - The eTS programming language is an extension of the TS language and also supports the TS syntax. - - ``` - enum Category { - Fruit, - Vegetable, - Nut, - Seafood, - Dessert - } - - let NextId = 0; - class FoodData { - id: string; - name: string; - image: Resource; - category: Category; - calories: number; - protein: number; - fat: number; - carbohydrates: number; - vitaminC: number; - - constructor(name: string, image: Resource, category: Category, calories: number, protein: number, fat: number, carbohydrates: number, vitaminC: number) { - this.id = `${ NextId++ }`; - this.name = name; - this.image = image; - this.category = category; - this.calories = calories; - this.protein = protein; - this.fat = fat; - this.carbohydrates = carbohydrates; - this.vitaminC = vitaminC; - } - } - ``` -3. Store food image resources in the **resources** \> **phone** \> **media** directory. Use food names as the image names. - - ![](figures/en-us_image_0000001195117633.png) - -4. Create food resource data. Create **FoodDataModels.ets** in the **model** folder and declare a food composition array, **FoodComposition** on the page. - - In this example, 12 pieces of food data are used. You can customize more data resources when needed. Use **LazyForEach** to load data if a large amount of food data is involved. The following nutritional data is sourced from the Internet. - - ``` - const FoodComposition: any[] = [ - { 'name': 'Tomato', 'image': $r('app.media.Tomato'), 'category': Category.Vegetable, 'calories': 17, 'protein': 0.9, 'fat': 0.2, 'carbohydrates': 3.9, 'vitaminC': 17.8 }, - { 'name': 'Walnut', 'image': $r('app.media.Walnut'), 'category': Category.Nut, 'calories': 654 , 'protein': 15, 'fat': 65, 'carbohydrates': 14, 'vitaminC': 1.3 }, - { 'name': 'Cucumber', 'image': $r('app.media.Cucumber'), 'category': Category.Vegetable, 'calories': 30, 'protein': 3, 'fat': 0, 'carbohydrates': 1.9, 'vitaminC': 2.1 }, - { 'name': 'Blueberry', 'image': $r('app.media.Blueberry'), 'category': Category.Fruit, 'calories': 57, 'protein': 0.7, 'fat': 0.3, 'carbohydrates': 14, 'vitaminC': 9.7 }, - { 'name': 'Crab', 'image': $r('app.media.Crab'), 'category': Category.Seafood, 'calories': 97, 'protein': 19, 'fat': 1.5, 'carbohydrates': 0, 'vitaminC': 7.6 }, - { 'name': 'IceCream', 'image': $r('app.media.IceCream'), 'category': Category.Dessert, 'calories': 207, 'protein': 3.5, 'fat': 11, 'carbohydrates': 24, 'vitaminC': 0.6 }, - { 'name': 'Onion', 'image': $r('app.media.Onion'), 'category': Category.Vegetable, 'calories': 39, 'protein': 1.1, 'fat': 0.1, 'carbohydrates': 9, 'vitaminC': 7.4 }, - { 'name': 'Mushroom', 'image': $r('app.media.Mushroom'), 'category': Category.Vegetable, 'calories': 22, 'protein': 3.1, 'fat': 0.3, 'carbohydrates': 3.3, 'vitaminC': 2.1 }, - { 'name': 'Kiwi', 'image': $r('app.media.Kiwi'), 'category': Category.Fruit, 'calories': 60 , 'protein': 1.1, 'fat': 0.5, 'carbohydrates': 15, 'vitaminC': 20.5 }, - { 'name': 'Pitaya', 'image': $r('app.media.Pitaya'), 'category': Category.Fruit, 'calories': 60, 'protein': 1.2, 'fat': 0, 'carbohydrates': 10, 'vitaminC': 60.9 }, - { 'name': 'Avocado', 'image': $r('app.media.Avocado'), 'category': Category.Fruit, 'calories': 160, 'protein': 2, 'fat': 15, 'carbohydrates': 9, 'vitaminC': 10 }, - { 'name': 'Strawberry', 'image': $r('app.media.Strawberry'), 'category': Category.Fruit, 'calories': 32, 'protein': 0.7, 'fat': 0.3, 'carbohydrates': 8, 'vitaminC': 58.8 } - ] - ``` +On the created page, we use various items to describe food, such as food names, calories, proteins, fats, carbohydrates, and vitamin C. This form of coding is impractical in actual development. Therefore, you need to create food data models to store and manage data in a unified manner. -5. Create the **initializeOnStartUp** method to initialize the **FoodData** array. Export the **FoodData** class from **FoodData.ets**, and import **FoodData** and **Category** in **FoodDataModels.ets**. - ``` - // FoodData.ets - export enum Category { +![en-us_image_0000001267767897](figures/en-us_image_0000001267767897.png) + + +1. Create a folder named model and create a file named FoodData.ets therein. + ![en-us_image_0000001223127760](figures/en-us_image_0000001223127760.png) + +2. Define a food data storage model, FoodData, and an enum variable, Category. The FoodData class contains the food ID, name, category, image, calories, protein, fat, carbohydrates, and vitamin C attributes. + The eTS programming language is an extension of the TS language and also supports the TS syntax. + + + ``` + enum Category { + Fruit, + Vegetable, + Nut, + Seafood, + Dessert + } + + let NextId = 0; + class FoodData { + id: string; + name: string; + image: Resource; + category: Category; + calories: number; + protein: number; + fat: number; + carbohydrates: number; + vitaminC: number; + + constructor(name: string, image: Resource, category: Category, calories: number, protein: number, fat: number, carbohydrates: number, vitaminC: number) { + this.id = `${ NextId++ }`; + this.name = name; + this.image = image; + this.category = category; + this.calories = calories; + this.protein = protein; + this.fat = fat; + this.carbohydrates = carbohydrates; + this.vitaminC = vitaminC; + } + } + ``` + +3. Store food image resources in the resources > phone > media directory. Use food names as the image names. + ![en-us_image_0000001222967800](figures/en-us_image_0000001222967800.png) + +4. Create food resource data. Create FoodDataModels.ets in the model folder and declare a food composition array, FoodComposition on the page. + In this example, 12 pieces of food data are used. You can customize more data resources when needed. Use LazyForEach to load data if a large amount of food data is involved. The following nutritional data is sourced from the Internet. + + + ``` + const FoodComposition: any[] = [ + { 'name': 'Tomato', 'image': $r('app.media.Tomato'), 'category': Category.Vegetable, 'calories': 17, 'protein': 0.9, 'fat': 0.2, 'carbohydrates': 3.9, 'vitaminC': 17.8 }, + { 'name': 'Walnut', 'image': $r('app.media.Walnut'), 'category': Category.Nut, 'calories': 654 , 'protein': 15, 'fat': 65, 'carbohydrates': 14, 'vitaminC': 1.3 }, + { 'name': 'Cucumber', 'image': $r('app.media.Cucumber'), 'category': Category.Vegetable, 'calories': 30, 'protein': 3, 'fat': 0, 'carbohydrates': 1.9, 'vitaminC': 2.1 }, + { 'name': 'Blueberry', 'image': $r('app.media.Blueberry'), 'category': Category.Fruit, 'calories': 57, 'protein': 0.7, 'fat': 0.3, 'carbohydrates': 14, 'vitaminC': 9.7 }, + { 'name': 'Crab', 'image': $r('app.media.Crab'), 'category': Category.Seafood, 'calories': 97, 'protein': 19, 'fat': 1.5, 'carbohydrates': 0, 'vitaminC': 7.6 }, + { 'name': 'IceCream', 'image': $r('app.media.IceCream'), 'category': Category.Dessert, 'calories': 207, 'protein': 3.5, 'fat': 11, 'carbohydrates': 24, 'vitaminC': 0.6 }, + { 'name': 'Onion', 'image': $r('app.media.Onion'), 'category': Category.Vegetable, 'calories': 39, 'protein': 1.1, 'fat': 0.1, 'carbohydrates': 9, 'vitaminC': 7.4 }, + { 'name': 'Mushroom', 'image': $r('app.media.Mushroom'), 'category': Category.Vegetable, 'calories': 22, 'protein': 3.1, 'fat': 0.3, 'carbohydrates': 3.3, 'vitaminC': 2.1 }, + { 'name': 'Kiwi', 'image': $r('app.media.Kiwi'), 'category': Category.Fruit, 'calories': 60 , 'protein': 1.1, 'fat': 0.5, 'carbohydrates': 15, 'vitaminC': 20.5 }, + { 'name': 'Pitaya', 'image': $r('app.media.Pitaya'), 'category': Category.Fruit, 'calories': 60, 'protein': 1.2, 'fat': 0, 'carbohydrates': 10, 'vitaminC': 60.9 }, + { 'name': 'Avocado', 'image': $r('app.media.Avocado'), 'category': Category.Fruit, 'calories': 160, 'protein': 2, 'fat': 15, 'carbohydrates': 9, 'vitaminC': 10 }, + { 'name': 'Strawberry', 'image': $r('app.media.Strawberry'), 'category': Category.Fruit, 'calories': 32, 'protein': 0.7, 'fat': 0.3, 'carbohydrates': 8, 'vitaminC': 58.8 } + ] + ``` + +5. Create the initializeOnStartUp method to initialize the FoodData array. Export the FoodData class from FoodData.ets, and import FoodData and Category in FoodDataModels.ets. + + ``` + // FoodData.ets + export enum Category { + ...... + } + export class FoodData { ...... - } - export class FoodData { - ...... - } - // FoodDataModels.ets - import { Category, FoodData } from './FoodData' - - export function initializeOnStartup(): Array { - let FoodDataArray: Array = [] - FoodComposition.forEach(item => { - FoodDataArray.push(new FoodData(item.name, item.image, item.category, item.calories, item.protein, item.fat, item.carbohydrates, item.vitaminC )); - }) - return FoodDataArray; - } - ``` + } + // FoodDataModels.ets + import { Category, FoodData } from './FoodData' + + export function initializeOnStartup(): Array { + let FoodDataArray: Array = [] + FoodComposition.forEach(item => { + FoodDataArray.push(new FoodData(item.name, item.image, item.category, item.calories, item.protein, item.fat, item.carbohydrates, item.vitaminC )); + }) + return FoodDataArray; + } + ``` The data resources for the diet application are now ready. You can continue to create a food category list by loading the data. - diff --git a/en/application-dev/ui/ui-ts-components-web.md b/en/application-dev/ui/ui-ts-components-web.md index 45220f270d672c3466c67be863c24a2f02dc7c77..c1a6363dfd7588d4ad9854539b1d8d54f47ef8c1 100644 --- a/en/application-dev/ui/ui-ts-components-web.md +++ b/en/application-dev/ui/ui-ts-components-web.md @@ -1,10 +1,10 @@ # Web -The **\** component can be used to display web pages. For details, see [Web API](../reference/arkui-ts/ts-basic-components-web.md). +The \ component can be used to display web pages. For details, see [Web API](../reference/arkui-ts/ts-basic-components-web.md). ## Creating a Component -Create a **\** component in the .ets file under **main/ets/MainAbility/pages**. Then, in the created component, use **src** to specify the web page URI to be referenced, and bind a controller to the component to call the component APIs. +Create a \ component in the .ets file under main/ets/MainAbility/pages. Then, in the created component, use src to specify the web page URI to be referenced, and bind a controller to the component to call the component APIs. ``` // xxx.ets @@ -22,7 +22,7 @@ Create a **\** component in the .ets file under **main/ets/MainAbility/page ## Setting Styles and Attributes -When using the **\** component, you need to specify the styles and attributes. The sample code is as follows. +When using the \ component, you need to specify the styles and attributes. The sample code is as follows. ``` // xxx.ets @@ -50,7 +50,7 @@ struct WebComponent { ``` ## Adding Events and Methods -Add the **onProgressChange** event for the **\** component, which is triggered when the loading progress changes and returns the progress value in its callback. Assign the progress value to the **\** component to control the status of the component. When the progress reaches 100%, the **\** component is hidden, and the web page loading is complete. +Add the onProgressChange event for the \ component, which is triggered when the loading progress changes and returns the progress value in its callback. Assign the progress value to the \ component to control the status of the component. When the progress reaches 100%, the \ component is hidden, and the web page loading is complete. ``` // xxx.ets @@ -89,7 +89,7 @@ struct WebComponent { } } ``` -Add the **runJavaScript** method to the **onPageEnd** event. The **onPageEnd** event is triggered when the web page finishes loading. In this case, the **runJavaScript** method can be used to execute JavaScript scripts in the HTML file. In the sample code below, when the web page finishes loading, the **onPageEnd** event is triggered to call the **test** method in the HTML file and print information on the console. +Add the runJavaScript method to the onPageEnd event. The onPageEnd event is triggered when the web page finishes loading. In this case, the runJavaScript method can be used to execute JavaScript scripts in the HTML file. In the sample code below, when the web page finishes loading, the onPageEnd event is triggered to call the test method in the HTML file and print information on the console. ``` // xxx.ets @@ -134,7 +134,7 @@ struct WebComponent { } ``` -Create an HTML file in **main/resources/rawfile**. +Create an HTML file in main/resources/rawfile. ``` @@ -153,7 +153,7 @@ Create an HTML file in **main/resources/rawfile**. ``` ## Scenario Example -In this example, you'll implement a **\** component where videos can be played dynamically. Embed a video resource into an HTML page, and then use the **\** component controller to invoke the **onActive** and **onInactive** methods to activate and pause page rendering, respectively. When the page is hidden, the **\** component stops rendering and the video playback pauses. When the page is displayed, the **\** component is activated and the video playback resumes. +In this example, you'll implement a \ component where videos can be played dynamically. Embed a video resource into an HTML page, and then use the \ component controller to invoke the onActive and onInactive methods to activate and pause page rendering, respectively. When the page is hidden, the \ component stops rendering and the video playback pauses. When the page is displayed, the \ component is activated and the video playback resumes. ``` // xxx.ets diff --git a/en/application-dev/ui/ui-ts-components.md b/en/application-dev/ui/ui-ts-components.md index a72ec12ada141779b6a31af7d978836f0a6ee2e4..c6676800713d25a34656222a9704746c15a13737 100644 --- a/en/application-dev/ui/ui-ts-components.md +++ b/en/application-dev/ui/ui-ts-components.md @@ -1,19 +1,23 @@ -# Getting to Know Components +# Getting to Know Components -Before customizing a component, get to know what the [component and decorator](#section1094392618525) are and initialize the component. Then, [modify the component attributes and constructor parameters](#section19391124065216) to customize a component. -## Components and Decorators +Before customizing a component, get to know what the [component and decorator](#components-and-decorators) are and initialize the component. Then, [modify the component attributes and constructor parameters](#modifying-component-attributes-and-constructor-parameters) to customize a component. -In a declarative UI, all pages are composed of components. The data structure of the component is **struct**, and the decorator [@Component](ts-component-based-component.md) is the component-based flag. The struct decorated by **@Component** indicates that the struct has the component capability. + +## Components and Decorators + +In a declarative UI, all pages are composed of components. The data structure of the component is struct, and the decorator [@Component](ts-component-based-component.md) is the component-based flag. The struct decorated by @Component indicates that the struct has the component capability. The method for declaring a custom component is as follows: + ``` @Component struct MyComponent {} ``` -In an IDE project template, **MyComponent** is a custom component that can display text in the center. You can describe your UI structures in the **build** method of the component, by complying with the API constraints of the **Builder**. +In an IDE project template, MyComponent is a custom component that can display text in the center. You can describe your UI structures in the build method of the component, by complying with the API constraints of the Builder. + ``` interface Builder { @@ -21,59 +25,58 @@ interface Builder { } ``` -The component decorated by [@Entry](ts-component-based-entry.md) indicates that the component is the main entry of the page and can also be considered as the root node of the page. Note that a page must have one and only one **@Entry**. Only the **@Entry** decorated component and its child components are displayed on the page. +The component decorated by [@Entry](ts-component-based-entry.md) indicates that the component is the main entry of the page and can also be considered as the root node of the page. **NOTE** that a page must have one and only one @Entry. Only the @Entry decorated component and its child components are displayed on the page. -**@Component** and **@Entry** are basic and important decorators. To put it simply, a decorator assigns a capability to an object to be decorated. For example, **@Entry** assigns the capability of the page entry, and **@Component** assigns the component capability. +@Component and @Entry are basic and important decorators. To put it simply, a decorator assigns a capability to an object to be decorated. For example, @Entry assigns the capability of the page entry, and @Component assigns the component capability. With a basic knowledge of the component and decorator, you are ready to develop a diet application. -## Modifying Component Attributes and Constructor Parameters -When you create a system component, the default style is used. You can change the display of the component by changing its attributes and styles. - -1. Modify the **fontSize** attribute of the **** component to change the font size of the component. In this example, the font size is set to 26 and font weight 500. Two configuration methods are available for setting the font weight: - - 1. The value of the number type ranges from 100 to 900. The default value is **400**. A larger value indicates a thicker font. - 2. **fontWeight** is a built-in enumeration type. Its value can be **Lighter**, **Normal**, **Bold**, or **Bolder**. - - The attribute method must follow the component and be connected by the operator ".". You can also configure multiple attributes of the component in method chaining mode. - - ``` - @Entry - @Component - struct MyComponent { - build() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Text('Hello World') - .fontSize(26) - .fontWeight(500) - } - .width('100%') - .height('100%') - } - } - ``` - - ![](figures/en-us_image_0000001168728272.png) - -2. Change the display content of the **** component from **Hello World** to **Tomato** by modifying the constructor parameters of the **** component. - - ``` - @Entry - @Component - struct MyComponent { - build() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Text('Tomato') - .fontSize(26) - .fontWeight(500) - } - .width('100%') - .height('100%') - } - } - ``` - - ![](figures/en-us_image_0000001168888224.png) +## Modifying Component Attributes and Constructor Parameters +When you create a system component, the default style is used. You can change the display of the component by changing its attributes and styles. +1. Modify the fontSize attribute of the component to change the font size of the component. In this example, the font size is set to 26 and font weight 500. Two configuration methods are available for setting the font weight: + 1. The value of the number type ranges from 100 to 900. The default value is 400. A larger value indicates a thicker font. + 2. fontWeight is a built-in enumeration type. Its value can be Lighter, Normal, Bold, or Bolder. + + The attribute method must follow the component and be connected by the operator ".". You can also configure multiple attributes of the component in method chaining mode. + + + ``` + @Entry + @Component + struct MyComponent { + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Text('Hello World') + .fontSize(26) + .fontWeight(500) + } + .width('100%') + .height('100%') + } + } + ``` + + ![en-us_image_0000001267767845](figures/en-us_image_0000001267767845.png) + +2. Change the display content of the component from Hello World to Tomato by modifying the constructor parameters of the component. + + ``` + @Entry + @Component + struct MyComponent { + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Text('Tomato') + .fontSize(26) + .fontWeight(500) + } + .width('100%') + .height('100%') + } + } + ``` + + ![en-us_image_0000001267887829](figures/en-us_image_0000001267887829.png) diff --git a/en/application-dev/ui/ui-ts-creating-project.md b/en/application-dev/ui/ui-ts-creating-project.md index 940bf1824a3bc1fa8b9c815608a04efe0c93bc7f..23bd070dff61aa90e7c29e51ef44fe7b5c85f389 100644 --- a/en/application-dev/ui/ui-ts-creating-project.md +++ b/en/application-dev/ui/ui-ts-creating-project.md @@ -1,67 +1,69 @@ -# Creating a Declarative UI Project +# Creating a Declarative UI Project -Before creating a project, you need to install DevEco Studio. For details, see [HUAWEI DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/tools_overview-0000001053582387). -1. Open DevEco Studio and click **Create Project**. If there is already a project, choose **File** \> **New** \> **New project**. +Before creating a project, you need to install DevEco Studio. - ![](figures/en-us_image_0000001168956332.png) -2. On the page for selecting an ability template, select **\[Standard\]Empty Ability**. +1. Open DevEco Studio and click Create Project. If there is already a project, choose File > New > New project. + ![en-us_image_0000001267607861](figures/en-us_image_0000001267607861.png) - ![](figures/en-us_image_0000001168059158.png) +2. + -3. Install the OpenHarmony SDK. + On the page for selecting an ability template, select [Standard]Empty Ability. - ![](figures/en-us_image_0000001213462329.png) + ![en-us_image_0000001223127704](figures/en-us_image_0000001223127704.png) -4. On the project configuration page, set Project Name to **HealthyDiet**, **Project Type** to **Application**, **Device Type** to **Phone**, **Language** to **eTS**, and **Compatible API Version** to **SDK: API Version 7**. By default, DevEco Studio saves the project to drive C. You can change the save path by setting **Save Location**. When you are done, click **Finish**. +3. + Install the OpenHarmony SDK. - ![](figures/en-us_image_0000001167746622.png) + ![en-us_image_0000001223127700](figures/en-us_image_0000001223127700.png) -5. After the project is created, open the **app.ets** file. +4. On the project configuration page, set Project Name to HealthyDiet, Project Type to Application, Device Type to Phone, Language to eTS, and Compatible API Version to SDK: API Version 7. By default, DevEco Studio saves the project to drive C. You can change the save path by setting Save Location. When you are done, click Finish. + - The **app.ets** file provides the **onCreate** and **onDestroy** methods for the application lifecycle. **onCreate** is called when an application is created, and **onDestroy** is called when an application is destroyed. Global variables can be declared in the **app.ets** file, wherein the declared data and methods are shared by the entire application. + ![en-us_image_0000001267647849](figures/en-us_image_0000001267647849.png) - ``` - export default { - onCreate() { - console.info('Application onCreate') - }, - onDestroy() { - console.info('Application onDestroy') - }, - } - ``` +5. After the project is created, open the app.ets file. + The app.ets file provides the onCreate and onDestroy methods for the application lifecycle. onCreate is called when an application is created, and onDestroy is called when an application is destroyed. Global variables can be declared in the app.ets file, wherein the declared data and methods are shared by the entire application. + + ``` + export default { + onCreate() { + console.info('Application onCreate') + }, + onDestroy() { + console.info('Application onDestroy') + }, + } + ``` -6. In the project navigation tree, open **index.ets**. This page displays the current UI description. The declarative UI framework automatically generates a component-based **struct**, which complies with the **Builder** API declaration. The current layout and components are declared in the **build** method. +6. In the project navigation tree, open index.ets. This page displays the current UI description. The declarative UI framework automatically generates a component-based struct, which complies with the Builder API declaration. The current layout and components are declared in the build method. + + ``` + @Entry + @Component + struct MyComponent { + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { + Text('Hello World') + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + .height('100%') + } + } + ``` - ``` - @Entry - @Component - struct MyComponent { - build() { - Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Text('Hello World') - .fontSize(50) - .fontWeight(FontWeight.Bold) - } - .width('100%') - .height('100%') - } - } - ``` +7. Click Previewer on the right to open the Previewer window. In the Previewer window of the phone type, Hello World is displayed in the middle and in bold. + If the Previewer button is unavailable, choose Settings > SDK Manager >OpenHarmony SDK > Tools to check whether the Previewer is installed. -7. Click **Previewer** on the right to open the **Previewer** window. In the **Previewer** window of the phone type, **Hello World** is displayed in the middle and in bold. + ![en-us_image_0000001222807756](figures/en-us_image_0000001222807756.png) - If the **Previewer** button is unavailable, choose **Settings** \> **SDK Manager** \>OpenHarmony SDK \> **Tools** to check whether the **Previewer** is installed. +8. Install the application on the phone and run the application. Connect the phone to the computer. After the IDE identifies the phone, click Run'entry'. + ![en-us_image_0000001267607865](figures/en-us_image_0000001267607865.png) - ![](figures/en-us_image_0000001214595111.png) - -8. Install the application on the phone and run the application. Connect the phone to the computer. After the IDE identifies the phone, click **Run'entry'**. - - ![](figures/en-us_image_0000001148858818.png) - - Before the installation, you must configure an application signature. For details, see [Configuring the OpenHarmony App Signature](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-debugging-and-running-0000001263040487#section17660437768). After the installation is complete, click the **Run** icon on the screen to open the application. **Hello World** is displayed in the center of the screen. - - ![](figures/en-us_image_0000001158896538.png) + Before the installation, you must configure an application signature. For details, see [Configuring the OpenHarmony App Signature](../quick-start/configuring-the-openharmony-app-signature.md). After the installation is complete, click the Run icon on the screen to open the application. Hello World is displayed in the center of the screen. + ![en-us_image_0000001267647841](figures/en-us_image_0000001267647841.png) diff --git a/en/application-dev/ui/ui-ts-creating-simple-page.md b/en/application-dev/ui/ui-ts-creating-simple-page.md index ca6be86def635a49f870cbf0a3d653f093e60774..c4edd001c5d1a15479d0e535d7838d0a20fe562c 100644 --- a/en/application-dev/ui/ui-ts-creating-simple-page.md +++ b/en/application-dev/ui/ui-ts-creating-simple-page.md @@ -1,559 +1,558 @@ -# Creating a Simple Page - -In this section, we will develop an infographic food details page, by building custom components through the container components **** and **** as well as basic components **** and ****. - -## Building the Stack Layout - -1. Create a food name. - - Delete the code of the **build** method in the project template, create a **** component, and place the **** component in the braces of the **** component so that the **** component becomes a child component of the **** component. A **** component consists of one or more child components. The latter child component overwrites the former one. - - ``` - @Entry - @Component - struct MyComponent { - build() { - Stack() { - Text('Tomato') - .fontSize(26) - .fontWeight(500) - } - } - } - ``` - - ![](figures/en-us_image_0000001214128687.png) - -2. Display food pictures. - - Create an **** component and specify a URL for it. The **** and **** components are mandatory. To display the **** component above the **** component, you need to declare the **** component first. Image resources are stored in the **rawfile** folder in **resources**. When referencing the resources in the **rawfile** folder, use the **$rawfile\('_filename_ loaded\)** format, where **filename** indicates the relative path of the file in the **rawfile** folder. Currently, **$rawfile** only allows the **** component to reference image resources. - - ``` - @Entry - @Component - struct MyComponent { - build() { - Stack() { - Image($rawfile('Tomato.png')) - Text('Tomato') - .fontSize(26) - .fontWeight(500) - } - } - } - ``` - - ![](figures/en-us_image_0000001168410342.png) - -3. Access images through resources. - - In addition to specifying the image path, you can also use the media resource symbol **$r** to reference resources based on the resource qualifier rules in the **resources** folder. Right-click the **resources** folder, choose **New** \> **Resource Directory**, set **Resource Type** to **Media** \(image resource\), and set the resource qualifier to **Device-Phone** \(currently, phones are used\). - - ![](figures/en-us_image_0000001168570318.png) - - Click **OK**. The **phone.media** folder is generated in the **resources** folder. Place **Tomato.png** in the folder. - - ![](figures/en-us_image_0000001214330169.png) - - You can then can reference the application resource in the **$r\('app.type.name'\)** format, that is, **$r\('app.media.Tomato'\)**. - - ``` - @Entry - @Component - struct MyComponent { - build() { - Stack() { - Image($r('app.media.Tomato')) - .objectFit(ImageFit.Contain) - .height(357) - Text('Tomato') - .fontSize(26) - .fontWeight(500) - } - } - } - ``` - -4. Set the width and height of the image, and set the **objectFit** attribute of the image to **ImageFit.Contain**, which means to keep the aspect ratio of the image to ensure that the image is completely displayed within the boundary. - - If the image fills the entire screen, the possible causes are as follows: - - 1. The width and height of the image are not set. - 2. The default attribute of **objectFit** of the image is **ImageFit.Cover**, that is, the image is zoomed in or zoomed out to fill the entire display boundary with the aspect ratio locked. - - ``` - @Entry - @Component - struct MyComponent { - build() { - Stack() { - Image($r('app.media.Tomato')) - .objectFit(ImageFit.Contain) - .height(357) - Text('Tomato') - .fontSize(26) - .fontWeight(500) - } - } - } - ``` - - ![](figures/en-us_image_0000001214210217.png) - -5. Set the food image and name layout. Set the alignment mode of the stack to bottom alignment. By default, the stack is center aligned. Set **alignContent** to **Alignment.BottomStart**. Similar to **FontWeight**, **Alignment** is a built-in enumeration type provided by the framework. - - ``` - @Entry - @Component - struct MyComponent { - build() { - Stack({ alignContent: Alignment.BottomStart }) { - Image($r('app.media.Tomato')) - .objectFit(ImageFit.Contain) - .height(357) - Text('Tomato') - .fontSize(26) - .fontWeight(500) - } - } - } - ``` - - ![](figures/en-us_image_0000001168728872.png) - -6. You can change the background color of the food image by setting the background color of the stack. You can set the background color in either of the following ways: - - 1. By using the built-in enumeration value of **Color** provided by the framework. For example, **backgroundColor\(Color.Red\)** indicates that the background color is set to red. - 2. By using the parameter of the string type. The supported color formats are rgb, rgba, and HEX. For example, you can set the background color to blue by setting **backgroundColor\(??\#0000FF??\)** and set the background color to white by setting **backgroundColor\(??rgb\(255, 255, 255\)??\)**. - - ``` - @Entry - @Component - struct MyComponent { - build() { - Stack({ alignContent: Alignment.BottomStart }) { - Image($r('app.media.Tomato')) - .objectFit(ImageFit.Contain) - .height(357) - Text('Tomato') - .fontSize(26) - .fontWeight(500) - } - .backgroundColor('#FFedf2f5') - } - } - ``` - - ![](figures/en-us_image_0000001168888822.png) - -7. Adjust the left and bottom margin of the **** component. Margin is a shorthand attribute. You can specify the margins of the four edges in a unified manner or separately. The configuration method is as follows: - - 1. When the parameter is set to **Length**, the outer margins of the four edges are specified. For example, **margin\(20\)** indicates that the outer margins of the top, right, bottom, and left edges are all 20. - 2. **\{top?: Length, right?: Length, bottom?: Length, left?:Length\}** specifies the margins of the four edges. For example, **margin\(\{ left: 26, bottom: 17.4 \}\)** indicates that the left margin is 26 and the bottom margin is 17.4. - - ``` - @Entry - @Component - struct MyComponent { - build() { - Stack({ alignContent: Alignment.BottomStart }) { - Image($r('app.media.Tomato')) - .objectFit(ImageFit.Contain) - .height(357) +# Creating a Simple Page + + +In this section, we will develop an infographic food details page, by building custom components through the container components <Stack> and <Flex> as well as basic components <Image> and <Text>. + + +## Building the Stack Layout + +1. Create a food name. + Delete the code of the build method in the project template, create a <Stack> component, and place the <Text> component in the braces of the <Stack> component so that the <Text> component becomes a child component of the <Stack> component. A <Stack> component consists of one or more child components. The latter child component overwrites the former one. + + ``` + @Entry + @Component + struct MyComponent { + build() { + Stack() { + Text('Tomato') + .fontSize(26) + .fontWeight(500) + } + } + } + ``` + + ![en-us_image_0000001222967780](figures/en-us_image_0000001222967780.png) + +2. Display food pictures. + Create an <Image> component and specify a URL for it. The <Image> and <Text> components are mandatory. To display the <Text> component above the <Image> component, you need to declare the <Image> component first. Image resources are stored in the rawfile folder in resources. When referencing the resources in the rawfile folder, use the $rawfile('_filename_ loaded) format, where filename indicates the relative path of the file in the rawfile folder. Currently, $rawfile only allows the <Image> component to reference image resources. + + ``` + @Entry + @Component + struct MyComponent { + build() { + Stack() { + Image($rawfile('Tomato.png')) + Text('Tomato') + .fontSize(26) + .fontWeight(500) + } + } + } + ``` + + ![en-us_image_0000001267887861](figures/en-us_image_0000001267887861.png) + +3. Access images through resources. + In addition to specifying the image path, you can also use the media resource symbol $r to reference resources based on the resource qualifier rules in the resources folder. Right-click the resources folder, choose New > Resource Directory, set Resource Type to Media (image resource), and set the resource qualifier to Device-Phone (currently, phones are used). + + ![en-us_image_0000001267887853](figures/en-us_image_0000001267887853.png) + + Click OK. The phone.media folder is generated in the resources folder. Place Tomato.png in the folder. + + ![en-us_image_0000001222807784](figures/en-us_image_0000001222807784.png) + + You can then can reference the application resource in the $r('app.type.name') format, that is, $r('app.media.Tomato'). + + + ``` + @Entry + @Component + struct MyComponent { + build() { + Stack() { + Image($r('app.media.Tomato')) + .objectFit(ImageFit.Contain) + .height(357) + Text('Tomato') + .fontSize(26) + .fontWeight(500) + } + } + } + ``` + +4. Set the width and height of the image, and set the objectFit attribute of the image to ImageFit.Contain, which means to keep the aspect ratio of the image to ensure that the image is completely displayed within the boundary. + If the image fills the entire screen, the possible causes are as follows: + 1. The width and height of the image are not set. + + 2. The default attribute of objectFit of the image is ImageFit.Cover, that is, the image is zoomed in or zoomed out to fill the entire display boundary with the aspect ratio locked. + + + ``` + @Entry + @Component + struct MyComponent { + build() { + Stack() { + Image($r('app.media.Tomato')) + .objectFit(ImageFit.Contain) + .height(357) + Text('Tomato') + .fontSize(26) + .fontWeight(500) + } + } + } + ``` + + ![en-us_image_0000001223127732](figures/en-us_image_0000001223127732.png) + +5. Set the food image and name layout. Set the alignment mode of the stack to bottom alignment. By default, the stack is center aligned. Set alignContent to Alignment.BottomStart. Similar to FontWeight, Alignment is a built-in enumeration type provided by the framework. + + ``` + @Entry + @Component + struct MyComponent { + build() { + Stack({ alignContent: Alignment.BottomStart }) { + Image($r('app.media.Tomato')) + .objectFit(ImageFit.Contain) + .height(357) Text('Tomato') - .fontSize(26) - .fontWeight(500) - .margin({left: 26, bottom: 17.4}) - } - .backgroundColor('#FFedf2f5') - } - } - ``` - - ![](figures/en-us_image_0000001213968747.png) - -8. Adjust the structure between components and semanticize component names. Create the **FoodDetail** page entry component, create a column in **FoodDetail**, and set the alignment to **alignItems\(HorizontalAlign.Center\)**. Change the name of the **MyComponent** component to **FoodImageDisplay**, which is a child component of the **FoodDetail** component. - - A column is a container component whose child components are vertically arranged. It is a linear layout in essence. Therefore, only the alignment in the cross axis direction can be set. - - ``` - @Component - struct FoodImageDisplay { - build() { - Stack({ alignContent: Alignment.BottomStart }) { - Image($r('app.media.Tomato')) - .objectFit(ImageFit.Contain) - Text('Tomato') - .fontSize(26) - .fontWeight(500) - .margin({ left: 26, bottom: 17.4 }) - } - .height(357) - .backgroundColor('#FFedf2f5') - } - } - - @Entry - @Component - struct FoodDetail { - build() { - Column() { - FoodImageDisplay() - } - .alignItems(HorizontalAlign.Center) - } - } - ``` - - -## Building the Flex Layout - -You can use the **Flex** layout to build a food composition table. In this way you do not need to worry about the width and height calculation. The size of different cells can be flexibly set based on the proportion. - -1. Create a **ContentTable** component as a child component of the **FoodDetail** component. - - ``` - @Component - struct FoodImageDisplay { - build() { - Stack({ alignContent: Alignment.BottomStart }) { - Image($r('app.media.Tomato')) - .objectFit(ImageFit.Contain) - .height(357) - Text('Tomato') - .fontSize(26) - .fontWeight(500) - .margin({ left: 26, bottom: 17.4 }) - } - .backgroundColor('#FFedf2f5') - } - } - - @Component - struct ContentTable { - build() {} - } - - @Entry - @Component - struct FoodDetail { - build() { - Column() { - FoodImageDisplay() - ContentTable() - } - .alignItems(HorizontalAlign.Center) - } - } - ``` - -2. Create a **Flex** component to display two food composition categories in the tomato: Calories and Nutrition. - - **Calories** contains information about calories. **Nutrition** contains information about protein, fat, carbohydrates, and vitamin C. - - Create the Calories class. Create a **Flex** component and set its height to **280**, and the top, right, and left margins to **30**. The **Flex** component contains three **Text** child components, which represent the category name \(**Calories**\), content name \(**Calories**\), and contain value \(**17 kcal**\), respectively. By default, child components in the **Flex** component are arranged horizontally. - - In the following example, code of **FoodImageDisplay** is omitted, and only code of **ContentTable** is provided. - - ``` - @Component - struct ContentTable { - build() { - Flex() { - Text('Calories') - .fontSize(17.4) - .fontWeight(FontWeight.Bold) - Text('Calories') - .fontSize(17.4) - Text('17kcal') - .fontSize(17.4) - } - .height(280) - .padding({ top: 30, right: 30, left: 30 }) - } - } - - @Entry - @Component - struct FoodDetail { - build() { - Column() { - FoodImageDisplay() - ContentTable() - } - .alignItems(HorizontalAlign.Center) - } - } - ``` - - ![](figures/en-us_image_0000001169759552.png) - -3. Adjust the layout and set the proportion \(**layoutWeight**\) of each part. Set the proportion of the category name to 1, and the total proportion of content name and content value to **2**. The content name and content value are in a same **Flex**, and the content name occupies all remaining space **flexGrow\(1\)**. - - ``` - @Component - struct FoodImageDisplay { - build() { - Stack({ alignContent: Alignment.BottomStart }) { - Image($m('Tomato.png')) - .objectFit(ImageFit.Contain) - .height(357) - Text('Tomato') - .fontSize(26) - .fontWeight(500) - .margin({ left: 26, bottom: 17.4 }) - } + .fontSize(26) + .fontWeight(500) + } + } + } + ``` + + ![en-us_image_0000001267647873](figures/en-us_image_0000001267647873.png) + +6. You can change the background color of the food image by setting the background color of the stack. You can set the background color in either of the following ways: + 1. By using the built-in enumeration value of Color provided by the framework. For example, backgroundColor(Color.Red) indicates that the background color is set to red. + 2. By using the parameter of the string type. The supported color formats are rgb, rgba, and HEX. For example, you can set the background color to blue by setting backgroundColor(??\#0000FF??) and set the background color to white by setting backgroundColor(??rgb(255, 255, 255)??). + + + ``` + @Entry + @Component + struct MyComponent { + build() { + Stack({ alignContent: Alignment.BottomStart }) { + Image($r('app.media.Tomato')) + .objectFit(ImageFit.Contain) + .height(357) + Text('Tomato') + .fontSize(26) + .fontWeight(500) + } + .backgroundColor('#FFedf2f5') + } + } + ``` + + ![en-us_image_0000001222967772](figures/en-us_image_0000001222967772.png) + +7. Adjust the left and bottom margin of the <Text> component. Margin is a shorthand attribute. You can specify the margins of the four edges in a unified manner or separately. The configuration method is as follows: + 1. When the parameter is set to Length, the outer margins of the four edges are specified. For example, margin(20) indicates that the outer margins of the top, right, bottom, and left edges are all 20. + 2. {top?: Length, right?: Length, bottom?: Length, left?:Length} specifies the margins of the four edges. For example, margin({ left: 26, bottom: 17.4 }) indicates that the left margin is 26 and the bottom margin is 17.4. + + + ``` + @Entry + @Component + struct MyComponent { + build() { + Stack({ alignContent: Alignment.BottomStart }) { + Image($r('app.media.Tomato')) + .objectFit(ImageFit.Contain) + .height(357) + Text('Tomato') + .fontSize(26) + .fontWeight(500) + .margin({left: 26, bottom: 17.4}) + } .backgroundColor('#FFedf2f5') - } - } - - @Component - struct ContentTable { - build() { - Flex() { - Text('Calories') - .fontSize(17.4) - .fontWeight(FontWeight.Bold) - .layoutWeight(1) - Flex() { - Text('Calories') - .fontSize(17.4) - .flexGrow(1) - Text('17kcal') - .fontSize(17.4) - } - .layoutWeight(2) - } - .height(280) - .padding({ top: 30, right: 30, left: 30 }) - } - } - - @Entry - @Component - struct FoodDetail { - build() { - Column() { - FoodImageDisplay() - ContentTable() - } - .alignItems(HorizontalAlign.Center) - } - } - ``` - - ![](figures/en-us_image_0000001215079443.png) - -4. Create the **Nutrient** class in a similar process. **Nutrition** consists of four parts: **Protein**, **Fat**, **Carbohydrates**, and **VitaminC**. The names of the last three parts are omitted in the table and represented by spaces. - - Set **FlexDirection.Column**, **FlexAlign.SpaceBetween**, and **ItemAlign.Start**. - - ``` - @Component - struct ContentTable { - build() { - Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Start }) { - Flex() { - Text('Calories') - .fontSize(17.4) - .fontWeight(FontWeight.Bold) - .layoutWeight(1) - Flex() { - Text('Calories') - .fontSize(17.4) - .flexGrow(1) - Text('17kcal') - .fontSize(17.4) - } - .layoutWeight(2) - } - Flex() { - Text('Nutrition') - .fontSize(17.4) - .fontWeight(FontWeight.Bold) - .layoutWeight(1) - Flex() { - Text('Protein') - .fontSize(17.4) - .flexGrow(1) - Text('0.9g') - .fontSize(17.4) - } - .layoutWeight(2) - } - Flex() { - Text(' ') - .fontSize(17.4) - .fontWeight(FontWeight.Bold) - .layoutWeight(1) - Flex() { - Text('Fat') - .fontSize(17.4) - .flexGrow(1) - Text('0.2g') - .fontSize(17.4) - } - .layoutWeight(2) - } - Flex() { - Text(' ') - .fontSize(17.4) - .fontWeight(FontWeight.Bold) - .layoutWeight(1) - Flex() { - Text('Carbohydrates') - .fontSize(17.4) - .flexGrow(1) - Text('3.9g') - .fontSize(17.4) - } - .layoutWeight(2) - } - Flex() { - Text(' ') - .fontSize(17.4) - .fontWeight(FontWeight.Bold) - .layoutWeight(1) - Flex() { - Text('vitaminC') - .fontSize(17.4) - .flexGrow(1) - Text('17.8mg') - .fontSize(17.4) - } - .layoutWeight(2) - } - } - .height(280) - .padding({ top: 30, right: 30, left: 30 }) - } - } - - @Entry - @Component - struct FoodDetail { - build() { - Column() { - FoodImageDisplay() - ContentTable() - } - .alignItems(HorizontalAlign.Center) - } - } - ``` - -5. Use the custom constructor **@Builder** to simplify the code. It can be found that the food groups in each food composition table are actually of the same UI structure. - - ![](figures/en-us_image_0000001169599582.png) - - Currently, all food groups are declared, resulting in code duplication and redundancy. You can use **@Builder** to build a custom method and abstract the same UI structure declaration. The **@Builder** decorated method and the **build** method for the **@Component** decorated component are used to declare some UI rendering structures and comply with the same eTS syntax. You can define one or more methods decorated by **@Builder**, but a component decorated by **@Component** can have only one **build** method. - - Declare the **IngredientItem** method decorated by **@Builder** in **ContentTable** to declare the UI descriptions for the category name, content name, and content value. - - ``` - @Component - struct ContentTable { - @Builder IngredientItem(title:string, colorValue: string, name: string, value: string) { - Flex() { - Text(title) - .fontSize(17.4) - .fontWeight(FontWeight.Bold) - .layoutWeight(1) - Flex({ alignItems: ItemAlign.Center }) { - Circle({width: 6, height: 6}) - .margin({right: 12}) - .fill(colorValue) - Text(name) - .fontSize(17.4) - .flexGrow(1) - Text(value) - .fontSize(17.4) - } - .layoutWeight(2) - } - } - } - ``` - - When the **IngredientItem** API is called in the **build** method of **ContentTable**, **this** needs to be used to invoke the method in the scope of the component to distinguish the global method call. - - ``` - @Component - struct ContentTable { - ...... - build() { - Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Start }) { - this.IngredientItem('Calories', 'Calories', '17kcal') - this.IngredientItem('Nutrition', 'Protein', '0.9g') - this.IngredientItem('', 'Fat', '0.2g') - this.IngredientItem('', 'Carbohydrates', '3.9g') - this.IngredientItem('', 'VitaminC', '17.8mg') - } - .height(280) - .padding({ top: 30, right: 30, left: 30 }) - } - } - ``` - - The overall code of the **ContentTable** component is as follows: - - ``` - @Component - struct ContentTable { - @Builder IngredientItem(title:string, name: string, value: string) { - Flex() { - Text(title) - .fontSize(17.4) - .fontWeight(FontWeight.Bold) - .layoutWeight(1) - Flex() { - Text(name) - .fontSize(17.4) - .flexGrow(1) - Text(value) - .fontSize(17.4) - } - .layoutWeight(2) - } - } - - build() { - Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Start }) { - this.IngredientItem('Calories', 'Calories', '17kcal') - this.IngredientItem('Nutrition', 'Protein', '0.9g') - this.IngredientItem('', 'Fat', '0.2g') - this.IngredientItem('', 'Carbohydrates', '3.9g') - this.IngredientItem('', 'VitaminC', '17.8mg') - } - .height(280) - .padding({ top: 30, right: 30, left: 30 }) - } - } - - @Entry - @Component - struct FoodDetail { - build() { - Column() { - FoodImageDisplay() - ContentTable() - } - .alignItems(HorizontalAlign.Center) - } - } - ``` - - ![](figures/en-us_image_0000001215199399.png) - + } + } + ``` + + ![en-us_image_0000001222967776](figures/en-us_image_0000001222967776.png) + +8. Adjust the structure between components and semanticize component names. Create the FoodDetail page entry component, create a column in FoodDetail, and set the alignment to alignItems(HorizontalAlign.Center). Change the name of the MyComponent component to FoodImageDisplay, which is a child component of the FoodDetail component. + A column is a container component whose child components are vertically arranged. It is a linear layout in essence. Therefore, only the alignment in the cross axis direction can be set. + + + ``` + @Component + struct FoodImageDisplay { + build() { + Stack({ alignContent: Alignment.BottomStart }) { + Image($r('app.media.Tomato')) + .objectFit(ImageFit.Contain) + Text('Tomato') + .fontSize(26) + .fontWeight(500) + .margin({ left: 26, bottom: 17.4 }) + } + .height(357) + .backgroundColor('#FFedf2f5') + } + } + + @Entry + @Component + struct FoodDetail { + build() { + Column() { + FoodImageDisplay() + } + .alignItems(HorizontalAlign.Center) + } + } + ``` + + +## Building the Flex Layout + +You can use the Flex layout to build a food composition table. In this way you do not need to worry about the width and height calculation. The size of different cells can be flexibly set based on the proportion. + +1. Create a ContentTable component as a child component of the FoodDetail component. + + ``` + @Component + struct FoodImageDisplay { + build() { + Stack({ alignContent: Alignment.BottomStart }) { + Image($r('app.media.Tomato')) + .objectFit(ImageFit.Contain) + .height(357) + Text('Tomato') + .fontSize(26) + .fontWeight(500) + .margin({ left: 26, bottom: 17.4 }) + } + .backgroundColor('#FFedf2f5') + } + } + + @Component + struct ContentTable { + build() {} + } + + @Entry + @Component + struct FoodDetail { + build() { + Column() { + FoodImageDisplay() + ContentTable() + } + .alignItems(HorizontalAlign.Center) + } + } + ``` + +2. Create a Flex component to display two food composition categories in the tomato: Calories and Nutrition. + Calories contains information about calories. Nutrition contains information about protein, fat, carbohydrates, and vitamin C. + + Create the Calories class. Create a Flex component and set its height to 280, and the top, right, and left margins to 30. The Flex component contains three Text child components, which represent the category name (Calories), content name (Calories), and contain value (17 kcal), respectively. By default, child components in the Flex component are arranged horizontally. + + In the following example, code of FoodImageDisplay is omitted, and only code of ContentTable is provided. + + + ``` + @Component + struct ContentTable { + build() { + Flex() { + Text('Calories') + .fontSize(17.4) + .fontWeight(FontWeight.Bold) + Text('Calories') + .fontSize(17.4) + Text('17kcal') + .fontSize(17.4) + } + .height(280) + .padding({ top: 30, right: 30, left: 30 }) + } + } + + @Entry + @Component + struct FoodDetail { + build() { + Column() { + FoodImageDisplay() + ContentTable() + } + .alignItems(HorizontalAlign.Center) + } + } + ``` + + ![en-us_image_0000001267767869](figures/en-us_image_0000001267767869.png) + +3. Adjust the layout and set the proportion (layoutWeight) of each part. Set the proportion of the category name to 1, and the total proportion of content name and content value to 2. The content name and content value are in a same Flex, and the content name occupies all remaining space flexGrow(1). + + ``` + @Component + struct FoodImageDisplay { + build() { + Stack({ alignContent: Alignment.BottomStart }) { + Image($m('Tomato.png')) + .objectFit(ImageFit.Contain) + .height(357) + Text('Tomato') + .fontSize(26) + .fontWeight(500) + .margin({ left: 26, bottom: 17.4 }) + } + .backgroundColor('#FFedf2f5') + } + } + + @Component + struct ContentTable { + build() { + Flex() { + Text('Calories') + .fontSize(17.4) + .fontWeight(FontWeight.Bold) + .layoutWeight(1) + Flex() { + Text('Calories') + .fontSize(17.4) + .flexGrow(1) + Text('17kcal') + .fontSize(17.4) + } + .layoutWeight(2) + } + .height(280) + .padding({ top: 30, right: 30, left: 30 }) + } + } + + @Entry + @Component + struct FoodDetail { + build() { + Column() { + FoodImageDisplay() + ContentTable() + } + .alignItems(HorizontalAlign.Center) + } + } + ``` + + ![en-us_image_0000001267607901](figures/en-us_image_0000001267607901.png) + +4. Create the Nutrient class in a similar process. Nutrition consists of four parts: Protein, Fat, Carbohydrates, and VitaminC. The names of the last three parts are omitted in the table and represented by spaces. + Set FlexDirection.Column, FlexAlign.SpaceBetween, and ItemAlign.Start. + + + ``` + @Component + struct ContentTable { + build() { + Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Start }) { + Flex() { + Text('Calories') + .fontSize(17.4) + .fontWeight(FontWeight.Bold) + .layoutWeight(1) + Flex() { + Text('Calories') + .fontSize(17.4) + .flexGrow(1) + Text('17kcal') + .fontSize(17.4) + } + .layoutWeight(2) + } + Flex() { + Text('Nutrition') + .fontSize(17.4) + .fontWeight(FontWeight.Bold) + .layoutWeight(1) + Flex() { + Text('Protein') + .fontSize(17.4) + .flexGrow(1) + Text('0.9g') + .fontSize(17.4) + } + .layoutWeight(2) + } + Flex() { + Text(' ') + .fontSize(17.4) + .fontWeight(FontWeight.Bold) + .layoutWeight(1) + Flex() { + Text('Fat') + .fontSize(17.4) + .flexGrow(1) + Text('0.2g') + .fontSize(17.4) + } + .layoutWeight(2) + } + Flex() { + Text(' ') + .fontSize(17.4) + .fontWeight(FontWeight.Bold) + .layoutWeight(1) + Flex() { + Text('Carbohydrates') + .fontSize(17.4) + .flexGrow(1) + Text('3.9g') + .fontSize(17.4) + } + .layoutWeight(2) + } + Flex() { + Text(' ') + .fontSize(17.4) + .fontWeight(FontWeight.Bold) + .layoutWeight(1) + Flex() { + Text('vitaminC') + .fontSize(17.4) + .flexGrow(1) + Text('17.8mg') + .fontSize(17.4) + } + .layoutWeight(2) + } + } + .height(280) + .padding({ top: 30, right: 30, left: 30 }) + } + } + + @Entry + @Component + struct FoodDetail { + build() { + Column() { + FoodImageDisplay() + ContentTable() + } + .alignItems(HorizontalAlign.Center) + } + } + ``` + +5. Use the custom constructor @Builder to simplify the code. It can be found that the food groups in each food composition table are actually of the same UI structure. + ![en-us_image_0000001223287704](figures/en-us_image_0000001223287704.png) + + Currently, all food groups are declared, resulting in code duplication and redundancy. You can use @Builder to build a custom method and abstract the same UI structure declaration. The @Builder decorated method and the build method for the @Component decorated component are used to declare some UI rendering structures and comply with the same eTS syntax. You can define one or more methods decorated by @Builder, but a component decorated by @Component can have only one build method. + + Declare the IngredientItem method decorated by @Builder in ContentTable to declare the UI descriptions for the category name, content name, and content value. + + + ``` + @Component + struct ContentTable { + @Builder IngredientItem(title:string, name: string, value: string) { + Flex() { + Text(title) + .fontSize(17.4) + .fontWeight(FontWeight.Bold) + .layoutWeight(1) + Flex({ alignItems: ItemAlign.Center }) { + Circle({width: 6, height: 6}) + .margin({right: 12}) + .fill(colorValue) + Text(name) + .fontSize(17.4) + .flexGrow(1) + Text(value) + .fontSize(17.4) + } + .layoutWeight(2) + } + } + } + ``` + + When the IngredientItem API is called in the build method of ContentTable, this needs to be used to invoke the method in the scope of the component to distinguish the global method call. + + + ``` + @Component + struct ContentTable { + ...... + build() { + Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Start }) { + this.IngredientItem('Calories', 'Calories', '17kcal') + this.IngredientItem('Nutrition', 'Protein', '0.9g') + this.IngredientItem('', 'Fat', '0.2g') + this.IngredientItem('', 'Carbohydrates', '3.9g') + this.IngredientItem('', 'VitaminC', '17.8mg') + } + .height(280) + .padding({ top: 30, right: 30, left: 30 }) + } + } + ``` + + The overall code of the ContentTable component is as follows: + + + ``` + @Component + struct ContentTable { + @Builder IngredientItem(title:string, name: string, value: string) { + Flex() { + Text(title) + .fontSize(17.4) + .fontWeight(FontWeight.Bold) + .layoutWeight(1) + Flex() { + Text(name) + .fontSize(17.4) + .flexGrow(1) + Text(value) + .fontSize(17.4) + } + .layoutWeight(2) + } + } + + build() { + Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Start }) { + this.IngredientItem('Calories', 'Calories', '17kcal') + this.IngredientItem('Nutrition', 'Protein', '0.9g') + this.IngredientItem('', 'Fat', '0.2g') + this.IngredientItem('', 'Carbohydrates', '3.9g') + this.IngredientItem('', 'VitaminC', '17.8mg') + } + .height(280) + .padding({ top: 30, right: 30, left: 30 }) + } + } + + @Entry + @Component + struct FoodDetail { + build() { + Column() { + FoodImageDisplay() + ContentTable() + } + .alignItems(HorizontalAlign.Center) + } + } + ``` + + ![en-us_image_0000001222807792](figures/en-us_image_0000001222807792.png) You've learned how to build a simple food details page. Read on to learn how to define the page layout and connection. -## Samples +## Samples The following sample is provided to help you better understand how to use build a simple page: -- [eTSBuildCommonView](https://gitee.com/openharmony/app_samples/tree/master/ETSUI/eTSBuildCommonView) - - This sample shows how to build a common view to display the picture of tomatoes and nutrition information, with the stack layout and flex layout. - +- [eTSBuildCommonView](https://gitee.com/openharmony/app_samples/tree/master/ETSUI/eTSBuildCommonView) + This sample shows how to build a common view to display the picture of tomatoes and nutrition information, with the stack layout and flex layout. diff --git a/en/application-dev/ui/ui-ts-experiencing-declarative-ui.md b/en/application-dev/ui/ui-ts-experiencing-declarative-ui.md deleted file mode 100644 index 9b9c92657e1cc0373916facd7fbfa8e29eb7b665..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ui-ts-experiencing-declarative-ui.md +++ /dev/null @@ -1,9 +0,0 @@ -# Experiencing the Declarative UI - -- **[Creating a Declarative UI Project](ui-ts-creating-project.md)** - -- **[Getting to Know Components](ui-ts-components.md)** - -- **[Creating a Simple Page](ui-ts-creating-simple-page.md)** - - diff --git a/en/application-dev/ui/ui-ts-overview.md b/en/application-dev/ui/ui-ts-overview.md index cc1ab7d987b871b9b46f53fa4f7244786491682e..bb34ef82c1acff6cbbb552461d07f6021dcc3e61 100644 --- a/en/application-dev/ui/ui-ts-overview.md +++ b/en/application-dev/ui/ui-ts-overview.md @@ -1,53 +1,47 @@ -# Overview +# Overview -The TypeScript-based declarative development paradigm of ArkUI is a simplified, high-performance UI development framework for cross-device applications on OpenHarmony. -## Basic Capabilities +The TypeScript-based declarative development paradigm of ArkUI is a simplified, high-performance UI development framework for cross-device applications. -In ArkUI that uses the TypeScript-based declarative development paradigm, the programming mode 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. The UI capabilities are provided from three dimensions: component, animation, and state management. System capability APIs are also provided to allow for effortless invocation of system capabilities. -- **Out-of-the-box components** +## Basic Capabilities - A wide range of preset system components are provided. You can set the rendering effect of these components in method chaining mode. You can combine system components to form custom components. In this way, page components are divided into independent UI units to implement independent creation, development, and reuse of different units on pages, making pages more engineering-oriented. +In ArkUI that uses the TypeScript-based declarative development paradigm, the programming mode 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. The UI capabilities are provided from three dimensions: component, animation, and state management. System capability APIs are also provided to allow for effortless invocation of system capabilities. -- **A diverse array of animation APIs** +- Out-of-the-box components + A wide range of preset system components are provided. You can set the rendering effect of these components in method chaining mode. You can combine system components to form custom components. In this way, page components are divided into independent UI units to implement independent creation, development, and reuse of different units on pages, making pages more engineering-oriented. - By drawing from the standard SVG drawing capability and various open animation APIs, you can customize animation tracks by encapsulating physical models or calling the provided APIs. +- A diverse array of animation APIs + By drawing from the standard SVG drawing capability and various open animation APIs, you can customize animation tracks by encapsulating physical models or calling the provided APIs. -- **State and data management** - State data management provides clear page update and rendering processes and pipes through decorators with different functions. State management covers UI component states and application states. With these features, you are able to build an application-wide data update and UI rendering process. +- State and data management + State data management provides clear page update and rendering processes and pipes through decorators with different functions. State management covers UI component states and application states. With these features, you are able to build an application-wide data update and UI rendering process. -- **System capability APIs** +- System capability APIs + Development has never been so easy, with a diverse array of encapsulated system capability APIs, from UI design to system capability invoking. - Development has never been so easy, with a diverse array of encapsulated system capability APIs, from UI design to system capability invoking. +## Overall Architecture -## Overall Architecture -![](figures/en-us_image_0000001169532276.png) -- **Declarative UI frontend** +![en-us_image_0000001223287712](figures/en-us_image_0000001223287712.png) - 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. +- 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. -- **Language runtime** +- Language runtime + Provides the parsing capability for the UI paradigm syntax and allows for cross-language API calls for a high-performance running environment of the TS language. - Provides the parsing capability for the UI paradigm syntax and allows for cross-language API calls for a high-performance running environment of the TS language. - -- **Declarative UI backend engine** - - Provides UI rendering pipelines that are compatible with different development paradigms, multiple basic components, layout calculation, dynamic effects, and interaction events, with state management and drawing capabilities. - -- **Render engine** - - Provides efficient drawing capabilities, which enable rendering instructions collected by the rendering pipeline to be drawn to the screen. - -- **Porting layer** - - Provides abstract APIs to connect to different systems, such as system rendering pipelines and lifecycle scheduling. +- Declarative UI backend engine + Provides UI rendering pipelines that are compatible with different development paradigms, multiple basic components, layout calculation, dynamic effects, and interaction events, with state management and drawing capabilities. +- Render engine + Provides efficient drawing capabilities, which enable rendering instructions collected by the rendering pipeline to be drawn to the screen. +- Porting layer + Provides abstract APIs to connect to different systems, such as system rendering pipelines and lifecycle scheduling. diff --git a/en/application-dev/ui/ui-ts-page-layout-connections.md b/en/application-dev/ui/ui-ts-page-layout-connections.md deleted file mode 100644 index b1ecb7fa250587d29c727f0d53d437efdc69f8b6..0000000000000000000000000000000000000000 --- a/en/application-dev/ui/ui-ts-page-layout-connections.md +++ /dev/null @@ -1,11 +0,0 @@ -# Defining Page Layout and Connection - -- **[Building a Food Data Model](ui-ts-building-data-model.md)** - -- **[Building a Food Category List Layout](ui-ts-building-category-list-layout.md)** - -- **[Building a Food Category Grid Layout](ui-ts-building-category-grid-layout.md)** - -- **[Implementing Page Redirection and Data Transmission](ui-ts-page-redirection-data-transmission.md)** - - diff --git a/en/application-dev/ui/ui-ts-page-redirection-data-transmission.md b/en/application-dev/ui/ui-ts-page-redirection-data-transmission.md index e1ef96fc52a31ee3659ae19d48cce27d80641153..575b56f4091b96d56c17146ad32d8aa75a94a3de 100644 --- a/en/application-dev/ui/ui-ts-page-redirection-data-transmission.md +++ b/en/application-dev/ui/ui-ts-page-redirection-data-transmission.md @@ -1,279 +1,282 @@ -# Implementing Page Redirection and Data Transmission +# Implementing Page Redirection and Data Transmission -This section describes how to implement page redirection and data transmission between pages: - -1. Page redirection: Click a food item on the food list page to go to the food details page. Click the back button on the food details page to go back to the food list page. -2. Data transmission between pages: After you click a food item, **FoodDetail** receives data from the previous page and renders the corresponding food details page. - -## Page Redirection - -The declarative UI paradigm provides two mechanisms for page redirection: - -1. **Navigator**: encapsulates the page routing capability. After the page target is specified, all child components in the page target have the routing capability. -2. Router APIs: called to implement various operations of page routing. You'll need to import **router** before calling the router APIs. - -The procedure below uses these two mechanisms for redirection between the page list page and food details page. - -1. Click **FoodListItem**. The **FoodDetail** page is displayed. Create a **Navigator** component in **FoodListItem** to enable its child components to have the routing function. The target page is **'pages/FoodDetail'**. - - ``` - @Component - struct FoodListItem { - private foodItem: FoodData - build() { - Navigator({ target: 'pages/FoodDetail' }) { - Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { - Image(this.foodItem.image) - .objectFit(ImageFit.Contain) - .height(40) - .width(40) - .backgroundColor('#FFf1f3f5') - .margin({ right: 16 }) - Text(this.foodItem.name) - .fontSize(14) - .flexGrow(1) - Text(this.foodItem.calories + ' kcal') - .fontSize(14) - } - .height(64) - } - .margin({ right: 24, left:32 }) - } - } - ``` - - ![](figures/listrouter.gif) - -2. Click **FoodGridItem**. The **FoodDetail** page is displayed. Import the **router** module, and then call the **push** API of this module to push the **FoodDetail** page to the route stack to implement page redirection. - - ``` - import router from '@system.router' - - @Component - struct FoodGridItem { - private foodItem: FoodData - build() { - Column() { - ...... - } - .height(184) - .width('100%') - .onClick(() => { - router.push({ uri: 'pages/FoodDetail' }) - }) - } - } - ``` - - ![](figures/routercategory.gif) -3. Add the icon for returning from the **FoodDetail** page to the food list page. Save the **Back.png** file to the **resources** \> **phone** \> **media** directory. Create a custom component **PageTitle**, which contains the back icon and Food Detail text. Call the **router.back\(\)** API of the router to display the top page of the route stack, that is, the upper-level page. - - ``` - // FoodDetail.ets - import router from '@system.router' - - @Component - struct PageTitle { - build() { - Flex({ alignItems: ItemAlign.Start }) { - Image($r('app.media.Back')) - .width(21.8) - .height(19.6) - Text('Food Detail') - .fontSize(21.8) - .margin({left: 17.4}) - } - .height(61) - .backgroundColor('#FFedf2f5') - .padding({ top: 13, bottom: 15, left: 28.3 }) - .onClick(() => { - router.back() - }) - } - } - ``` - -4. Create the Stack component in the **FoodDetail** component, including the **FoodImageDisplay** and **PageTitle** child components. Set the alignment mode to **TopStart**. - - ``` - @Entry - @Component - struct FoodDetail { - build() { - Column() { - Stack( { alignContent: Alignment.TopStart }) { - FoodImageDisplay() - PageTitle() - } - ContentTable() - } - .alignItems(HorizontalAlign.Center) - } - } - ``` - - ![](figures/en-us_image_0000001214998349.png) - - -## Data Transmission Between Pages - -We have implemented the redirection and going back of the **FoodCategoryList** and **FoodDetail** pages. At this point, the tomato details page is displayed no matter which **FoodListItem**/**FoodGridItem** is clicked. This is because the data transmission between pages is not yet configured. To configure data transmission between pages, set the routing with parameters as follows: - -1. Set the **params** attribute in the **Navigator** of the **FoodListItem** component. The **params** attribute accepts the key-value object. - - ``` - // FoodList.ets - @Component - struct FoodListItem { - private foodItem: FoodData - build() { - Navigator({ target: 'pages/FoodDetail' }) { - ...... - } - .params({ foodData: this.foodItem }) - } - } - ``` +This section describes how to implement page redirection and data transmission between pages: - The router API called by **FoodGridItem** also has the capability of redirection with parameters. The method of using the router API is similar to that of using the **Navigator**. - ``` - router.push({ - uri: 'pages/FoodDetail', - params: { foodData: this.foodItem } - }) - ``` +1. Page redirection: Click a food item on the food list page to go to the food details page. Click the back button on the food details page to go back to the food list page. -2. Import the **FoodData** class to the **FoodDetail** page and add the **foodItem** member variable to the **FoodDetail** component. +2. Data transmission between pages: After you click a food item, FoodDetail receives data from the previous page and renders the corresponding food details page. - ``` - // FoodDetail.ets - import { FoodData } from '../model/FoodData' - - @Entry - @Component - struct FoodDetail { - private foodItem: FoodData - build() { - ...... - } - } - ``` -3. Obtain the value of **foodData**. Call **router.getParams\(\).foodData** to obtain the data corresponding to **foodData** carried when the **FoodCategoryList** page is displayed. +## Page Redirection - ``` - @Entry - @Component - struct FoodDetail { - private foodItem: FoodData = router.getParams().foodData - - build() { - ...... - } - } - ``` +The declarative UI paradigm provides two mechanisms for page redirection: -4. Re-build the components on the **FoodDetail** page. During building, the food information on the **FoodDetail** page is all directly declared constants. You need to use the passed **FoodData** data to assign a new value to the constants. The code is as follows: +1. Navigator: encapsulates the page routing capability. After the page target is specified, all child components in the page target have the routing capability. - ``` - @Component - struct PageTitle { - build() { - Flex({ alignItems: ItemAlign.Start }) { - Image($r('app.media.Back')) - .width(21.8) - .height(19.6) - Text('Food Detail') - .fontSize(21.8) - .margin({left: 17.4}) - } - .height(61) - .backgroundColor('#FFedf2f5') - .padding({ top: 13, bottom: 15, left: 28.3 }) - .onClick(() => { - router.back() - }) - } - } - - @Component - struct FoodImageDisplay { - private foodItem: FoodData - build() { - Stack({ alignContent: Alignment.BottomStart }) { - Image(this.foodItem.image) - .objectFit(ImageFit.Contain) - Text(this.foodItem.name) - .fontSize(26) - .fontWeight(500) - .margin({ left: 26, bottom: 17.4 }) - } - .height(357) - .backgroundColor('#FFedf2f5') - } - } - - @Component - struct ContentTable { - private foodItem: FoodData - - @Builder IngredientItem(title:string, name: string, value: string) { - Flex() { - Text(title) - .fontSize(17.4) - .fontWeight(FontWeight.Bold) - .layoutWeight(1) - Flex() { - Text(name) - .fontSize(17.4) - .flexGrow(1) - Text(value) - .fontSize(17.4) - } - .layoutWeight(2) - } - } - - build() { - Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Start }) { - this.IngredientItem('Calories', 'Calories', this.foodItem.calories + 'kcal') - this.IngredientItem('Nutrition', 'Protein', this.foodItem.protein + 'g') - this.IngredientItem('', 'Fat', this.foodItem.fat + 'g') - this.IngredientItem('', 'Carbohydrates', this.foodItem.carbohydrates + 'g') - this.IngredientItem('', 'VitaminC', this.foodItem.vitaminC + 'mg') - } - .height(280) - .padding({ top: 30, right: 30, left: 30 }) - } - } - - @Entry - @Component - struct FoodDetail { - private foodItem: FoodData = router.getParams().foodData - - build() { - Column() { - Stack( { alignContent: Alignment.TopStart }) { - FoodImageDisplay({ foodItem: this.foodItem }) - PageTitle() - } - ContentTable({ foodItem: this.foodItem }) - } - .alignItems(HorizontalAlign.Center) - } - } - ``` +2. Router APIs: called to implement various operations of page routing. You'll need to import router before calling the router APIs. +The procedure below uses these two mechanisms for redirection between the page list page and food details page. -## Samples +1. Click FoodListItem. The FoodDetail page is displayed. Create a Navigator component in FoodListItem to enable its child components to have the routing function. The target page is 'pages/FoodDetail'. + + ``` + @Component + struct FoodListItem { + private foodItem: FoodData + build() { + Navigator({ target: 'pages/FoodDetail' }) { + Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { + Image(this.foodItem.image) + .objectFit(ImageFit.Contain) + .height(40) + .width(40) + .backgroundColor('#FFf1f3f5') + .margin({ right: 16 }) + Text(this.foodItem.name) + .fontSize(14) + .flexGrow(1) + Text(this.foodItem.calories + ' kcal') + .fontSize(14) + } + .height(64) + } + .margin({ right: 24, left:32 }) + } + } + ``` + + ![en-us_image_0000001223127744](figures/en-us_image_0000001223127744.gif) + +2. Click FoodGridItem. The FoodDetail page is displayed. Import the router module, and then call the push API of this module to push the FoodDetail page to the route stack to implement page redirection. + + ``` + import router from '@system.router' + + @Component + struct FoodGridItem { + private foodItem: FoodData + build() { + Column() { + ...... + } + .height(184) + .width('100%') + .onClick(() => { + router.push({ uri: 'pages/FoodDetail' }) + }) + } + } + ``` + + ![en-us_image_0000001267607909](figures/en-us_image_0000001267607909.gif) + +3. Add the icon for returning from the FoodDetail page to the food list page. Save the Back.png file to the resources > phone > media directory. Create a custom component PageTitle, which contains the back icon and Food Detail text. Call the router.back() API of the router to display the top page of the route stack, that is, the upper-level page. + + ``` + // FoodDetail.ets + import router from '@system.router' + + @Component + struct PageTitle { + build() { + Flex({ alignItems: ItemAlign.Start }) { + Image($r('app.media.Back')) + .width(21.8) + .height(19.6) + Text('Food Detail') + .fontSize(21.8) + .margin({left: 17.4}) + } + .height(61) + .backgroundColor('#FFedf2f5') + .padding({ top: 13, bottom: 15, left: 28.3 }) + .onClick(() => { + router.back() + }) + } + } + ``` + +4. Create the Stack component in the FoodDetail component, including the FoodImageDisplay and PageTitle child components. Set the alignment mode to TopStart. + + ``` + @Entry + @Component + struct FoodDetail { + build() { + Column() { + Stack( { alignContent: Alignment.TopStart }) { + FoodImageDisplay() + PageTitle() + } + ContentTable() + } + .alignItems(HorizontalAlign.Center) + } + } + ``` + + ![en-us_image_0000001267767881](figures/en-us_image_0000001267767881.png) + + +## Data Transmission Between Pages + +We have implemented the redirection and going back of the FoodCategoryList and FoodDetail pages. At this point, the tomato details page is displayed no matter which FoodListItem/FoodGridItem is clicked. This is because the data transmission between pages is not yet configured. To configure data transmission between pages, set the routing with parameters as follows: + +1. Set the params attribute in the Navigator of the FoodListItem component. The params attribute accepts the key-value object. + + ``` + // FoodList.ets + @Component + struct FoodListItem { + private foodItem: FoodData + build() { + Navigator({ target: 'pages/FoodDetail' }) { + ...... + } + .params({ foodData: this.foodItem }) + } + } + ``` + + The router API called by FoodGridItem also has the capability of redirection with parameters. The method of using the router API is similar to that of using the Navigator. + + + ``` + router.push({ + uri: 'pages/FoodDetail', + params: { foodData: this.foodItem } + }) + ``` + +2. Import the FoodData class to the FoodDetail page and add the foodItem member variable to the FoodDetail component. + + ``` + // FoodDetail.ets + import { FoodData } from '../model/FoodData' + + @Entry + @Component + struct FoodDetail { + private foodItem: FoodData + build() { + ...... + } + } + ``` + +3. Obtain the value of foodData. Call router.getParams().foodData to obtain the data corresponding to foodData carried when the FoodCategoryList page is displayed. + + ``` + @Entry + @Component + struct FoodDetail { + private foodItem: FoodData = router.getParams().foodData + + build() { + ...... + } + } + ``` + +4. Re-build the components on the FoodDetail page. During building, the food information on the FoodDetail page is all directly declared constants. You need to use the passed FoodData data to assign a new value to the constants. The code is as follows: + + ``` + @Component + struct PageTitle { + build() { + Flex({ alignItems: ItemAlign.Start }) { + Image($r('app.media.Back')) + .width(21.8) + .height(19.6) + Text('Food Detail') + .fontSize(21.8) + .margin({left: 17.4}) + } + .height(61) + .backgroundColor('#FFedf2f5') + .padding({ top: 13, bottom: 15, left: 28.3 }) + .onClick(() => { + router.back() + }) + } + } + + @Component + struct FoodImageDisplay { + private foodItem: FoodData + build() { + Stack({ alignContent: Alignment.BottomStart }) { + Image(this.foodItem.image) + .objectFit(ImageFit.Contain) + Text(this.foodItem.name) + .fontSize(26) + .fontWeight(500) + .margin({ left: 26, bottom: 17.4 }) + } + .height(357) + .backgroundColor('#FFedf2f5') + } + } + + @Component + struct ContentTable { + private foodItem: FoodData + + @Builder IngredientItem(title:string, name: string, value: string) { + Flex() { + Text(title) + .fontSize(17.4) + .fontWeight(FontWeight.Bold) + .layoutWeight(1) + Flex() { + Text(name) + .fontSize(17.4) + .flexGrow(1) + Text(value) + .fontSize(17.4) + } + .layoutWeight(2) + } + } + + build() { + Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Start }) { + this.IngredientItem('Calories', 'Calories', this.foodItem.calories + 'kcal') + this.IngredientItem('Nutrition', 'Protein', this.foodItem.protein + 'g') + this.IngredientItem('', 'Fat', this.foodItem.fat + 'g') + this.IngredientItem('', 'Carbohydrates', this.foodItem.carbohydrates + 'g') + this.IngredientItem('', 'VitaminC', this.foodItem.vitaminC + 'mg') + } + .height(280) + .padding({ top: 30, right: 30, left: 30 }) + } + } + + @Entry + @Component + struct FoodDetail { + private foodItem: FoodData = router.getParams().foodData + + build() { + Column() { + Stack( { alignContent: Alignment.TopStart }) { + FoodImageDisplay({ foodItem: this.foodItem }) + PageTitle() + } + ContentTable({ foodItem: this.foodItem }) + } + .alignItems(HorizontalAlign.Center) + } + } + ``` + +## Samples The following sample is provided to help you better understand how to define the page layout and connection: -- [eTSDefiningPageLayoutAndConnection](https://gitee.com/openharmony/app_samples/tree/master/ETSUI/eTSDefiningPageLayoutAndConnection) - - This sample exemplifies the basic usage of the list layout, grid layout, and page routing, by building the food list page and food details page. - +- [eTSDefiningPageLayoutAndConnection](https://gitee.com/openharmony/app_samples/tree/master/ETSUI/eTSDefiningPageLayoutAndConnection) + This sample exemplifies the basic usage of the list layout, grid layout, and page routing, by building the food list page and food details page. diff --git a/zh-cn/application-dev/ui/figures/zh-cn_image_0000001148858818.png b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001148858818.png index 345a2be66315d210a86c20d30c56b8b5f487c325..3be38a7df454954c455b44bb1fbb6b2158be3785 100644 Binary files a/zh-cn/application-dev/ui/figures/zh-cn_image_0000001148858818.png and b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001148858818.png differ diff --git a/zh-cn/application-dev/ui/figures/zh-cn_image_0000001167746622.png b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001167746622.png index f7b8012da47797dfd3909843cba9af1468fb4e89..e53f6d7e1c8b3060ae000d78555ea0b33ffc97bf 100644 Binary files a/zh-cn/application-dev/ui/figures/zh-cn_image_0000001167746622.png and b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001167746622.png differ diff --git a/zh-cn/application-dev/ui/figures/zh-cn_image_0000001168059158.png b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001168059158.png index 1b9259dc9c0a7cb3530e3f7d9b0225e5160b92c8..205d18f50424811f04dcecc1b6a95c52530c6527 100644 Binary files a/zh-cn/application-dev/ui/figures/zh-cn_image_0000001168059158.png and b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001168059158.png differ diff --git a/zh-cn/application-dev/ui/figures/zh-cn_image_0000001168570318.png b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001168570318.png index 5e855312aef77f5badc0c0b0b4d5cbeac23b802f..d8f65fa710293636817f62b13aca13791e8c579d 100644 Binary files a/zh-cn/application-dev/ui/figures/zh-cn_image_0000001168570318.png and b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001168570318.png differ diff --git a/zh-cn/application-dev/ui/figures/zh-cn_image_0000001168956332.png b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001168956332.png index 15a7e0bdc38655a23f64bfa56c4adad9a6a199a0..adb255e05d2f54161e79e0f0a21ddc6b04552793 100644 Binary files a/zh-cn/application-dev/ui/figures/zh-cn_image_0000001168956332.png and b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001168956332.png differ diff --git a/zh-cn/application-dev/ui/figures/zh-cn_image_0000001214330169.png b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001214330169.png index 19ee7009247945887ceb0f8f6f471e45f3116b70..f0c016e9fa69e07581cda8d89f13d5b56f91cc7f 100644 Binary files a/zh-cn/application-dev/ui/figures/zh-cn_image_0000001214330169.png and b/zh-cn/application-dev/ui/figures/zh-cn_image_0000001214330169.png differ diff --git a/zh-cn/application-dev/ui/ui-ts-creating-project.md b/zh-cn/application-dev/ui/ui-ts-creating-project.md index 010b44121b4964354a23377ce81e3e60bf4b77e1..ce681733ccdc518f519fb5fddddc815baf6a83f7 100644 --- a/zh-cn/application-dev/ui/ui-ts-creating-project.md +++ b/zh-cn/application-dev/ui/ui-ts-creating-project.md @@ -6,25 +6,22 @@ 1. 打开DevEco Studio,点击Create Project。如果已有一个工程,则点击File > New > New project。 + ![zh-cn_image_0000001168956332](figures/zh-cn_image_0000001168956332.png) 2. - 进入选择ability template界面,选择[Standard]Empty Ability。 + 进入选择Ability Template界面,选择Empty Ability。 ![zh-cn_image_0000001168059158](figures/zh-cn_image_0000001168059158.png) -3. - 安装OpenHarmony SDK。 - - ![zh-cn_image_0000001213462329](figures/zh-cn_image_0000001213462329.png) - -4. 进入配置工程界面,将工程名字改为HealthyDiet,Project Type选择Application,Device Type选择Phone,Language选择eTS,选择兼容API Version 7。DevEco Studio会默认将工程保存在C盘,如果要更改工程保存位置,点击Save Location的文件夹图标,自行指定工程创建位置。配置完成后点击Finish。 - +4. 进入配置工程界面,将工程名字改为HealthyDiet,Project Type选择Application,Compile API选择8,UI Syntax选择eTS。DevEco Studio会默认将工程保存在C盘,如果要更改工程保存位置,点击Save Location的文件夹图标,自行指定工程创建位置。配置完成后点击Finish。 + ![zh-cn_image_0000001167746622](figures/zh-cn_image_0000001167746622.png) 5. 工程创建完成后,打开app.ets。 app.ets提供了应用生命周期的接口:onCreate和onDestroy,分别在应用创建之初和应用被销毁时调用。在app.ets里可以声明全局变量,并且声明的数据和方法是整个应用共享的。 + ``` export default { onCreate() { @@ -35,7 +32,7 @@ }, } ``` - + 6. 在工程导航栏里,打开index.ets。该页面展示了当前的UI描述,声明式UI框架会自动生成一个组件化的struct,这个struct遵循Builder接口声明,在build方法里面声明当前的布局和组件。 ``` @Entry diff --git a/zh-cn/application-dev/ui/ui-ts-creating-simple-page.md b/zh-cn/application-dev/ui/ui-ts-creating-simple-page.md index bed0ef4e7477d279f345db2a80e0bf23cf38bca2..615cd88da59eb938fad5247d03bc8be0b4f93408 100644 --- a/zh-cn/application-dev/ui/ui-ts-creating-simple-page.md +++ b/zh-cn/application-dev/ui/ui-ts-creating-simple-page.md @@ -24,7 +24,7 @@ ![zh-cn_image_0000001214128687](figures/zh-cn_image_0000001214128687.png) 2. 食物图片展示。 - 创建Image组件,指定Image组件的url,Image组件和Text组件都是必选构造参数组件。为了让Text组件在Image组件上方显示,所以要先声明Image组件。图片资源放在resources下的rawfile文件夹内,引用rawfile下资源时使用```“$rawfile('filename')”```的形式,filename为rawfile目录下的文件相对路径。当前$rawfile仅支持Image控件引用图片资源。 + 创建Image组件,指定Image组件的url,Image组件和Text组件都是必选构造参数组件。为了让Text组件在Image组件上方显示,所以要先声明Image组件。图片资源放在resources下的rawfile文件夹内,引用rawfile下资源时使用“$rawfile('filename')”的形式,filename为rawfile目录下的文件相对路径。当前$rawfile仅支持Image控件引用图片资源。 ``` @Entry @Component @@ -47,11 +47,11 @@ ![zh-cn_image_0000001168570318](figures/zh-cn_image_0000001168570318.png) - 点击OK后,resources文件夹下生成phone.media文件夹。将Tomato.png放入该文件夹内。 + 点击OK后,resources文件夹下生成phone文件夹,phone文件夹下生成media文件夹,将Tomato.png放入media文件夹内。 ![zh-cn_image_0000001214330169](figures/zh-cn_image_0000001214330169.png) - 就可以通过```“$r('app.type.name')”```的形式引用应用资源,即$r('app.media.Tomato')。 + 就可以通过“$r('app.type.name')”的形式引用应用资源,即$r('app.media.Tomato')。 ``` @Entry @@ -73,7 +73,7 @@ 4. 设置Image宽高,并且将image的objectFit属性设置为ImageFit.Contain,即保持图片长宽比的情况下,使得图片完整地显示在边界内。 如果Image填满了整个屏幕,原因如下: 1. Image没有设置宽高。 - + 2. Image的objectFit默认属性是ImageFit.Cover,即在保持长宽比的情况下放大或缩小,使其填满整个显示边界。 ``` @@ -183,7 +183,7 @@ .backgroundColor('#FFedf2f5') } } - + @Entry @Component struct FoodDetail { @@ -218,12 +218,12 @@ .backgroundColor('#FFedf2f5') } } - + @Component struct ContentTable { build() {} } - + @Entry @Component struct FoodDetail { @@ -261,7 +261,7 @@ .padding({ top: 30, right: 30, left: 30 }) } } - + @Entry @Component struct FoodDetail { @@ -294,7 +294,7 @@ .backgroundColor('#FFedf2f5') } } - + @Component struct ContentTable { build() { @@ -316,7 +316,7 @@ .padding({ top: 30, right: 30, left: 30 }) } } - + @Entry @Component struct FoodDetail { @@ -415,7 +415,7 @@ .padding({ top: 30, right: 30, left: 30 }) } } - + @Entry @Component struct FoodDetail { @@ -502,7 +502,7 @@ .layoutWeight(2) } } - + build() { Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Start }) { this.IngredientItem('Calories', 'Calories', '17kcal') @@ -515,7 +515,7 @@ .padding({ top: 30, right: 30, left: 30 }) } } - + @Entry @Component struct FoodDetail {