diff --git a/ArkUIKit/ChooseComponent/entry/src/main/ets/pages/button/ButtonCustomStyle.ets b/ArkUIKit/ChooseComponent/entry/src/main/ets/pages/button/ButtonCustomStyle.ets index 78d7808b6b623569c27b297741b576d5bf69b934..023fa4d5d6374de967068d95615cc4bf0f76ab24 100644 --- a/ArkUIKit/ChooseComponent/entry/src/main/ets/pages/button/ButtonCustomStyle.ets +++ b/ArkUIKit/ChooseComponent/entry/src/main/ets/pages/button/ButtonCustomStyle.ets @@ -55,7 +55,6 @@ export struct ButtonCustomStyle { .fontWeight(800) // [End custom_font_style] - // [Start custom_font_style2] Button('font style', { type: ButtonType.Normal }) .fontSize(20) diff --git a/ArkUIKit/ChooseComponent/entry/src/main/ets/pages/toggle/CreateToggle.ets b/ArkUIKit/ChooseComponent/entry/src/main/ets/pages/toggle/CreateToggle.ets index a9ffad560d8bdfca47a5d2c9b271a7e9b298a149..af67afbb143e59c5ec9d3995922297faa0c7c1f4 100644 --- a/ArkUIKit/ChooseComponent/entry/src/main/ets/pages/toggle/CreateToggle.ets +++ b/ArkUIKit/ChooseComponent/entry/src/main/ets/pages/toggle/CreateToggle.ets @@ -28,8 +28,8 @@ export struct CreateToggle { title: 'ToggleType is Checkbox', }) { // [Start create_toggle_with_checkbox] - Toggle({ type: ToggleType.Checkbox, isOn: false }).id('toggle1') - Toggle({ type: ToggleType.Checkbox, isOn: true }).id('toggle2') + Toggle({ type: ToggleType.Checkbox, isOn: false }).id('toggle1') // 请开发者替换为实际的id + Toggle({ type: ToggleType.Checkbox, isOn: true }).id('toggle2') // 请开发者替换为实际的id // [End create_toggle_with_checkbox] } diff --git a/ArkUIKit/CustomComponentsFreeze/README_zh.md b/ArkUIKit/CustomComponentsFreeze/README_zh.md index 99faa215e7c500b16ab7e7e1e2fc8149f65cc27e..c5f5c8b721b3ecc95a8ec7cc961339b81362df35 100644 --- a/ArkUIKit/CustomComponentsFreeze/README_zh.md +++ b/ArkUIKit/CustomComponentsFreeze/README_zh.md @@ -10,7 +10,7 @@ ### 3.[Button](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-button.md) -### 3[ 自定义组件冻结功能](https://docs.openharmony.cn/pages/v5.1/zh-cn/application-dev/ui/state-management/arkts-custom-components-freeze.md) +### 4.[ 自定义组件冻结功能](https://docs.openharmony.cn/pages/v5.1/zh-cn/application-dev/ui/state-management/arkts-custom-components-freeze.md) ### 效果预览 diff --git a/ArkUIKit/CustomComponentsFreeze/entry/src/main/ets/View/MyNavigationTestStack.ets b/ArkUIKit/CustomComponentsFreeze/entry/src/main/ets/View/MyNavigationTestStack.ets index 03fe48ca28836b16e6e08187610fdfb24eeac2a0..2cedcbcbfcd1523f2de0f7aeafc72fd1b1f042c2 100644 --- a/ArkUIKit/CustomComponentsFreeze/entry/src/main/ets/View/MyNavigationTestStack.ets +++ b/ArkUIKit/CustomComponentsFreeze/entry/src/main/ets/View/MyNavigationTestStack.ets @@ -177,8 +177,8 @@ struct NavigationContentMsgStack { @Link logNumber: number; info() { - hilog.info(0x0000, 'freeze-test NavigationContent message callback', 'FreezeChild message callback func %{public}d, index: %{public}d', this.message) - hilog.info(0x0000, 'freeze-test ---- called by content', 'FreezeChild message callback func %{public}d, index: %{public}d', this.index) + hilog.info(0x0000, 'FreezeChild', `freeze-test NavigationContent message callback ${this.message}`); + hilog.info(0x0000, 'FreezeChild', `freeze-test ---- called by content ${this.index}`); this.logNumber++; } diff --git a/ArkUIKit/CustomLifecycle/README_zh.md b/ArkUIKit/CustomLifecycle/README_zh.md index ff8cd3f9928492b669794b9495cecc990c0cd1fb..97a206e9a4c0b01371f051bec4cc5857a89a21a7 100644 --- a/ArkUIKit/CustomLifecycle/README_zh.md +++ b/ArkUIKit/CustomLifecycle/README_zh.md @@ -1,9 +1,9 @@ -# ArkUI使用支持交互事件指南文档示例 +# ArkUI使用自定义组件生命周期指南文档示例 ### 介绍 本示例通过使用[ArkUI指南文档](https://gitee.com/openharmony/docs/tree/master/zh-cn/application-dev/ui) -中各场景的开发示例,展示在工程中,帮助开发者更好地理解ArkUI提供的组件及组件属性并合理使用。 +中各场景的开发示例,展示在工程中,帮助开发者更好地理解ArkUI提供的自定义组件生命周期并合理使用。 ### 效果预览 diff --git a/ArkUIKit/CustomLifecycle/entry/src/main/ets/pages/parent/Index.ets b/ArkUIKit/CustomLifecycle/entry/src/main/ets/pages/parent/Index.ets index bebe363e6d47622919dfba1ae2c0227110f407d6..7baedefadcf85581dd957a2511e3eb797d2ad997 100644 --- a/ArkUIKit/CustomLifecycle/entry/src/main/ets/pages/parent/Index.ets +++ b/ArkUIKit/CustomLifecycle/entry/src/main/ets/pages/parent/Index.ets @@ -14,7 +14,8 @@ */ // [Start nested_custom_components] -// Index.ets +import { hilog } from '@kit.PerformanceAnalysisKit'; + @Entry @Component struct Parent { @@ -23,17 +24,17 @@ struct Parent { // 组件生命周期 aboutToAppear() { - console.info('Parent aboutToAppear'); + hilog.info(0x0000, 'testTag', 'Parent aboutToAppear'); } // 组件生命周期 onDidBuild() { - console.info('Parent onDidBuild'); + hilog.info(0x0000, 'testTag', 'Parent onDidBuild'); } // 组件生命周期 aboutToDisappear() { - console.info('Parent aboutToDisappear'); + hilog.info(0x0000, 'testTag', 'Parent aboutToDisappear'); } build() { @@ -60,17 +61,17 @@ struct Child { // 组件生命周期 aboutToDisappear() { - console.info('Child aboutToDisappear'); + hilog.info(0x0000, 'testTag', 'Child aboutToDisappear'); } // 组件生命周期 onDidBuild() { - console.info('Child onDidBuild'); + hilog.info(0x0000, 'testTag', 'Child onDidBuild'); } // 组件生命周期 aboutToAppear() { - console.info('Child aboutToAppear'); + hilog.info(0x0000, 'testTag', 'Child aboutToAppear'); } build() { diff --git a/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageFiveShare2.ets b/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageFiveShare2.ets index 074c0b4b39ca0176a98c79378bce908016fb2d88..f34f85985e9ec0fa3259cda32e1423f5b863d74d 100644 --- a/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageFiveShare2.ets +++ b/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageFiveShare2.ets @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - // [Start localtorage_page_five_share2] +// [Start localtorage_page_five_share2] // Page.ets @Builder @@ -21,7 +21,6 @@ export function PageBuilder() { } // Page组件获得了父亲Index组件的LocalStorage实例 -@Entry @Component struct Page { @LocalStorageLink('PropA') propA: number = 2; diff --git a/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageSixLocalStorage.ets b/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageSixLocalStorage.ets index a01d34f95ae27f5dc161dd8355a3f2a191fcaaf5..8195b23f84a7ead1efd9fb79d69d63b953cc4d5a 100644 --- a/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageSixLocalStorage.ets +++ b/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageSixLocalStorage.ets @@ -32,7 +32,7 @@ struct TestIndex { Text(this.propA) .fontSize(50) .fontWeight(FontWeight.Bold) - // 使用LocalStorage 实例localStorage2 + // 使用LocalStorage 实例localStorage2A Child6({ count: this.count }, localStorage2A) } .width('100%') @@ -45,7 +45,7 @@ struct TestIndex { @Component struct Child6 { @Link count: number; - // 'Hello World'和localStorage2中'PropB'的双向同步,如果localStorage2中没有'PropB',则使用默认值'Hello World' + // 'Hello World'和localStorage2A中'PropB'的双向同步,如果localStorage2A中没有'PropB',则使用默认值'Hello World' @LocalStorageLink('PropB') propB: string = 'Hello World'; build() { diff --git a/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageSixLocalStorageA.ets b/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageSixLocalStorageA.ets index 72f1ae64008b1e13aabd61718106b146b4b52681..183deef7bcd69f6ac6f77e2f42594cf301b99af2 100644 --- a/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageSixLocalStorageA.ets +++ b/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageSixLocalStorageA.ets @@ -13,16 +13,16 @@ * limitations under the License. */ // [Start localtorage_page_six_local_storageA] -let localStorage1A: LocalStorage = new LocalStorage(); -localStorage1A.setOrCreate('propA', 'propA'); +let localStorageA0: LocalStorage = new LocalStorage(); +localStorageA0.setOrCreate('propA', 'propA'); -let localStorage2: LocalStorage = new LocalStorage(); -localStorage2.setOrCreate('propB', 'propB'); +let localStorageB0: LocalStorage = new LocalStorage(); +localStorageB0.setOrCreate('propB', 'propB'); -@Entry(localStorage1A) +@Entry(localStorageA0) @Component struct AIndex { - // 'PropA',和localStorage1中'PropA'的双向同步 + // 'PropA',和localStorageA0中'PropA'的双向同步 @LocalStorageLink('PropA') propA: string = 'Hello World'; @State count: number = 0; @@ -32,8 +32,8 @@ struct AIndex { Text(this.propA) .fontSize(50) .fontWeight(FontWeight.Bold) - // 使用LocalStorage 实例localStorage2 - AChild(localStorage2) + // 使用LocalStorage 实例localStorageB0 + AChild(localStorageB0) } .width('100%') } diff --git a/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageSixLocalStorageB.ets b/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageSixLocalStorageB.ets index bcb7f5e37f1743dab9f807bdf4779912556ab425..2c26903687e0c051203092c5ba08c06d239cefe6 100644 --- a/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageSixLocalStorageB.ets +++ b/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageSixLocalStorageB.ets @@ -13,16 +13,16 @@ * limitations under the License. */ // [Start localtorage_page_six_local_storageB] -let localStorage1B: LocalStorage = new LocalStorage(); -localStorage1B.setOrCreate('propA', 'propA'); +let localStorageB1: LocalStorage = new LocalStorage(); +localStorageB1.setOrCreate('propA', 'propA'); -let localStorage2B: LocalStorage = new LocalStorage(); -localStorage2B.setOrCreate('propB', 'propB'); +let localStorageB2: LocalStorage = new LocalStorage(); +localStorageB2.setOrCreate('propB', 'propB'); -@Entry(localStorage1B) +@Entry(localStorageB1) @Component struct BIndex { - // 'PropA',和localStorage1中'PropA'的双向同步 + // 'PropA',和localStorageB1中'propA'的双向同步 @LocalStorageLink('PropA') propA: string = 'Hello World'; @State count: number = 0; @@ -32,8 +32,8 @@ struct BIndex { Text(this.propA) .fontSize(50) .fontWeight(FontWeight.Bold) - // 使用LocalStorage 实例localStorage2 - BChild({}, localStorage2B) + // 使用LocalStorage 实例localStorageB2 + BChild({}, localStorageB2) } .width('100%') } @@ -44,7 +44,7 @@ struct BIndex { @Component struct BChild { @State count: number = 5; - // 'Hello World',和localStorage2中'PropB'的双向同步,如果localStorage2中没有'PropB',则使用默认值'Hello World' + // 'Hello World',和localStorageB2中'propB'的双向同步,如果localStorageB2中没有'propB',则使用默认值'Hello World' @LocalStorageLink('PropB') propB: string = 'Hello World'; build() { diff --git a/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageTowSigleSYN.ets b/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageTowSigleSYN.ets index 93c540ecdc151bb308a28881b5543552c26f9822..b8fa25d50397e04afdda3b8920f734323bcb940c 100644 --- a/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageTowSigleSYN.ets +++ b/ArkUIKit/LocalStorage/entry/src/main/ets/pages/PageTowSigleSYN.ets @@ -12,10 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +// [Start localtorage_page_tow_sigle_syn] // 创建新实例并使用给定对象初始化 +let para0: Record = { 'PropA': 47 }; +let storage0: LocalStorage = new LocalStorage(para0); // 使LocalStorage可从@Component组件访问 -// [Start localtorage_page_tow_sigle_syn] -@Entry +@Entry(storage0) @Component struct Parent1 { // @LocalStorageProp变量装饰器与LocalStorage中的'PropA'属性建立单向绑定 diff --git a/ArkUIKit/LocalStorage/entry/src/main/resources/base/profile/main_pages.json b/ArkUIKit/LocalStorage/entry/src/main/resources/base/profile/main_pages.json index f7a31f81792667b62a2537ca6a176426881fb155..71cd980b6a5d4964bf3a02dcbbdfeacb2ed1532c 100644 --- a/ArkUIKit/LocalStorage/entry/src/main/resources/base/profile/main_pages.json +++ b/ArkUIKit/LocalStorage/entry/src/main/resources/base/profile/main_pages.json @@ -6,7 +6,6 @@ "pages/PageTwoWaySYN", "pages/PageFourStateVariableSYN", "pages/PageFiveShare", - "pages/PageFiveShare2", "pages/PageSixLocalStorage", "pages/PageSixLocalStorageA", "pages/PageSixLocalStorageB", diff --git a/ArkUIKit/LocalStorage/entry/src/ohosTest/ets/test/Index.test.ets b/ArkUIKit/LocalStorage/entry/src/ohosTest/ets/test/Index.test.ets index 407134b935e24fe94ee8d345a68f8e3ab11fbaa1..99fa632454df762d212bc40c83dd99e4b25dda5f 100644 --- a/ArkUIKit/LocalStorage/entry/src/ohosTest/ets/test/Index.test.ets +++ b/ArkUIKit/LocalStorage/entry/src/ohosTest/ets/test/Index.test.ets @@ -253,11 +253,6 @@ export default function IndexTest() { expect(button1 === null).assertFalse(); await button1.click(); await driver.delayMs(1000); - let button2 = await driver.findComponent(ON.text('Change propA', MatchPattern.CONTAINS)); - expect(button2 === null).assertFalse(); - await button2.click(); - await driver.delayMs(1000); - await driver.pressBack(); console.info('uitest: PageElevenTest end'); done(); }) diff --git a/ArkUIKit/NativeDialogSample/entry/src/main/cpp/customdialog/nativedialogdemo.cpp b/ArkUIKit/NativeDialogSample/entry/src/main/cpp/customdialog/nativedialogdemo.cpp index 3fdeed02746cebac2332281175bafe75a0c267f6..1fd43c3ad69ee26a7ead4ce970e6e7ff7e012bd4 100644 --- a/ArkUIKit/NativeDialogSample/entry/src/main/cpp/customdialog/nativedialogdemo.cpp +++ b/ArkUIKit/NativeDialogSample/entry/src/main/cpp/customdialog/nativedialogdemo.cpp @@ -35,12 +35,34 @@ void CloseDialog(); void OnButtonClicked(ArkUI_NodeEvent *event); void MainViewMethod(ArkUI_NodeContentHandle handle); +// [Start dialog_create] +ArkUI_NativeDialogHandle g_dialogController = nullptr; +// [StartExclude dialog_create] +// [Start show_dialog] +void ShowDialog() +{ + // [EndExclude dialog_create] + ArkUI_NativeDialogAPI_1 *dialogAPI = reinterpret_cast( + OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_DIALOG, "ArkUI_NativeDialogAPI_1")); + if (!g_dialogController) { + g_dialogController = dialogAPI->create(); + } + // [End dialog_create] + auto contentNode = CreateDialogContent(); + dialogAPI->setContent(g_dialogController, contentNode); + dialogAPI->setContentAlignment(g_dialogController, static_cast(ARKUI_ALIGNMENT_BOTTOM), 0, 0); + dialogAPI->setBackgroundColor(g_dialogController, 0xffffffff); + dialogAPI->setCornerRadius(g_dialogController, 6.0f, 6.0f, 6.0f, 6.0f); + dialogAPI->setModalMode(g_dialogController, false); + dialogAPI->setAutoCancel(g_dialogController, true); + dialogAPI->show(g_dialogController, false); +} +// [End show_dialog] + // 创建可交互界面,点击Button后弹窗 // [Start main_view] constexpr int32_t BUTTON_CLICK_ID = 1; -bool g_isShown = false; -ArkUI_NativeDialogHandle g_dialogController = nullptr; -ArkUI_NodeHandle g_buttonNode; +ArkUI_NodeHandle g_buttonNode = nullptr; void MainViewMethod(ArkUI_NodeContentHandle handle) { @@ -110,26 +132,6 @@ ArkUI_NodeHandle CreateDialogContent() } // [End create_content] -// [Start show_dialog] -void ShowDialog() -{ - // [Start dialog_create] - ArkUI_NativeDialogAPI_1 *dialogAPI = reinterpret_cast( - OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_DIALOG, "ArkUI_NativeDialogAPI_1")); - if (!g_dialogController) { - g_dialogController = dialogAPI->create(); - } - // [End dialog_create] - auto contentNode = CreateDialogContent(); - dialogAPI->setContent(g_dialogController, contentNode); - dialogAPI->setContentAlignment(g_dialogController, static_cast(ARKUI_ALIGNMENT_BOTTOM), 0, 0); - dialogAPI->setBackgroundColor(g_dialogController, 0xffffffff); - dialogAPI->setModalMode(g_dialogController, false); - dialogAPI->setAutoCancel(g_dialogController, true); - dialogAPI->show(g_dialogController, false); -} -// [End show_dialog] - // [Start close_controller] void CloseDialog() { @@ -142,6 +144,8 @@ void CloseDialog() // 触发controller弹窗 // [Start controller_click] +bool g_isShown = false; + void OnButtonClicked(ArkUI_NodeEvent *event) { if (!event || !g_buttonNode) { @@ -209,8 +213,6 @@ void MainViewMethod(ArkUI_NodeContentHandle handle); void OpenDialogCallBack(int32_t dialogId); void OnButtonClicked(ArkUI_NodeEvent *event); -ArkUI_NodeHandle g_buttonNode = nullptr; -ArkUI_CustomDialogOptions* g_dialogOptions = nullptr; constexpr int32_t BUTTON_CLICK_ID = 1; bool g_isShown = false; @@ -249,6 +251,7 @@ ArkUI_NodeHandle CreateDialogContent() } // 触发dialogOptions弹窗 +ArkUI_CustomDialogOptions* g_dialogOptions = nullptr; // [Start open_dialogOption] int32_t g_id = 0; void OpenDialogCallBack(int32_t dialogId) @@ -264,6 +267,7 @@ void OpenCustomDialog() } OH_ArkUI_CustomDialog_SetAlignment(g_dialogOptions, static_cast(ARKUI_ALIGNMENT_BOTTOM), 0, 0); OH_ArkUI_CustomDialog_SetBackgroundColor(g_dialogOptions, 0xffffffff); + OH_ArkUI_CustomDialog_SetCornerRadius(g_dialogOptions, 6.0f, 6.0f, 6.0f, 6.0f); OH_ArkUI_CustomDialog_SetModalMode(g_dialogOptions, false); OH_ArkUI_CustomDialog_SetAutoCancel(g_dialogOptions, true); OH_ArkUI_CustomDialog_SetBorderStyle(g_dialogOptions, ARKUI_BORDER_STYLE_SOLID, @@ -279,6 +283,32 @@ void CloseCustomDialog() } // [End close_option] +ArkUI_NodeHandle g_buttonNode = nullptr; +// [Start option_click] +void OnButtonClicked(ArkUI_NodeEvent *event) +{ + if (!event || !g_buttonNode) { + return; + } + auto eventId = OH_ArkUI_NodeEvent_GetTargetId(event); + if (eventId == BUTTON_CLICK_ID) { + ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast( + OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1")); + if (g_isShown) { + g_isShown = false; + ArkUI_AttributeItem labelItem = {.string = "显示弹窗"}; + nodeAPI->setAttribute(g_buttonNode, NODE_BUTTON_LABEL, &labelItem); + CloseCustomDialog(); + } else { + g_isShown = true; + ArkUI_AttributeItem labelItem = {.string = "关闭弹窗"}; + nodeAPI->setAttribute(g_buttonNode, NODE_BUTTON_LABEL, &labelItem); + OpenCustomDialog(); + } + } +} +// [End option_click] + // 创建可交互界面,点击Button后弹窗 void MainViewMethod(ArkUI_NodeContentHandle handle) { @@ -313,31 +343,6 @@ void MainViewMethod(ArkUI_NodeContentHandle handle) OH_ArkUI_NodeContent_AddNode(handle, column); } -// [Start option_click] -void OnButtonClicked(ArkUI_NodeEvent *event) -{ - if (!event || !g_buttonNode) { - return; - } - auto eventId = OH_ArkUI_NodeEvent_GetTargetId(event); - if (eventId == BUTTON_CLICK_ID) { - ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast( - OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1")); - if (g_isShown) { - g_isShown = false; - ArkUI_AttributeItem labelItem = {.string = "显示弹窗"}; - nodeAPI->setAttribute(g_buttonNode, NODE_BUTTON_LABEL, &labelItem); - CloseCustomDialog(); - } else { - g_isShown = true; - ArkUI_AttributeItem labelItem = {.string = "关闭弹窗"}; - nodeAPI->setAttribute(g_buttonNode, NODE_BUTTON_LABEL, &labelItem); - OpenCustomDialog(); - } - } -} -// [End option_click] - // 退出时删除dialogController napi_value Dispose(napi_env env, napi_callback_info info) { @@ -345,9 +350,7 @@ napi_value Dispose(napi_env env, napi_callback_info info) napi_get_undefined(env, &result); // 返回undefined表示void if (g_dialogOptions) { - // [Start dialog_disposeOption] OH_ArkUI_CustomDialog_DisposeOptions(g_dialogOptions); - // [End dialog_disposeOption] g_dialogOptions = nullptr; } return result; @@ -378,7 +381,6 @@ void OpenDialogCallBack(int32_t dialogId); void OnButtonClicked(ArkUI_NodeEvent *event); ArkUI_NodeHandle g_buttonNode = nullptr; -ArkUI_CustomDialogOptions* g_dialogOptions = nullptr; constexpr int32_t BUTTON_CLICK_ID = 1; bool g_isShown = false; @@ -389,9 +391,12 @@ void OpenDialogCallBack(int32_t dialogId) g_id = dialogId; } +// [Start dialog_createOption] +ArkUI_CustomDialogOptions* g_dialogOptions = nullptr; +// [StartExclude dialog_createOption] void OpenTextDialog() { - // [Start dialog_createOption] + // [EndExclude dialog_createOption] auto textNode = std::make_shared(); if (!g_dialogOptions) { g_dialogOptions = OH_ArkUI_CustomDialog_CreateOptions(textNode->GetHandle()); @@ -476,7 +481,9 @@ napi_value Dispose(napi_env env, napi_callback_info info) napi_get_undefined(env, &result); // 返回undefined表示void if (g_dialogOptions) { + // [Start dialog_disposeOption] OH_ArkUI_CustomDialog_DisposeOptions(g_dialogOptions); + // [End dialog_disposeOption] g_dialogOptions = nullptr; } return result; diff --git a/ArkUIKit/NativeType/CustomRenderNode/README.md b/ArkUIKit/NativeType/CustomRenderNode/README.md index 57224c10233d8b69b4a227698820b07f1bd8a10f..63f8b9989a02ac99e2dc0f9d32a1b1bc7a67f5db 100644 --- a/ArkUIKit/NativeType/CustomRenderNode/README.md +++ b/ArkUIKit/NativeType/CustomRenderNode/README.md @@ -51,11 +51,27 @@ entry/src/main/ ## 具体实现 1. 创建和删除节点。 + + RenderNode提供了节点创建和删除的能力。可以通过RenderNode的构造函数创建自定义的RenderNode节点。通过构造函数创建的节点对应一个实体的节点。同时,可以通过RenderNode中的[dispose](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#dispose12)接口来实现与实体节点的绑定关系的解除。 + 2. 操作节点树。 + + RenderNode提供了节点的增、删、查、改的能力,能够修改节点的子树结构;可以对所有RenderNode的节点的父子节点做出查询操作,并返回查询结果。 + 3. 设置和获取渲染相关属性。 + + RenderNode中可以设置渲染相关的属性,包括:[backgroundColor](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#backgroundcolor),[clipToFrame](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#cliptoframe),[opacity](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#opacity),[size](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#size),[position](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#position),[frame](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#frame),[pivot](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#pivot),[scale](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#scale),[translation](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#translation),[rotation](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#rotation),[transform](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#transform),[shadowColor](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#shadowcolor),[shadowOffset](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#shadowoffset),[shadowAlpha](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#shadowalpha),[shadowElevation](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#shadowelevation),[shadowRadius](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#shadowradius),[borderStyle](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#borderstyle12),[borderWidth](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#borderwidth12),[borderColor](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#bordercolor12),[borderRadius](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#borderradius12),[shapeMask](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#shapemask12),[shapeClip](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#shapeclip12),[markNodeGroup](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#marknodegroup12)等。具体属性支持范围参考[RenderNode](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md)接口说明。 + 4. 自定义绘制。 + + 通过重写RenderNode中的[draw](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#draw)方法,可以自定义RenderNode的绘制内容,通过[invalidate](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#invalidate)接口可以主动触发节点的重新绘制。 + 5. 调整自定义绘制Canvas的变换矩阵。 + 从API version 12开始,通过重写RenderNode中的[draw](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-renderNode.md#draw)方法,可以自定义RenderNode的绘制内容。 + + 通过[concatMatrix](https://gitcode.com/arkui-x/docs/blob/master/zh-cn/application-dev/reference/apis/arkts-apis-graphics-drawing-Canvas.md#concatmatrix20)可以调整自定义绘制Canvas的变换矩阵。 + ## 相关权限 不涉及 diff --git a/ArkUIKit/NativeType/NdkCreateList/AppScope/app.json5 b/ArkUIKit/NativeType/NdkCreateList/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..d06fc6a5ca5afbf04b735955ea97f77a50892f14 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/AppScope/app.json5 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "app": { + "bundleName": "com.samples.NdkCreateList", + "vendor": "samples", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/ArkUIKit/NativeType/NdkCreateList/AppScope/resources/base/element/string.json b/ArkUIKit/NativeType/NdkCreateList/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..95ae0412ef0c6355313a1cdf42cfb4f72a20c5a8 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "NdkCreateList" + } + ] +} diff --git a/ArkUIKit/NativeType/NdkCreateList/AppScope/resources/base/media/background.png b/ArkUIKit/NativeType/NdkCreateList/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/ArkUIKit/NativeType/NdkCreateList/AppScope/resources/base/media/background.png differ diff --git a/ArkUIKit/NativeType/NdkCreateList/AppScope/resources/base/media/foreground.png b/ArkUIKit/NativeType/NdkCreateList/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..eb9427585b36d14b12477435b6419d1f07b3e0bb Binary files /dev/null and b/ArkUIKit/NativeType/NdkCreateList/AppScope/resources/base/media/foreground.png differ diff --git a/ArkUIKit/NativeType/NdkCreateList/AppScope/resources/base/media/layered_image.json b/ArkUIKit/NativeType/NdkCreateList/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/README_zh.md b/ArkUIKit/NativeType/NdkCreateList/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..41c195c01482f8587a0bc7ffac58f48de2dc43a3 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/README_zh.md @@ -0,0 +1,106 @@ +# ArkUI指南文档示例 + +### 介绍 + +ArkUI开发框架提供了列表组件,使用列表可以轻松高效地显示结构化、可滚动的信息。列表组件支持控制滚动位置、支持分组显示内容、支持使用NodeAdapter实现懒加载以提升列表创建性能。 + +该工程中展示的代码详细描述可查如下链接: + +1. [使用列表](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/ui/ndk-loading-long-list.md)。 + +### 效果预览 + +| 分组列表测试 | +|-----------------------------| +| ![](screenshots/result.jpg) | + + +### 使用说明 + +1. 在首页选择对应的测试界面。 + +2. 在对应的测试界面点击查看页面。 + +### 工程目录 +``` +entry/ +└── src + ├── main + │   ├── cpp + │   │   ├── ArkUIBaseNode.h + │   │   ├── ArkUIListItemAdapter.h + │   │   ├── ArkUIListItemGroupNode.h + │   │   ├── ArkUIListItemNode.h + │   │   ├── ArkUIListNode.h + │   │   ├── ArkUINode.h + │   │   ├── ArkUITextNode.h + │   │   ├── CMakeLists.txt + │   │   ├── LazyTextListExample.h + │   │   ├── LazyTextListExample1.h + │   │   ├── NativeEntry.cpp + │   │   ├── NativeEntry.h + │   │   ├── NativeModule.h + │   │   ├── napi_init.cpp + │   │   └── types + │   │   └── libentry + │   │   ├── Index.d.ts + │   │   └── oh-package.json5 + │   ├── ets + │   │   ├── entryability + │   │   │   └── EntryAbility.ets + │   │   ├── entrybackupability + │   │   │   └── EntryBackupAbility.ets + │   │   └── pages + │   │   ├── Index.ets + │   │   └── LazyTextListExample.ets + │   ├── module.json5 + │   ├── resources +``` + +### 具体实现 + +1. 实现懒加载适配器。源码参考:[ArkUIListItemAdapter.h](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListItemAdapter.h) + + +2. 在列表中应用懒加载适配器。源码参考:[ArkUIListNode.h](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListNode.h) + + * 在ArkUIListNode中添加SetLazyAdapter函数,给列表节点设置NODE_LIST_NODE_ADAPTER属性,并将NodeAdapter作为属性入参传入 + + * 创建List使用懒加载的示例代码,调用List节点的SetLazyAdapter接口设置懒加载适配器 + +3. 使用分组列表。源码参考:[ArkUIListItemGroupNode.h](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkUISample/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListItemGroupNode.h) + + * 分组列表使用ListItemGroup组件实现,ListItemGroup支持添加header、footer设置函数,支持使用懒加载 + + * List组件设置吸顶 + + * List组件下使用ListItemGroup实现分组列表界面 + + +### 相关权限 + +不涉及。 + +### 依赖 + +不涉及。 + +### 约束与限制 + +1.本示例仅支持标准系统上运行, 支持设备:RK3568。 + +2.本示例为Stage模型,支持API20版本SDK,版本号:6.0.0.41,镜像版本号:OpenHarmony_6.0.0.41。 + +3.本示例需要使用DevEco Studio 5.0.5 Release (Build Version: 5.0.13.200, built on May 13, 2025)及以上版本才可编译运行。 + +### 下载 + +如需单独下载本工程,执行如下命令: + +```` +git init +git config core.sparsecheckout true +echo code/DocsSample/ArkUISample/NativeType/NdkCreateList > .git/info/sparse-checkout +git remote add origin https://gitcode.com/openharmony/applications_app_samples.git +git pull origin master +```` \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/build-profile.json5 b/ArkUIKit/NativeType/NdkCreateList/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..724b825f1ee429691a14b6b6d138c70fd7c56db9 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/build-profile.json5 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "6.0.0(20)", + "compatibleSdkVersion": "6.0.0(20)", + "targetSdkVersion": "6.0.0(20)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/code-linter.json5 b/ArkUIKit/NativeType/NdkCreateList/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..ed05653cca31b61d64cf6471529eaf50d4f70709 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/code-linter.json5 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/build-profile.json5 b/ArkUIKit/NativeType/NdkCreateList/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f16a69b6cabee8faa9f51173548df942097f6fe2 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/build-profile.json5 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "apiType": "stageMode", + "buildOption": { + "resOptions": { + "copyCodeResource": { + "enable": false + } + }, + "externalNativeOptions": { + "path": "./src/main/cpp/CMakeLists.txt", + "arguments": "", + "cppFlags": "", + "abiFilters": ["arm64-v8a","x86_64"] + } + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + }, + "nativeLib": { + "debugSymbol": { + "strip": true, + "exclude": [] + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/hvigorfile.ts b/ArkUIKit/NativeType/NdkCreateList/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..cfa8a00f74f409d9647f55cdf270ab6aec69fe41 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/hvigorfile.ts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/oh-package.json5 b/ArkUIKit/NativeType/NdkCreateList/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..118bdd4fe7699368a010e04c24f5bfc887cf1298 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/oh-package.json5 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + "libentry.so": "file:./src/main/cpp/types/libentry" + } +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIBaseNode.h b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIBaseNode.h new file mode 100644 index 0000000000000000000000000000000000000000..bcf144a01294a376241a7baa08e025b8925bfa50 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIBaseNode.h @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// ArkUIBaseNode.h +// 提供组件树操作的基类。 +#ifndef MYAPPLICATION_ARKUIBASENODE_H +#define MYAPPLICATION_ARKUIBASENODE_H + +#include +#include +#include +#include + +#include "NativeModule.h" + +namespace NativeModule { + +const unsigned int LOG_PRINT_DOMAIN = 0xF811; + +class ArkUIBaseNode { +public: + explicit ArkUIBaseNode(ArkUI_NodeHandle handle) + : handle_(handle), nativeModule_(NativeModuleInstance::GetInstance()->GetNativeNodeAPI()) {} + + virtual ~ArkUIBaseNode() + { + // 封装析构函数,实现子节点移除功能。 + if (!children_.empty()) { + for (const auto &child : children_) { + nativeModule_->removeChild(handle_, child->GetHandle()); + } + children_.clear(); + } + // 封装析构函数,统一回收节点资源。 + nativeModule_->disposeNode(handle_); + } + + void AddChild(const std::shared_ptr &child) + { + children_.emplace_back(child); + OnAddChild(child); + } + + void RemoveChild(const std::shared_ptr &child) + { + children_.remove(child); + OnRemoveChild(child); + } + + void InsertChild(const std::shared_ptr &child, int32_t index) + { + if (index >= children_.size()) { + AddChild(child); + } else { + auto iter = children_.begin(); + std::advance(iter, index); + children_.insert(iter, child); + OnInsertChild(child, index); + } + } + + void InsertChildBefore(const std::shared_ptr &child, + const std::shared_ptr &slibing) + { + auto it = std::find(children_.begin(), children_.end(), slibing); + if (it != children_.end()) { + children_.insert(it, child); + } + OnInsertChildBefore(child, slibing); + } + + void InsertChildAfter(const std::shared_ptr &child, + const std::shared_ptr &slibing) + { + auto it = std::find(children_.begin(), children_.end(), slibing); + if (it != children_.end()) { + children_.insert(std::next(it), child); + } + OnInsertChildAfter(child, slibing); + } + + void RemoveAllChild() + { + for (auto it = children_.begin(); it != children_.end();) { + RemoveChild(*it); + } + OnRemoveAllChild(); + } + ArkUI_NodeHandle (*getChildAt)(ArkUI_NodeHandle node, int32_t position); + ArkUI_NodeHandle (*getFirstChild)(ArkUI_NodeHandle node); + ArkUI_NodeHandle (*getLastChild)(ArkUI_NodeHandle node); + ArkUI_NodeHandle (*getPreviousSibling)(ArkUI_NodeHandle node); + ArkUI_NodeHandle (*getNextSibling)(ArkUI_NodeHandle node); + + // 以下方法不可跨过ContentSlot。获取nodeHandle后可根据nativeEntry保存的节点map,做对应查找。 + ArkUI_NodeHandle GetParent() const { return nativeModule_->getParent(handle_); } + ArkUI_NodeHandle GetChildAt(uint32_t index) const { return nativeModule_->getChildAt(handle_, index); } + ArkUI_NodeHandle GetFirstChild() const { return nativeModule_->getFirstChild(handle_); } + ArkUI_NodeHandle GetLastChild() const { return nativeModule_->getLastChild(handle_); } + ArkUI_NodeHandle GetPreviousSibling() const { return nativeModule_->getPreviousSibling(handle_); } + ArkUI_NodeHandle GetNextSibling() const { return nativeModule_->getNextSibling(handle_); } + + // 以下方法可以跨过ContentSlot。 + ArkUI_NodeHandle GetParentInPageTree() const { return OH_ArkUI_NodeUtils_GetParentInPageTree(handle_); } + + ArkUI_NodeHandle GetCurrentPageRootNode() const + { + auto rootNode = OH_ArkUI_NodeUtils_GetCurrentPageRootNode(handle_); + + int32_t uniqueId = -1; + OH_ArkUI_NodeUtils_GetNodeUniqueId(handle_, &uniqueId); + auto nodeType = OH_ArkUI_NodeUtils_GetNodeType(handle_); + OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "BaseNode", + "Print base node info, uniqueId%{public}d, type:%{public}d, ", uniqueId, nodeType); + return rootNode; + } + + ArkUI_NodeHandle GetActiveChildrenByIndex(uint32_t index) const + { + ArkUI_ActiveChildrenInfo *childrenInfo; + // 通过接口先获取结构体信息。 + OH_ArkUI_NodeUtils_GetActiveChildrenInfo(handle_, &childrenInfo); + // 通过getCount接口获取子节点数量。 + auto count = OH_ArkUI_ActiveChildrenInfo_GetCount(childrenInfo); + ArkUI_NodeHandle child; + // 根据节点数量查找节点,并打印子节点信息。 + if (index < count) { + child = OH_ArkUI_ActiveChildrenInfo_GetNodeByIndex(childrenInfo, index); + int32_t uniqueId = -1; + OH_ArkUI_NodeUtils_GetNodeUniqueId(child, &uniqueId); + auto nodeType = OH_ArkUI_NodeUtils_GetNodeType(child); + OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "BaseNode", + "Print child info, uniqueId%{public}d, type:%{public}d, ", uniqueId, nodeType); + } + OH_ArkUI_ActiveChildrenInfo_Destroy(childrenInfo); + return child; + } + + // 用于获取懒展开的第一个活跃子节点下标。 + uint32_t GetFirstChildIndexWithoutExpand() const + { + uint32_t index = -1; + OH_ArkUI_NodeUtils_GetFirstChildIndexWithoutExpand(handle_, &index); + return index; + } + + // 用于获取懒展开的最后一个活跃子节点下标。 + uint32_t GetLastChildIndexWithoutExpand() const + { + uint32_t index = -1; + OH_ArkUI_NodeUtils_GetLastChildIndexWithoutExpand(handle_, &index); + return index; + } + + // 根据前置接口获取的懒展开活跃节点范围,高效的获取子节点信息。 + ArkUI_NodeHandle GetChildWithExpandMode(uint32_t index) const + { + ArkUI_NodeHandle subNode; + auto result = OH_ArkUI_NodeUtils_GetChildWithExpandMode(handle_, index, &subNode, ARKUI_LAZY_EXPAND); + if (result == ARKUI_ERROR_CODE_NO_ERROR) { + return subNode; + } + return nullptr; + } + + // 通知节点从布局到绘制全部标脏,实际使用可根据业务需要选择其中具体需要执行的内容,提升性能。 + void MarkDirty() + { + nativeModule_->markDirty(handle_, NODE_NEED_MEASURE); + nativeModule_->markDirty(handle_, NODE_NEED_LAYOUT); + nativeModule_->markDirty(handle_, NODE_NEED_RENDER); + } + + // 对单一节点设置单位。 + void SetLengthMetricUnit(ArkUI_LengthMetricUnit unit) { nativeModule_->setLengthMetricUnit(handle_, unit); } + + // 设置及获取自定义属性。 + void AddCustomProperty(const char *name, const char *value) + { + // 给组件添加自定义属性。 + OH_ArkUI_NodeUtils_AddCustomProperty(handle_, name, value); + } + + void RemoveCustomProperty(const char *name) { OH_ArkUI_NodeUtils_RemoveCustomProperty(handle_, name); } + + const char* GetCustomProperty(const char *name) + { + ArkUI_CustomProperty *property; + // 给开发者创建的结构体指针赋值。 + OH_ArkUI_NodeUtils_GetCustomProperty(handle_, name, &property); + // 从赋值过到结构体中取出string值。 + auto value = OH_ArkUI_CustomProperty_GetStringValue(property); + + OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "BaseNode", "Get CP name-value: %{public}s - %{public}s", + name, value); + // 使用完毕后销毁结构体,释放内存。 + OH_ArkUI_CustomProperty_Destroy(property); + return value; + } + + // 节点迁移,可跨实例转移节点。 + void MoveTo(const std::shared_ptr &anotherParent) + { + OH_ArkUI_NodeUtils_MoveTo(handle_, anotherParent->GetHandle(), -1); //-1代表放到最后一个位置 + } + + ArkUI_NodeHandle GetHandle() const { return handle_; } + +protected: + // 针对父容器子类需要重载下面的函数,实现组件挂载和卸载。 + virtual void OnAddChild(const std::shared_ptr &child) {} + virtual void OnRemoveChild(const std::shared_ptr &child) {} + virtual void OnRemoveAllChild() {} + virtual void OnInsertChild(const std::shared_ptr &child, int32_t index) {} + virtual void OnInsertChildBefore(const std::shared_ptr &child, + const std::shared_ptr &slibing) {} + virtual void OnInsertChildAfter(const std::shared_ptr &child, + const std::shared_ptr &slibing) {} + + ArkUI_NodeHandle handle_; + ArkUI_NativeNodeAPI_1 *nativeModule_ = nullptr; + +private: + std::list> children_; +}; +} // namespace NativeModule + +#endif // MYAPPLICATION_ARKUIBASENODE_H \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListItemAdapter.h b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListItemAdapter.h new file mode 100644 index 0000000000000000000000000000000000000000..d2f4628f06421694817e2563664bf0078a8ed736 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListItemAdapter.h @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// [Start Lazy_loading_of_text_list] +// [Start Item_adapter] +// [Start Remove_Item] +// ArkUIListItemAdapter +// [StartExclude Item_adapter] +// [StartExclude Remove_Item] +// 用于文本列表懒加载功能代码。 + +#ifndef MYAPPLICATION_ARKUILISTITEMADAPTER_H +#define MYAPPLICATION_ARKUILISTITEMADAPTER_H + +#include +#include +#include +#include + +#include "ArkUIListItemNode.h" +#include "ArkUITextNode.h" +#include "NativeModule.h" +#include + +namespace NativeModule { +const int32_t NUMBER_1000 = 1000; +const int32_t NUMBER_100 = 100; +const int32_t NUMBER_16 = 16; +// [EndExclude Item_adapter] +// [EndExclude Remove_Item] +class ArkUIListItemAdapter { + // [StartExclude Item_adapter] + // [StartExclude Remove_Item] +public: + ArkUIListItemAdapter() + : module_(NativeModuleInstance::GetInstance()->GetNativeNodeAPI()), + handle_(OH_ArkUI_NodeAdapter_Create()) + { // 使用NodeAdapter创建函数。 + // 初始化懒加载数据。 + for (int32_t i = 0; i < NUMBER_1000; i++) { + data_.emplace_back(std::to_string(i)); + } + // 设置懒加载数据。 + OH_ArkUI_NodeAdapter_SetTotalNodeCount(handle_, data_.size()); + // 设置懒加载回调事件。 + OH_ArkUI_NodeAdapter_RegisterEventReceiver(handle_, this, OnStaticAdapterEvent); + } + + ~ArkUIListItemAdapter() + { + // 释放创建的组件。 + while (!cachedItems_.empty()) { + cachedItems_.pop(); + } + items_.clear(); + // 释放Adapter相关资源。 + OH_ArkUI_NodeAdapter_UnregisterEventReceiver(handle_); + OH_ArkUI_NodeAdapter_Dispose(handle_); + } + + ArkUI_NodeAdapterHandle GetHandle() const { return handle_; } + // [EndExclude Remove_Item] + void RemoveItem(size_t index) + { + // 删除第index个数据。 + data_.erase(data_.begin() + index); + // 如果index会导致可视区域元素发生可见性变化,则会回调NODE_ADAPTER_EVENT_ON_REMOVE_NODE_FROM_ADAPTER事件删除元素, + // 根据是否有新增元素回调NODE_ADAPTER_EVENT_ON_GET_NODE_ID和NODE_ADAPTER_EVENT_ON_ADD_NODE_TO_ADAPTER事件。 + OH_ArkUI_NodeAdapter_RemoveItem(handle_, index, 1); + // 更新新的数量。 + OH_ArkUI_NodeAdapter_SetTotalNodeCount(handle_, data_.size()); + } + // [StartExclude Remove_Item] + void InsertItem(int32_t index, const std::string &value) + { + data_.insert(data_.begin() + index, value); + // 如果index会导致可视区域元素发生可见性变化,则会回调NODE_ADAPTER_EVENT_ON_GET_NODE_ID和NODE_ADAPTER_EVENT_ON_ADD_NODE_TO_ADAPTER事件, + // 根据是否有删除元素回调NODE_ADAPTER_EVENT_ON_REMOVE_NODE_FROM_ADAPTER事件。 + OH_ArkUI_NodeAdapter_InsertItem(handle_, index, 1); + // 更新新的数量。 + OH_ArkUI_NodeAdapter_SetTotalNodeCount(handle_, data_.size()); + } + + void MoveItem(int32_t oldIndex, int32_t newIndex) + { + auto temp = data_[oldIndex]; + data_.insert(data_.begin() + newIndex, temp); + data_.erase(data_.begin() + oldIndex); + // 移到位置如果未发生可视区域内元素的可见性变化,则不回调事件,反之根据新增和删除场景回调对应的事件。 + OH_ArkUI_NodeAdapter_MoveItem(handle_, oldIndex, newIndex); + } + + void ReloadItem(int32_t index, const std::string &value) + { + data_[index] = value; + // 如果index位于可视区域内,先回调NODE_ADAPTER_EVENT_ON_REMOVE_NODE_FROM_ADAPTER删除老元素, + // 再回调NODE_ADAPTER_EVENT_ON_GET_NODE_ID和NODE_ADAPTER_EVENT_ON_ADD_NODE_TO_ADAPTER事件。 + OH_ArkUI_NodeAdapter_ReloadItem(handle_, index, 1); + } + + void ReloadAllItem() + { + std::reverse(data_.begin(), data_.end()); + // 全部重新加载场景下,会回调NODE_ADAPTER_EVENT_ON_GET_NODE_ID接口获取新的组件ID, + // 根据新的组件ID进行对比,ID不发生变化的进行复用, + // 针对新增ID的元素,调用NODE_ADAPTER_EVENT_ON_ADD_NODE_TO_ADAPTER事件创建新的组件, + // 然后判断老数据中遗留的未使用ID,调用NODE_ADAPTER_EVENT_ON_REMOVE_NODE_FROM_ADAPTER删除老元素。 + OH_ArkUI_NodeAdapter_ReloadAllItems(handle_); + } + +private: + static void OnStaticAdapterEvent(ArkUI_NodeAdapterEvent *event) + { + // 获取实例对象,回调实例事件。 + auto itemAdapter = reinterpret_cast(OH_ArkUI_NodeAdapterEvent_GetUserData(event)); + itemAdapter->OnAdapterEvent(event); + } + + void OnAdapterEvent(ArkUI_NodeAdapterEvent *event) + { + auto type = OH_ArkUI_NodeAdapterEvent_GetType(event); + switch (type) { + case NODE_ADAPTER_EVENT_ON_GET_NODE_ID: + OnNewItemIdCreated(event); + break; + case NODE_ADAPTER_EVENT_ON_ADD_NODE_TO_ADAPTER: + OnNewItemAttached(event); + break; + case NODE_ADAPTER_EVENT_ON_REMOVE_NODE_FROM_ADAPTER: + OnItemDetached(event); + break; + default: + break; + } + } + + // 分配ID给需要显示的Item,用于ReloadAllItems场景的元素diff。 + void OnNewItemIdCreated(ArkUI_NodeAdapterEvent *event) + { + auto index = OH_ArkUI_NodeAdapterEvent_GetItemIndex(event); + static std::hash hashId = std::hash(); + auto id = hashId(data_[index]); + OH_ArkUI_NodeAdapterEvent_SetNodeId(event, id); + } + // [EndExclude Item_adapter] + // 需要新的Item显示在可见区域。 + void OnNewItemAttached(ArkUI_NodeAdapterEvent *event) + { + auto index = OH_ArkUI_NodeAdapterEvent_GetItemIndex(event); + ArkUI_NodeHandle handle = nullptr; + if (!cachedItems_.empty()) { + // 使用并更新回收复用的缓存。 + auto recycledItem = cachedItems_.top(); + auto textItem = std::dynamic_pointer_cast(recycledItem->GetChildren().back()); + textItem->SetTextContent(data_[index]); + handle = recycledItem->GetHandle(); + // [StartExclude Lazy_loading_of_text_list] + auto swipeContent = recycledItem->GetSwipeContent(); + swipeContent->RegisterOnClick([this, data = data_[index]](ArkUI_NodeEvent *event) { + auto it = std::find(data_.begin(), data_.end(), data); + if (it != data_.end()) { + auto index = std::distance(data_.begin(), it); + RemoveItem(index); + } + }); + // [EndExclude Lazy_loading_of_text_list] + // 释放缓存池的引用。 + cachedItems_.pop(); + } else { + // 创建新的元素。 + auto listItem = std::make_shared(); + auto textNode = std::make_shared(); + textNode->SetTextContent(data_[index]); + textNode->SetFontSize(NUMBER_16); + textNode->SetPercentWidth(1); + textNode->SetHeight(NUMBER_100); + textNode->SetBackgroundColor(0xFFfffacd); + textNode->SetTextAlign(ARKUI_TEXT_ALIGNMENT_CENTER); + listItem->AddChild(textNode); + // 创建ListItem划出菜单。 + auto swipeNode = std::make_shared(); + // [StartExclude Lazy_loading_of_text_list] + swipeNode->SetTextContent("del"); + swipeNode->SetFontSize(NUMBER_16); + swipeNode->SetFontColor(0xFFFFFFFF); + swipeNode->SetWidth(NUMBER_100); + swipeNode->SetHeight(NUMBER_100); + swipeNode->SetBackgroundColor(0xFFFF0000); + swipeNode->SetTextAlign(ARKUI_TEXT_ALIGNMENT_CENTER); + // [EndExclude Lazy_loading_of_text_list] + swipeNode->RegisterOnClick([this, data = data_[index]](ArkUI_NodeEvent *event) { + auto it = std::find(data_.begin(), data_.end(), data); + if (it != data_.end()) { + auto index = std::distance(data_.begin(), it); + RemoveItem(index); + } + }); + listItem->SetSwiperAction(swipeNode); + handle = listItem->GetHandle(); + // 保持文本列表项的引用。 + items_.emplace(handle, listItem); + } + // 设置需要展示的元素。 + OH_ArkUI_NodeAdapterEvent_SetItem(event, handle); + } + // [StartExclude Item_adapter] + // Item从可见区域移除。 + void OnItemDetached(ArkUI_NodeAdapterEvent *event) + { + auto item = OH_ArkUI_NodeAdapterEvent_GetRemovedNode(event); + // 放置到缓存池中进行回收复用。 + cachedItems_.emplace(items_[item]); + } + + std::vector data_; + ArkUI_NativeNodeAPI_1 *module_ = nullptr; + ArkUI_NodeAdapterHandle handle_ = nullptr; + + // 管理NodeAdapter生成的元素。 + std::unordered_map> items_; + + // 管理回收复用组件池。 + std::stack> cachedItems_; + // [EndExclude Item_adapter] + // [EndExclude Remove_Item] +}; +// [End Item_adapter] +// [End Remove_Item] +} // namespace NativeModule + +#endif // MYAPPLICATION_ARKUILISTITEMADAPTER_H +// [End Lazy_loading_of_text_list] \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListItemGroupNode.h b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListItemGroupNode.h new file mode 100644 index 0000000000000000000000000000000000000000..fd4e2f52702dff894f5b8841a3d14a2170bd0e9b --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListItemGroupNode.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// [Start Use_grouped_lists] +// ArkUIListItemGroupNode.h + +#ifndef MYAPPLICATION_ARKUILISTITEMGROUPNODE_H +#define MYAPPLICATION_ARKUILISTITEMGROUPNODE_H +#include "ArkUINode.h" +#include "ArkUIListItemAdapter.h" +namespace NativeModule { +class ArkUIListItemGroupNode : public ArkUINode { +public: + ArkUIListItemGroupNode() + : ArkUINode((NativeModuleInstance::GetInstance()->GetNativeNodeAPI()) + ->createNode(ARKUI_NODE_LIST_ITEM_GROUP)) {} + void SetHeader(std::shared_ptr node) + { + if (node) { + ArkUI_AttributeItem Item = { .object = node->GetHandle() }; + nativeModule_->setAttribute(handle_, NODE_LIST_ITEM_GROUP_SET_HEADER, &Item); + } else { + nativeModule_->resetAttribute(handle_, NODE_LIST_ITEM_GROUP_SET_HEADER); + } + } + void SetFooter(std::shared_ptr node) + { + if (node) { + ArkUI_AttributeItem Item = { .object= node->GetHandle() }; + nativeModule_->setAttribute(handle_, NODE_LIST_ITEM_GROUP_SET_FOOTER, &Item); + } else { + nativeModule_->resetAttribute(handle_, NODE_LIST_ITEM_GROUP_SET_FOOTER); + } + } + std::shared_ptr GetHeader() const + { + return header_; + } + std::shared_ptr GetFooter() const + { + return footer_; + } + //引入懒加载模块。 + void SetLazyAdapter(const std::shared_ptr &adapter) + { + ArkUI_AttributeItem item{nullptr, 0, nullptr, adapter->GetHandle()}; + nativeModule_->setAttribute(handle_, NODE_LIST_ITEM_GROUP_NODE_ADAPTER, &item); + adapter_ = adapter; + } +private: + std::shared_ptr header_; + std::shared_ptr footer_; + std::shared_ptr adapter_; +}; +} +#endif //MYAPPLICATION_ARKUILISTITEMGROUPNODE_H + // [End Use_grouped_lists] \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListItemNode.h b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListItemNode.h new file mode 100644 index 0000000000000000000000000000000000000000..84f4929c62d6cebcaee9303e47e81994e6c2c705 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListItemNode.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// [Start Provide_wrapper_class_list_items] +// ArkUIListItemNode.h +// 提供列表项的封装类。 +#ifndef MYAPPLICATION_ARKUILISTITEMNODE_H +#define MYAPPLICATION_ARKUILISTITEMNODE_H +#include "ArkUINode.h" +namespace NativeModule { +class ArkUIListItemNode : public ArkUINode { +public: + ArkUIListItemNode() + : ArkUINode((NativeModuleInstance::GetInstance()->GetNativeNodeAPI())->createNode(ARKUI_NODE_LIST_ITEM)) {} + ~ArkUIListItemNode() override + { + if (swipeAction_) { + OH_ArkUI_ListItemSwipeActionOption_Dispose(swipeAction_); + } + if (swipeItem_) { + OH_ArkUI_ListItemSwipeActionItem_Dispose(swipeItem_); + } + } + void SetSwiperAction(std::shared_ptr node) + { + swipeContent_ = node; + swipeItem_ = OH_ArkUI_ListItemSwipeActionItem_Create(); + OH_ArkUI_ListItemSwipeActionItem_SetContent(swipeItem_, node->GetHandle()); + swipeAction_ = OH_ArkUI_ListItemSwipeActionOption_Create(); + OH_ArkUI_ListItemSwipeActionOption_SetEnd(swipeAction_, swipeItem_); + ArkUI_AttributeItem Item = {.object = swipeAction_}; + nativeModule_->setAttribute(handle_, NODE_LIST_ITEM_SWIPE_ACTION, &Item); + } + std::shared_ptr GetSwipeContent() const { return swipeContent_; } + std::list> &GetChildren() { return children_; } + +private: + ArkUI_ListItemSwipeActionOption *swipeAction_ = nullptr; + ArkUI_ListItemSwipeActionItem *swipeItem_ = nullptr; + std::shared_ptr swipeContent_ = nullptr; + std::list> children_; +}; +} // namespace NativeModule +#endif // MYAPPLICATION_ARKUILISTITEMNODE_H +// [End Provide_wrapper_class_list_items] \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListNode.h b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListNode.h new file mode 100644 index 0000000000000000000000000000000000000000..2af5ec96b27e1d15914a8eab47e6c593ab86f788 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUIListNode.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// [Start List_encapsulated_object] +// [Start ScrollTo] +// [Start ScrollToIndex] +// [Start SetSticky] +// [Start ScrollBy] +// ArkUIListNode.h +// 提供列表组件的封装。 +// [StartExclude ScrollTo] +// [StartExclude SetSticky] +// [StartExclude ScrollToIndex] +// [StartExclude ScrollBy] +#ifndef MYAPPLICATION_ARKUILISTNODE_H +#define MYAPPLICATION_ARKUILISTNODE_H + +#include "ArkUINode.h" +#include "ArkUIListItemAdapter.h" +namespace NativeModule { +// [EndExclude ScrollTo] +// [EndExclude SetSticky] +// [EndExclude ScrollToIndex] +// [EndExclude ScrollBy] +class ArkUIListNode : public ArkUINode { + // [StartExclude ScrollToIndex] + // [StartExclude ScrollTo] + // [StartExclude ScrollBy] + // [StartExclude SetSticky] +public: + ArkUIListNode() // 创建ArkUI的列表组件。 + : ArkUINode((NativeModuleInstance::GetInstance()->GetNativeNodeAPI())->createNode(ARKUI_NODE_LIST)) {} + + ~ArkUIListNode() override + { + if (nativeModule_) { + nativeModule_->unregisterNodeEvent(handle_, NODE_LIST_ON_SCROLL_INDEX); + } + if (adapter_) { + // 析构的时候卸载adapter下的UI组件。 + nativeModule_->resetAttribute(handle_, NODE_LIST_NODE_ADAPTER); + adapter_.reset(); + } + } + // List组件的属性接口封装。 + void SetScrollBarState(bool isShow) + { + ArkUI_ScrollBarDisplayMode displayMode = + isShow ? ARKUI_SCROLL_BAR_DISPLAY_MODE_ON : ARKUI_SCROLL_BAR_DISPLAY_MODE_OFF; + ArkUI_NumberValue value[] = {{.i32 = displayMode}}; + ArkUI_AttributeItem item = {value, 1}; + nativeModule_->setAttribute(handle_, NODE_SCROLL_BAR_DISPLAY_MODE, &item); + } + + void RegisterOnScrollIndex(const std::function &onScrollIndex) + { + onScrollIndex_ = onScrollIndex; + nativeModule_->registerNodeEvent(handle_, NODE_LIST_ON_SCROLL_INDEX, 0, nullptr); + } + // 引入懒加载模块。 + void SetLazyAdapter(const std::shared_ptr &adapter) + { + ArkUI_AttributeItem item{nullptr, 0, nullptr, adapter->GetHandle()}; + nativeModule_->setAttribute(handle_, NODE_LIST_NODE_ADAPTER, &item); + adapter_ = adapter; + } + // [StartExclude List_encapsulated_object] + // [EndExclude ScrollTo] + void ScrollTo(float offset) + { + ArkUI_NumberValue value[] = {{.f32 = 0}, {.f32 = offset}, {.f32 = 0}}; + ArkUI_AttributeItem Item = {.value = value, .size = 3}; + nativeModule_->setAttribute(handle_, NODE_SCROLL_OFFSET, &Item); + } + // [StartExclude ScrollTo] + // [EndExclude ScrollToIndex] + void ScrollToIndex(int32_t index) + { + ArkUI_NumberValue value[] = {{.i32 = index}}; + ArkUI_AttributeItem Item = {.value = value, .size = 1}; + nativeModule_->setAttribute(handle_, NODE_LIST_SCROLL_TO_INDEX, &Item); + } + // [StartExclude ScrollToIndex] + // [EndExclude ScrollBy] + void ScrollBy(float offset) + { + ArkUI_NumberValue value[] = {{.f32 = 0}, {.f32 = offset}}; + ArkUI_AttributeItem Item = {.value = value, .size = 2}; + nativeModule_->setAttribute(handle_, NODE_SCROLL_BY, &Item); + } + // [StartExclude ScrollBy] + // [EndExclude SetSticky] + void SetSticky(ArkUI_StickyStyle style) + { + ArkUI_NumberValue value[] = {{.i32 = style}}; + ArkUI_AttributeItem item = {value, 1}; + nativeModule_->setAttribute(handle_, NODE_LIST_STICKY, &item); + } + // [StartExclude SetSticky] + // [EndExclude List_encapsulated_object] +protected: + void OnNodeEvent(ArkUI_NodeEvent *event) override + { + auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); + switch (eventType) { + case NODE_LIST_ON_SCROLL_INDEX: { + auto index = OH_ArkUI_NodeEvent_GetNodeComponentEvent(event)->data[0]; + if (onScrollIndex_) { + onScrollIndex_(index.i32); + } + break; + } + default: { + break; + } + } + } + +private: + std::function onScrollIndex_; + + std::shared_ptr adapter_; + // [EndExclude ScrollTo] + // [EndExclude ScrollToIndex] + // [EndExclude ScrollBy] + // [EndExclude SetSticky] +}; +// [End ScrollTo] +// [End SetSticky] +// [End ScrollToIndex] +// [End ScrollBy] +} // namespace NativeModule + +#endif // MYAPPLICATION_ARKUILISTNODE_H +// [End List_encapsulated_object] \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUINode.h b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUINode.h new file mode 100644 index 0000000000000000000000000000000000000000..150c6232a2d163fff884744c3a5e6a2e8c1def25 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUINode.h @@ -0,0 +1,325 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// ArkUINode.h +// 提供通用属性和事件的封装。 +#ifndef MYAPPLICATION_ARKUINODE_H +#define MYAPPLICATION_ARKUINODE_H + +#include "ArkUIBaseNode.h" +#include "NativeModule.h" +#include +#include +#include +#include +#include + +namespace NativeModule { +void CallBack(uint64_t nanoTimeLeft, uint32_t frameCount, void *userData) +{ + OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "PostCallback", + "***StartCallBack*** nanoTimeLeft = %{public}lu , frameCount = %{public}d", + nanoTimeLeft, frameCount); + if (userData) { + int *myData = (int *)userData; + } + // 执行业务相关逻辑。 +} + +class ArkUINode : public ArkUIBaseNode { +public: + explicit ArkUINode(ArkUI_NodeHandle handle) : ArkUIBaseNode(handle) + { + nativeModule_ = NativeModuleInstance::GetInstance()->GetNativeNodeAPI(); + // 事件触发时需要通过函数获取对应的事件对象,这边通过设置节点自定义数据将封装类指针保持在组件上,方便后续事件分发。 + nativeModule_->setUserData(handle_, this); + // 注册节点监听事件接受器。 + nativeModule_->addNodeEventReceiver(handle_, ArkUINode::NodeEventReceiver); + } + + ~ArkUINode() override + { + if (onClick_) { + nativeModule_->unregisterNodeEvent(handle_, NODE_ON_CLICK_EVENT); + } + if (onTouch_) { + nativeModule_->unregisterNodeEvent(handle_, NODE_TOUCH_EVENT); + } + if (onDisappear_) { + nativeModule_->unregisterNodeEvent(handle_, NODE_EVENT_ON_DISAPPEAR); + } + if (onAppear_) { + nativeModule_->unregisterNodeEvent(handle_, NODE_EVENT_ON_APPEAR); + } + nativeModule_->removeNodeEventReceiver(handle_, ArkUINode::NodeEventReceiver); + } + + // 通用属性调用封装 + void SetWidth(float width) + { + ArkUI_NumberValue value[] = {{.f32 = width}}; + ArkUI_AttributeItem item = {value, 1}; + auto result = nativeModule_->setAttribute(handle_, NODE_WIDTH, &item); + CheckErrorCode(result); + } + float GetWidth() + { + return nativeModule_->getAttribute(handle_, NODE_WIDTH)->value[0].f32; + } + void SetPercentWidth(float percent) + { + ArkUI_NumberValue value[] = {{.f32 = percent}}; + ArkUI_AttributeItem item = {value, 1}; + auto result = nativeModule_->setAttribute(handle_, NODE_WIDTH_PERCENT, &item); + CheckErrorCode(result); + } + void SetHeight(float height) + { + ArkUI_NumberValue value[] = {{.f32 = height}}; + ArkUI_AttributeItem item = {value, 1}; + auto result = nativeModule_->setAttribute(handle_, NODE_HEIGHT, &item); + CheckErrorCode(result); + } + float GetHeight() + { + return nativeModule_->getAttribute(handle_, NODE_HEIGHT)->value[0].f32; + } + void SetSize(float width, float height) + { + ArkUI_NumberValue valueWidth[] = {{.f32 = width}}; + ArkUI_AttributeItem itemWidth = {valueWidth, 1}; + nativeModule_->setAttribute(handle_, NODE_WIDTH, &itemWidth); + ArkUI_NumberValue valueHeight[] = {{.f32 = height}}; + ArkUI_AttributeItem itemHeight = {valueHeight, 1}; + nativeModule_->setAttribute(handle_, NODE_HEIGHT, &itemHeight); + } + void SetPercentHeight(float percent) + { + ArkUI_NumberValue value[] = {{.f32 = percent}}; + ArkUI_AttributeItem item = {value, 1}; + auto result = nativeModule_->setAttribute(handle_, NODE_HEIGHT_PERCENT, &item); + CheckErrorCode(result); + } + void SetBackgroundColor(uint32_t color) + { + ArkUI_NumberValue value[] = {{.u32 = color}}; + ArkUI_AttributeItem item = {value, 1}; + auto result = nativeModule_->setAttribute(handle_, NODE_BACKGROUND_COLOR, &item); + CheckErrorCode(result); + } + void SetId(const std::string &id) + { + ArkUI_AttributeItem item = {.string = id.c_str() }; + auto result = nativeModule_->setAttribute(handle_, NODE_ID, &item); + CheckErrorCode(result); + } + void ResetId() { nativeModule_->resetAttribute(handle_, NODE_ID); } + void CheckErrorCode(int32_t errorCode) + { + if (errorCode == ARKUI_ERROR_CODE_NO_ERROR) { + return; + } + int32_t uniqueId = -1; + OH_ArkUI_NodeUtils_GetNodeUniqueId(handle_, &uniqueId); + auto nodeType = OH_ArkUI_NodeUtils_GetNodeType(handle_); + auto isNDKNode = OH_ArkUI_NodeUtils_IsCreatedByNDK(handle_); + OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Manager", + "ErrorCode:%{public}d, uniqueId:%{public}d, nodeType:%{public}d, isCreateByNdk:%{public}d", + errorCode, uniqueId, nodeType, isNDKNode); + } + + void SetCrossLanguage(bool isCross) + { + // 构造结构体。 + auto option = OH_ArkUI_CrossLanguageOption_Create(); + // 设置结构体属性,此处为设置是否允许跨语言。 + OH_ArkUI_CrossLanguageOption_SetAttributeSettingStatus(option, isCross); + // 设置结构体给组件。 + OH_ArkUI_NodeUtils_SetCrossLanguageOption(handle_, option); + // 销毁结构体。 + OH_ArkUI_CrossLanguageOption_Destroy(option); + } + + bool GetCrossLanguage() + { + // 构造结构体。 + auto option = OH_ArkUI_CrossLanguageOption_Create(); + // 获取组件的结构体配置。 + OH_ArkUI_NodeUtils_GetCrossLanguageOption(handle_, option); + // 从结构体内取值。 + bool isCross = OH_ArkUI_CrossLanguageOption_GetAttributeSettingStatus(option); + int32_t uniqueId = -1; + OH_ArkUI_NodeUtils_GetNodeUniqueId(handle_, &uniqueId); + OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "Manager", + "uniqueId:%{public}d, isCrossLanguage:%{public}d", uniqueId, isCross); + OH_ArkUI_CrossLanguageOption_Destroy(option); + } + + ArkUI_IntOffset GetLayoutPositionInWindow() + { + ArkUI_IntOffset globalOffset; + auto result = OH_ArkUI_NodeUtils_GetLayoutPositionInWindow(handle_, &globalOffset); + if (result == ARKUI_ERROR_CODE_NO_ERROR) { + return globalOffset; + } else { + return {0, 0}; + } + } + + ArkUI_IntOffset GetPositionWithTranslateInWindow() + { + ArkUI_IntOffset translateOffset; + auto result = OH_ArkUI_NodeUtils_GetPositionWithTranslateInWindow(handle_, &translateOffset); + if (result == ARKUI_ERROR_CODE_NO_ERROR) { + return translateOffset; + } else { + return {0, 0}; + } + } + + // 处理通用事件。 + void RegisterOnClick(const std::function &onClick) + { + onClick_ = onClick; + // 注册点击事件。 + nativeModule_->registerNodeEvent(handle_, NODE_ON_CLICK_EVENT, 0, nullptr); + } + + void RegisterOnTouch(const std::function &onTouch) + { + onTouch_ = onTouch; + // 注册触碰事件。 + nativeModule_->registerNodeEvent(handle_, NODE_TOUCH_EVENT, 0, nullptr); + } + + void RegisterOnDisappear(const std::function &onDisappear) + { + onDisappear_ = onDisappear; + // 注册卸载事件。 + nativeModule_->registerNodeEvent(handle_, NODE_EVENT_ON_DISAPPEAR, 0, nullptr); + } + + void RegisterOnAppear(const std::function &onAppear) + { + onAppear_ = onAppear; + // 注册挂载事件。 + nativeModule_->registerNodeEvent(handle_, NODE_EVENT_ON_APPEAR, 0, nullptr); + } + + // 抛出任务在下一帧渲染时执行,用于执行一些需等待其他任务完成时的业务逻辑。 + void PostFrameCallback(void *data) + { + auto context = OH_ArkUI_GetContextByNode(handle_); + OH_ArkUI_PostFrameCallback(context, &data, CallBack); + } + + // 抛出任务在下一帧渲染结束后且vsync信号来临还有大于1ms时执行,若剩余时间小于1ms,则顺延至下一帧并自动请求vysnc。 + void PostIdleCallback(void *data) + { + auto context = OH_ArkUI_GetContextByNode(handle_); + OH_ArkUI_PostIdleCallback(context, &data, CallBack); + } + +protected: + // 组件树操作的实现类对接。 + void OnAddChild(const std::shared_ptr &child) override + { + nativeModule_->addChild(handle_, child->GetHandle()); + } + void OnRemoveChild(const std::shared_ptr &child) override + { + nativeModule_->removeChild(handle_, child->GetHandle()); + } + void OnRemoveAllChild() override + { + nativeModule_->removeAllChildren(handle_); + } + void OnInsertChild(const std::shared_ptr &child, int32_t index) override + { + nativeModule_->insertChildAt(handle_, child->GetHandle(), index); + } + void OnInsertChildBefore(const std::shared_ptr &child, + const std::shared_ptr &slibing) override + { + nativeModule_->insertChildBefore(handle_, child->GetHandle(), slibing->GetHandle()); + } + void OnInsertChildAfter(const std::shared_ptr &child, + const std::shared_ptr &slibing) override + { + nativeModule_->insertChildAfter(handle_, child->GetHandle(), slibing->GetHandle()); + } + + // 事件监听器函数指针。 + static void NodeEventReceiver(ArkUI_NodeEvent *event) + { + // 获取事件发生的UI组件对象。 + auto nodeHandle = OH_ArkUI_NodeEvent_GetNodeHandle(event); + // 获取保持在UI组件对象中的自定义数据,返回封装类指针。 + auto *node = reinterpret_cast( + NativeModuleInstance::GetInstance()->GetNativeNodeAPI()->getUserData(nodeHandle)); + // 基于封装类实例对象处理事件。 + node->ProcessNodeEvent(event); + } + void ProcessNodeEvent(ArkUI_NodeEvent *event) + { + auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); + switch (eventType) { + case NODE_ON_CLICK_EVENT: { + if (onClick_) { + onClick_(event); + } + break; + } + case NODE_TOUCH_EVENT: { + if (onTouch_) { + auto *uiInputEvent = OH_ArkUI_NodeEvent_GetInputEvent(event); + float x = OH_ArkUI_PointerEvent_GetX(uiInputEvent); + float y = OH_ArkUI_PointerEvent_GetY(uiInputEvent); + auto type = OH_ArkUI_UIInputEvent_GetAction(uiInputEvent); + onTouch_(type, x, y); + } + break; + } + case NODE_EVENT_ON_DISAPPEAR: { + if (onDisappear_) { + onDisappear_(); + } + break; + } + case NODE_EVENT_ON_APPEAR: { + if (onAppear_) { + onAppear_(); + } + break; + } + default: { + // 组件特有事件交给子类处理 + OnNodeEvent(event); + break; + } + } + } + + virtual void OnNodeEvent(ArkUI_NodeEvent *event) {} + +private: + std::function onClick_; + std::function onDisappear_; + std::function onAppear_; + std::function onTouch_; +}; + +} // namespace NativeModule + +#endif // MYAPPLICATION_ARKUINODE_H \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUITextNode.h b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUITextNode.h new file mode 100644 index 0000000000000000000000000000000000000000..73a61ba087b217b9d4b906bd120f826ea7787474 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/ArkUITextNode.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// [Start arkUITestNode_start] +// ArkUITextNode.h +// 实现文本组件的封装类。 +#ifndef MYAPPLICATION_ARKUITEXTNODE_H +#define MYAPPLICATION_ARKUITEXTNODE_H + +#include +#include +#include +#include "ArkUINode.h" +#include + +// [StartExclude arkUITestNode_start] +#include "NativeEntry.h" +// [EndExclude arkUITestNode_start] +namespace NativeModule { + +// 布局完成的回调方法 +void OnLayoutCompleted(void *userData) +{ + ArkUI_NodeHandle node = (ArkUI_NodeHandle)userData; + OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "the text_node is layout completed"); + ArkUI_NativeNodeAPI_1 *nativeModule = NativeModuleInstance::GetInstance()->GetNativeNodeAPI(); + ArkUI_AttributeItem item = {nullptr, 0, "layout callback"}; + nativeModule->setAttribute(node, NODE_TEXT_CONTENT, &item); +} +// 绘制送显完成的回调方法 +void OnDrawCompleted(void *userData) +{ + ArkUI_NodeHandle node = (ArkUI_NodeHandle)userData; + OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "the text_node is draw completed"); + ArkUI_NativeNodeAPI_1 *nativeModule = NativeModuleInstance::GetInstance()->GetNativeNodeAPI(); + ArkUI_AttributeItem item = {nullptr, 0, "draw callback"}; + nativeModule->setAttribute(node, NODE_TEXT_CONTENT, &item); +} +// [StartExclude arkUITestNode_start] +void ColorChangeCallback(ArkUI_SystemColorMode colorMode, void *userData) +{ + if (userData) { + auto handle = (ArkUI_NodeHandle)userData; + // 执行业务相关逻辑,如更换字体颜色,实际所需内容可以根据userData自行修改。 + bool isDark = (colorMode == ARKUI_SYSTEM_COLOR_MODE_DARK); + ArkUI_NumberValue value[] = {{.u32 = isDark ? 0xFFFFFFFF : 0xFF000000}}; // 深色模式字体白色,浅色模式字体黑色。 + ArkUI_AttributeItem item = {value, 1}; + NativeModuleInstance::GetInstance()->GetNativeNodeAPI()->setAttribute(handle, NODE_FONT_COLOR, &item); + } +} +// [EndExclude arkUITestNode_start] +class ArkUITextNode : public ArkUINode { +public: + ArkUITextNode() + : ArkUINode((NativeModuleInstance::GetInstance()->GetNativeNodeAPI())->createNode(ARKUI_NODE_TEXT)) {} + void SetFontSize(float fontSize) + { + ArkUI_NumberValue value[] = {{.f32 = fontSize}}; + ArkUI_AttributeItem item = {value, 1}; + nativeModule_->setAttribute(handle_, NODE_FONT_SIZE, &item); + } + void SetFontColor(uint32_t color) + { + ArkUI_NumberValue value[] = {{.u32 = color}}; + ArkUI_AttributeItem item = {value, 1}; + nativeModule_->setAttribute(handle_, NODE_FONT_COLOR, &item); + } + void SetTextContent(const std::string &content) + { + ArkUI_AttributeItem item = {nullptr, 0, content.c_str()}; + nativeModule_->setAttribute(handle_, NODE_TEXT_CONTENT, &item); + } + void SetTextAlign(ArkUI_TextAlignment align) + { + ArkUI_NumberValue value[] = {{.i32 = align}}; + ArkUI_AttributeItem item = {value, 1}; + nativeModule_->setAttribute(handle_, NODE_TEXT_ALIGN, &item); + } + void SetLayoutCallBack(int32_t nodeId) + { + OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "set layout callback"); + // 注册布局完成的回调方法 + OH_ArkUI_RegisterLayoutCallbackOnNodeHandle(handle_, this, OnLayoutCompleted); + } + void ResetLayoutCallBack() + { + OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "reset layout callback"); + // 取消注册布局完成的回调方法 + OH_ArkUI_UnregisterLayoutCallbackOnNodeHandle(handle_); + } + void SetDrawCallBack(int32_t nodeId) + { + OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "set draw callback"); + // 注册绘制送显完成的回调方法 + OH_ArkUI_RegisterDrawCallbackOnNodeHandle(handle_, this, OnDrawCompleted); + } + void ResetDrawCallBack() + { + OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "reset draw callback"); + // 取消注册绘制送显完成的回调方法 + OH_ArkUI_UnregisterDrawCallbackOnNodeHandle(handle_); + } + void SetInspectorId(std::string inspectorId) + { + ArkUI_AttributeItem item = {nullptr, 0, inspectorId.c_str()}; + nativeModule_->setAttribute(handle_, NODE_ID, &item); + } + // [StartExclude arkUITestNode_start] + void RegistSystemColorModeChange() + { + OH_ArkUI_RegisterSystemColorModeChangeEvent(handle_, handle_, ColorChangeCallback); + } + + void UnregistSystemColorModeChange() + { + OH_ArkUI_UnregisterSystemColorModeChangeEvent(handle_); + } + // [EndExclude arkUITestNode_start] +}; +} // namespace NativeModule + +#endif // MYAPPLICATION_ARKUITEXTNODE_H +// [End arkUITestNode_start] \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/CMakeLists.txt b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..4d5474baab9369b2c87217bb3928a1d7efd3a32a --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/CMakeLists.txt @@ -0,0 +1,15 @@ +# the minimum version of CMake. +cmake_minimum_required(VERSION 3.5.0) +project(MyNDKDemo) + +set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + +if(DEFINED PACKAGE_FIND_FILE) + include(${PACKAGE_FIND_FILE}) +endif() + +include_directories(${NATIVERENDER_ROOT_PATH} + ${NATIVERENDER_ROOT_PATH}/include) + +add_library(entry SHARED napi_init.cpp NativeEntry.cpp) +target_link_libraries(entry PUBLIC libace_napi.z.so libace_ndk.z.so libhilog_ndk.z.so) \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/LazyTextListExample.h b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/LazyTextListExample.h new file mode 100644 index 0000000000000000000000000000000000000000..e2c6560d38d45caeacd241d7afbb1109656bb567 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/LazyTextListExample.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// [Start Grouped_List_Interface] +// LazyTextListExample +// 懒加载列表示例代码。 + +#ifndef MYAPPLICATION_LAZYTEXTLISTEXAMPLE_H +#define MYAPPLICATION_LAZYTEXTLISTEXAMPLE_H + +#include "ArkUIBaseNode.h" +#include "ArkUIListNode.h" + +namespace NativeModule { + +std::shared_ptr CreateLazyTextListExample(napi_env env) +{ + // 创建组件并挂载 + // 1:创建List组件。 + auto list = std::make_shared(); + list->SetPercentWidth(1); + list->SetPercentHeight(1); + // 2:创建ListItem懒加载组件并挂载到List上。 + auto adapter = std::make_shared(); + list->SetLazyAdapter(adapter); + return list; +} +} // namespace NativeModule + +#endif // MYAPPLICATION_LAZYTEXTLISTEXAMPLE_H +// [End Grouped_List_Interface] \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/LazyTextListExample1.h b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/LazyTextListExample1.h new file mode 100644 index 0000000000000000000000000000000000000000..f6f87519fde427309405942f657097c47661a05f --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/LazyTextListExample1.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// [Start Grouped_List] +// LazyTextListExample.h +// 懒加载列表示例代码。 +#ifndef MYAPPLICATION_LAZYTEXTLISTEXAMPLE_H +#define MYAPPLICATION_LAZYTEXTLISTEXAMPLE_H +#include "ArkUIBaseNode.h" +#include "ArkUIListNode.h" +#include "ArkUIListItemGroupNode.h" +namespace NativeModule { +const int32_t NUMBER_3 = 3; +const int32_t NUMBER_50 = 50; + +std::shared_ptr CreateLazyTextListExample() +{ + // 创建组件并挂载 + // 1: 创建List组件。 + auto list = std::make_shared(); + list->SetPercentWidth(1); + list->SetPercentHeight(1); + // 设置吸顶 + list->SetSticky(ARKUI_STICKY_STYLE_BOTH); + // 2: 创建ListItemGroup并挂载到List上。 + for (int32_t i = 0; i < NUMBER_3; i++) { + auto header = std::make_shared(); + header->SetTextContent("header"); + header->SetFontSize(NUMBER_16); + header->SetPercentWidth(1); + header->SetHeight(NUMBER_50); + header->SetBackgroundColor(0xFFDCDCDC); + header->SetTextAlign(ARKUI_TEXT_ALIGNMENT_CENTER); + auto listItemGroup = std::make_shared(); + listItemGroup->SetHeader(header); + auto adapter = std::make_shared(); + listItemGroup->SetLazyAdapter(adapter); + list->AddChild(listItemGroup); + } + return list; +} +} // namespace NativeModule +#endif // MYAPPLICATION_LAZYTEXTLISTEXAMPLE_H +// [End Grouped_List] \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/NativeEntry.cpp b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/NativeEntry.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7ebe504c37266f156c7321ad5e995906bbe0bdf5 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/NativeEntry.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// [Start Interface_entrance_mounting_file] +// NDK接口入口挂载文件。 + +#include "NativeEntry.h" + +#include "LazyTextListExample1.h" + +#include +#include +#include +#include + +namespace NativeModule { + +napi_value CreateNativeRoot(napi_env env, napi_callback_info info) +{ + size_t argc = 1; + napi_value args[1] = {nullptr}; + + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + // 获取NodeContent + ArkUI_NodeContentHandle contentHandle; + OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &contentHandle); + NativeEntry::GetInstance()->SetContentHandle(contentHandle); + + // 创建懒加载文本列表 + auto node = CreateLazyTextListExample(); + + // 保持Native侧对象到管理类中,维护生命周期。 + NativeEntry::GetInstance()->SetRootNode(node); + return nullptr; +} + +napi_value DestroyNativeRoot(napi_env env, napi_callback_info info) +{ + // 从管理类中释放Native侧对象。 + NativeEntry::GetInstance()->DisposeRootNode(); + return nullptr; +} + +} // namespace NativeModule +// [End Interface_entrance_mounting_file] \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/NativeEntry.h b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/NativeEntry.h new file mode 100644 index 0000000000000000000000000000000000000000..8539a104696c7c1cfb575b900e92b273158a59eb --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/NativeEntry.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// NativeEntry.h + +#ifndef MYAPPLICATION_NATIVEENTRY_H +#define MYAPPLICATION_NATIVEENTRY_H + +#include +#include +#include + +namespace NativeModule { + +napi_value CreateNativeRoot(napi_env env, napi_callback_info info); + +napi_value DestroyNativeRoot(napi_env env, napi_callback_info info); + +// 管理Native组件的生命周期和内存。 +class NativeEntry { +public: + static NativeEntry *GetInstance() + { + static NativeEntry nativeEntry; + return &nativeEntry; + } + + void SetContentHandle(ArkUI_NodeContentHandle handle) + { + handle_ = handle; + } + + void SetRootNode(const std::shared_ptr &baseNode) + { + root_ = baseNode; + // 添加Native组件到NodeContent上用于挂载显示。 + OH_ArkUI_NodeContent_AddNode(handle_, root_->GetHandle()); + } + + void DisposeRootNode() + { + // 从NodeContent上卸载组件并销毁Native组件。 + OH_ArkUI_NodeContent_RemoveNode(handle_, root_->GetHandle()); + root_.reset(); + } + +private: + std::shared_ptr root_; + ArkUI_NodeContentHandle handle_; +}; + +} // namespace NativeModule + +#endif // MYAPPLICATION_NATIVEENTRY_H \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/NativeModule.h b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/NativeModule.h new file mode 100644 index 0000000000000000000000000000000000000000..c2ab7178a5666c80ec0b83f0f206143c55977e4b --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/NativeModule.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// NativeModule.h +// 提供获取ArkUI在Native侧模块的封装接口 + +#ifndef MYAPPLICATION_NATIVEMODULE_H +#define MYAPPLICATION_NATIVEMODULE_H + +#include "napi/native_api.h" +#include +#include + +#include + +namespace NativeModule { + +class NativeModuleInstance { +public: + static NativeModuleInstance *GetInstance() + { + static NativeModuleInstance instance; + return &instance; + } + + NativeModuleInstance() + { + OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, arkUINativeNodeApi_); + } + // 暴露给其他模块使用。 + ArkUI_NativeNodeAPI_1 *GetNativeNodeAPI() { return arkUINativeNodeApi_; } + +private: + ArkUI_NativeNodeAPI_1 *arkUINativeNodeApi_ = nullptr; +}; + +} // namespace NativeModule + +#endif // MYAPPLICATION_NATIVEMODULE_H \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/napi_init.cpp b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/napi_init.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4cffba215762b98695f791af61cadc0e8e7b81f6 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/napi_init.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// entry/src/main/cpp/napi_init.cpp +#include "napi/native_api.h" +#include "NativeEntry.h" + +EXTERN_C_START +static napi_value Init(napi_env env, napi_value exports) +{ + // 绑定Native侧的创建组件和销毁组件。 + napi_property_descriptor desc[] = { + {"createNativeRoot", nullptr, NativeModule::CreateNativeRoot, nullptr, nullptr, nullptr, napi_default, nullptr}, + {"destroyNativeRoot", nullptr, NativeModule::DestroyNativeRoot, nullptr, nullptr, nullptr, napi_default, + nullptr}}; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + return exports; +} +EXTERN_C_END + +static napi_module demoModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "entry", + .nm_priv = ((void *)0), + .reserved = {0}, +}; + +extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); } \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/types/libentry/Index.d.ts b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/types/libentry/Index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..06c9f41df7fdb7bf81a627dedc5ca307392f6d52 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/types/libentry/Index.d.ts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// entry/src/main/cpp/types/libentry/Index.d.ts + +export const createNativeRoot: (content: Object) => void; +export const destroyNativeRoot: () => void; diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/types/libentry/oh-package.json5 b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/types/libentry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..6abf3b7c20f22c62aaac6a995a25cae672f73f35 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/cpp/types/libentry/oh-package.json5 @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "name": "libentry.so", + "types": "./Index.d.ts", + "version": "1.0.0", + "description": "Please describe the basic information." +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/ets/entryability/EntryAbility.ets b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..62f53acbc95e5be7985f8fb1fe2db591cea260bd --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (err) { + hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err)); + } + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..0a97e21bd7a15599af76a806695860ff1eb0ebfe --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/ArkUIKit/PersistentStorage/entry/src/main/ets/pages/PageTowPersistentStorage.ets b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/ets/pages/Index.ets similarity index 54% rename from ArkUIKit/PersistentStorage/entry/src/main/ets/pages/PageTowPersistentStorage.ets rename to ArkUIKit/NativeType/NdkCreateList/entry/src/main/ets/pages/Index.ets index 68b9d2d8e354545d7bd14044d49387346069b7e0..7c28466949214883f639a1d66de320965ab3cb1a 100644 --- a/ArkUIKit/PersistentStorage/entry/src/main/ets/pages/PageTowPersistentStorage.ets +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/ets/pages/Index.ets @@ -12,28 +12,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// [Start Persistent_page_tow] -let aProp = AppStorage.setOrCreate('aProp', 47); -PersistentStorage.persistProp('aProp', 48); +interface Ary { + path:string, + name:string +} @Entry @Component -struct TestPageTwo { - @State message: string = 'Hello World'; - @StorageLink('aProp') aProp: number = 50; - +struct Index { + ary:Ary[]=[ + { + name:'LazyTextListExample', + path:'pages/LazyTextListExample' + } + ]; build() { - Row() { - Column() { - Text(this.message) - // 应用退出时会保存当前结果。重新启动后,会显示上一次的保存结果 - // 未修改时默认值为47 - Text(`${this.aProp}`) - .onClick(() => { - this.aProp += 1; - }) + Scroll() { + Column({ space: 10 }) { + ForEach(this.ary,(item:Ary)=>{ + Button(item.name) + .onClick(() => this.getUIContext().getRouter().pushUrl({url:item.path})) + },(item:Ary)=>item.name) } + .width(300) } } -} -// [End Persistent_page_tow] \ No newline at end of file +} \ No newline at end of file diff --git a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/SetOmissionProperty.ets b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/ets/pages/LazyTextListExample.ets similarity index 45% rename from ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/SetOmissionProperty.ets rename to ArkUIKit/NativeType/NdkCreateList/entry/src/main/ets/pages/LazyTextListExample.ets index cdf8397bfc230bee0cc98f07f7642aace1a87560..d386aa411ac5d784e36c5e5db9ff105ddc6e6766 100644 --- a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/SetOmissionProperty.ets +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/ets/pages/LazyTextListExample.ets @@ -13,30 +13,26 @@ * limitations under the License. */ -import { ComponentCard } from '../../common/Card'; +import nativeNode from 'libentry.so'; +import { NodeContent } from '@kit.ArkUI'; @Entry @Component -export struct SetOmissionProperty { +struct Index { + // 初始化NodeContent对象。 + private rootSlot = new NodeContent(); + build() { - NavDestination() { - Column({ space: 12 }) { - ComponentCard({ description: $r('app.string.Set_Omission_Property_description') }) { - // [Start set_omission_property] - TextInput({ text: $r('app.string.Set_Omission_Property_textContent') }) - .textOverflow(TextOverflow.Ellipsis) - .ellipsisMode(EllipsisMode.END) - .style(TextInputStyle.Inline) - .fontSize(30) - .margin(30) - // [End set_omission_property] - } - } - .width('100%') - .height('100%') - .padding({ left: 12, right: 12 }) + Column() { + Button('ShowNativeUI').onClick(() => { + nativeNode.createNativeRoot(this.rootSlot); + }) + Row() { + // 将NodeContent和ContentSlot占位组件绑定。 + ContentSlot(this.rootSlot); + }.layoutWeight(1) } - .backgroundColor('#f1f2f3') - .title($r('app.string.Set_Omission_Property')) + .width('100%') + .height('100%') } } \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/module.json5 b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..9d179325a9a4cfa7d090354c3954d3a73acca327 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/module.json5 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "ohos.want.action.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/element/color.json b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/element/float.json b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/element/string.json b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/media/background.png b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/media/background.png differ diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/media/foreground.png b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/media/foreground.png differ diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/media/layered_image.json b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/ArkUIKit/statemanagementproject/entry/src/main/resources/base/media/startIcon.png b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/media/startIcon.png similarity index 87% rename from ArkUIKit/statemanagementproject/entry/src/main/resources/base/media/startIcon.png rename to ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/media/startIcon.png index a31c7f86b9157290e9278a80f48ff93b61b5a60d..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b 100644 Binary files a/ArkUIKit/statemanagementproject/entry/src/main/resources/base/media/startIcon.png and b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/media/startIcon.png differ diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/profile/backup_config.json b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/profile/main_pages.json b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..d66dd4a50aeaef466858f75869539af5ccad824c --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,6 @@ +{ + "src": [ + "pages/LazyTextListExample", + "pages/Index" + ] +} diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/dark/element/color.json b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/main/syscap.json b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/syscap.json new file mode 100644 index 0000000000000000000000000000000000000000..ab50d1a5b1f72ec8788ea4c02956e86ef0837953 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/main/syscap.json @@ -0,0 +1,23 @@ + +{ + "devices": { + "general": [ + "default", + "tablet" + ] + }, + "production": { + "removedSysCaps": [ + "SystemCapability.HiviewDFX.HiDumper", + "SystemCapability.Security.DeviceAuth", + "SystemCapability.Multimedia.Media.AVTranscoder", + "SystemCapability.Tee.TeeClient", + "SystemCapability.Communication.Bluetooth.Core", + "SystemCapability.ArkUi.Graphics3D", + "SystemCapability.DistributedHardware.DeviceManager", + "SystemCapability.Multimedia.Drm.Core", + "SystemCapability.Advertising.Ads", + "SystemCapability.Customization.EnterpriseDeviceManager" + ] + } +} diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/mock/Libentry.mock.ets b/ArkUIKit/NativeType/NdkCreateList/entry/src/mock/Libentry.mock.ets new file mode 100644 index 0000000000000000000000000000000000000000..eebf1ed910f6a8f2a9e7e565aa71b179b7b8b537 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/mock/Libentry.mock.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const NativeMock: Record = { + 'add': (a: number, b: number) => { + return a + b; + }, +}; + +export default NativeMock; \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/mock/mock-config.json5 b/ArkUIKit/NativeType/NdkCreateList/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2c7d2ba82b796a2850ced0a277d261d7d7355416 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/mock/mock-config.json5 @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "libentry.so": { + "source": "src/mock/Libentry.mock.ets" + } +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/ohosTest/ets/test/Ability.test.ets b/ArkUIKit/NativeType/NdkCreateList/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..0f8ce9a2c012f8fe36114cef65216ef0b6254f41 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/ohosTest/ets/test/Index.test.ets b/ArkUIKit/NativeType/NdkCreateList/entry/src/ohosTest/ets/test/Index.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..8a9b79cf4a480d893b4ff7aa58d282500542312e --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/ohosTest/ets/test/Index.test.ets @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, beforeAll, it, expect, Level, Size, TestType } from '@ohos/hypium' +// 导入测试依赖kit +import { abilityDelegatorRegistry, Driver, ON, MouseButton, Component, MatchPattern } from '@kit.TestKit'; +import { UIAbility, Want } from '@kit.AbilityKit'; +import hilog from '@ohos.hilog'; + +const delegator: abilityDelegatorRegistry.AbilityDelegator = abilityDelegatorRegistry.getAbilityDelegator(); +const bundleName = abilityDelegatorRegistry.getArguments().bundleName; +let abilityDelegator: abilityDelegatorRegistry.AbilityDelegator; +abilityDelegator = abilityDelegatorRegistry.getAbilityDelegator(); +let want: Want; + +const TAG = '[Sample_NdkAddInteractionEvent]'; +const DOMAIN = 0xF811; +const BUNDLE = 'NdkAddInteractionEvent_'; +const ONE_SECONDS_TIME = 1000; + +function sleep(time: number) { + return new Promise((resolve: Function) => setTimeout(resolve, time)); +} + +export default function IndexTest() { + + describe('IndexTest', () => { + + beforeAll(async () => { + }) + + /** + * @tc.number: LazyTextListExampleTest_001 + * @tc.name: Lazy text list example + * @tc.desc: Test lazy text list example + * @tc.size: MediumTest + * @tc.type: Function + * @tc.level Level 1 + */ + it('LazyTextListExampleTest_001', TestType.FUNCTION | Size.MEDIUMTEST | Level.LEVEL1, async (done: Function) => { + hilog.info(DOMAIN, TAG, BUNDLE + 'LazyTextListExampleTest_001, begin'); + want = { + bundleName: bundleName, + abilityName: 'EntryAbility' + }; + await delegator.startAbility(want); + await sleep(ONE_SECONDS_TIME); + let driver = Driver.create(); + let button_root = await driver.findComponent(ON.text('LazyTextListExample', MatchPattern.CONTAINS)); + await button_root.click(); + let button_list = await driver.findComponent(ON.text('ShowNativeUI', MatchPattern.CONTAINS)); + expect(button_list === null).assertFalse(); + await button_list.click(); + await driver.pressBack(); + await driver.pressBack(); + await driver.delayMs(ONE_SECONDS_TIME); + hilog.info(DOMAIN, TAG, BUNDLE + 'LazyTextListExampleTest_001, end'); + done(); + }) + }) +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/ohosTest/ets/test/List.test.ets b/ArkUIKit/NativeType/NdkCreateList/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..a1951e50c73703b8b1fe39390c5287b68a1bf394 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import abilityTest from './Ability.test'; +import IndexTest from './Index.test'; + +export default function testsuite() { + abilityTest(); + IndexTest(); +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/ohosTest/module.json5 b/ArkUIKit/NativeType/NdkCreateList/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..84d30586d591412f4252801cc483bbc6d8554104 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/ohosTest/module.json5 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "default" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/test/List.test.ets b/ArkUIKit/NativeType/NdkCreateList/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f1186b1f53c3a70930921c5dbd1417332bec56c9 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/test/List.test.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/entry/src/test/LocalUnit.test.ets b/ArkUIKit/NativeType/NdkCreateList/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..7fc57c77dbf76d8df08a2b802a55b948e3fcf968 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/hvigor/hvigor-config.json5 b/ArkUIKit/NativeType/NdkCreateList/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..b8fea3f097bd68b0bc4d87de986d2cb7732c1d9b --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/hvigor/hvigor-config.json5 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "modelVersion": "6.0.0", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | "ultrafine" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + // "optimizationStrategy": "memory" /* Define the optimization strategy. Value: [ "memory" | "performance" ]. Default: "memory" */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/ArkUIKit/NativeType/NdkCreateList/hvigorfile.ts b/ArkUIKit/NativeType/NdkCreateList/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..e3340f07e45ddc5dcadbb87012668555def2e6e0 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/hvigorfile.ts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/ArkUIKit/NativeType/NdkCreateList/oh-package.json5 b/ArkUIKit/NativeType/NdkCreateList/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..69cb43cba3addcee1840403c67405134a2a9102c --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/oh-package.json5 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "modelVersion": "6.0.0", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.24", + "@ohos/hamock": "1.0.0" + } +} diff --git a/ArkUIKit/NativeType/NdkCreateList/ohosTest.md b/ArkUIKit/NativeType/NdkCreateList/ohosTest.md new file mode 100644 index 0000000000000000000000000000000000000000..f1447cc6f4d06c53926fe24be8c7d97358b52b70 --- /dev/null +++ b/ArkUIKit/NativeType/NdkCreateList/ohosTest.md @@ -0,0 +1,6 @@ +| 测试功能 | 预置条件 | 输入 | 预期输出 | 测试结果 | +|---------------------------------| ------------ | ---------------------- |-----------------| -------- | +| 首页加载测试 | 设备正常运行 | 验证基础元素渲染 | 检查标题和列表组件 | Pass | +| 分组列表测试 | 设备正常运行 | 点击"LazyTextListExample",再点击"ShowNativeUI" | 页面加载成功,分组列表显示正常 | Pass | + + diff --git a/ArkUIKit/NativeType/NdkCreateList/screenshots/result.jpg b/ArkUIKit/NativeType/NdkCreateList/screenshots/result.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2ffafe432998ca92bfdb13b3a9ef0ff656457b51 Binary files /dev/null and b/ArkUIKit/NativeType/NdkCreateList/screenshots/result.jpg differ diff --git a/ArkUIKit/NavigationSample/screenshots/device/1.png b/ArkUIKit/NavigationSample/screenshots/device/1.png deleted file mode 100644 index 9ea3f73ebfc4d9b903173f52ddf8ee1674f034df..0000000000000000000000000000000000000000 Binary files a/ArkUIKit/NavigationSample/screenshots/device/1.png and /dev/null differ diff --git a/ArkUIKit/Prop/entry/src/main/ets/pages/PageSeventeen.ets b/ArkUIKit/Prop/entry/src/main/ets/pages/PageSeventeen.ets index 061675d9003a18b4f453c18f4145b7a861a6b8b9..0f37b939675a23ec12d2dd220df781cbad3f0ba4 100644 --- a/ArkUIKit/Prop/entry/src/main/ets/pages/PageSeventeen.ets +++ b/ArkUIKit/Prop/entry/src/main/ets/pages/PageSeventeen.ets @@ -61,7 +61,8 @@ struct NestedDisplay { Button('change title.value to "Hi"') .onClick(() => { // [Start prop_seventeen_start] - this.title.value = 'Hi'; // 第一层属性变化,UI 会更新 + // 可以观察到第一层的变化 + this.title.value = 'Hi'; // [End prop_seventeen_start] }) @@ -69,7 +70,8 @@ struct NestedDisplay { Button('change title.info.value to "ArkUI"') .onClick(() => { // [Start prop_seventeen_start] - this.title.info.value = 'ArkUI'; // 第二层属性变化,@Prop 无反应 + // 观察不到第二层的变化 + this.title.info.value = 'ArkUI'; // [End prop_seventeen_start] }) diff --git a/ArkUIKit/ProviderConsumer/README_zh.md b/ArkUIKit/ProviderConsumer/README_zh.md index 4e749b878646cbdd9fa60eb6696881decf40ff97..57b64061e97ca5f30c6c4254064b82648915b051 100644 --- a/ArkUIKit/ProviderConsumer/README_zh.md +++ b/ArkUIKit/ProviderConsumer/README_zh.md @@ -1,13 +1,15 @@ -# ArkUI使用滚动类指南文档示例 +# @Provider装饰器和@Consumer装饰器指南文档示例 ### 介绍 -本示例展示了[@Once:初始化同步一次](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/ui/arkts-color-effect.md)装饰器的使用方法: +@Provider和@Consumer用于跨组件层级数据双向同步,可以使得开发者不用拘泥于组件层级。 + +@Provider和@Consumer属于状态管理V2装饰器,所以只能在@ComponentV2中才能使用,在@Component中使用会编译报错。 使用说明: 1. 该工程可以选择在模拟器和开发板上运行。 2. 点击构建,即可在生成的应用中点击对应的按钮,观察自定义占位节点的不同应用。 -3. 进入”DocsSample/ArkUISample/internationalization/entry/src/ohosTest/ets/test/index.test.ets“文件,可以对本项目进行UI的自动化测试。 +3. 进入”DocsSample/ArkUISample/ProviderConsumer/entry/src/ohosTest/ets/test/index.test.ets“文件,可以对本项目进行UI的自动化测试。 ### 效果预览 | 首页 | 列表类组件目录 | 列表中显示数据示例 | @@ -29,6 +31,7 @@ entry/src/main/ets/ |---entryability |---homePage +| |---BuilderNode.ets @Consumer在跨BuilderNode场景下和@Provider建立双向同步过程 | |---CodeFirst.ets 点击第一段代码 | |---CodeSecond.ets 点击第二段代码 | |---CodeThree.ets 点击第三段代码 @@ -42,8 +45,6 @@ entry/src/main/ets/ | |---NoTwowayBinding.ets 点击未建立双向绑定 | |---ProviderSame.ets 点击@Provider重名时 | |---TwowayBinding.ets 点击未建立双向绑定 - - |---pages | |---Index.ets // 应用主页面 entry/src/ohosTest/ diff --git a/ArkUIKit/ProviderConsumer/entry/src/main/ets/homePage/BuilderNode.ets b/ArkUIKit/ProviderConsumer/entry/src/main/ets/homePage/BuilderNode.ets index 668e57ab6992b11f62f1036339e75a4b774b54f8..90d0ed2262b6533f8db1e08f77b8c790bbd85dc1 100644 --- a/ArkUIKit/ProviderConsumer/entry/src/main/ets/homePage/BuilderNode.ets +++ b/ArkUIKit/ProviderConsumer/entry/src/main/ets/homePage/BuilderNode.ets @@ -64,7 +64,6 @@ class TextNodeController extends NodeController { @ComponentV2 struct RemoChildDisconnectProvider { @Provider() content: string = 'Index: hello world'; - @Monitor('content') providerWatch() { console.info(`Provider change ${this.content}`); @@ -109,7 +108,6 @@ struct RemoChildDisconnectProvider { @ComponentV2 struct TestRemove { @Consumer() content: string = 'default value'; - @Monitor('content') consumerWatch() { console.info(`Consumer change ${this.content}`); diff --git a/ArkUIKit/ProviderConsumer/entry/src/main/ets/homePage/DecorativeSet.ets b/ArkUIKit/ProviderConsumer/entry/src/main/ets/homePage/DecorativeSet.ets index 710ca0ab0476b1533c87892e7d927b51539f25f1..f02b4ef39f3bd33971a5afba8c34f35fba672bfe 100644 --- a/ArkUIKit/ProviderConsumer/entry/src/main/ets/homePage/DecorativeSet.ets +++ b/ArkUIKit/ProviderConsumer/entry/src/main/ets/homePage/DecorativeSet.ets @@ -16,7 +16,7 @@ // [Start Decorative_Set] @Entry @ComponentV2 -export struct Parent { +struct Parent { @Provider() message: Set = new Set([1, 2, 3, 4]); build() { diff --git a/ArkUIKit/ProviderConsumer/entry/src/main/ets/homePage/DragDrop.ets b/ArkUIKit/ProviderConsumer/entry/src/main/ets/homePage/DragDrop.ets index c8ccf7e2a93d77318670e90bab8b0daa004d4690..39fd2db63ec1a5c5746177b17a01d2f411b112fc 100644 --- a/ArkUIKit/ProviderConsumer/entry/src/main/ets/homePage/DragDrop.ets +++ b/ArkUIKit/ProviderConsumer/entry/src/main/ets/homePage/DragDrop.ets @@ -35,8 +35,7 @@ struct Parent { @ComponentV2 struct Child { - @Consumer() onDrag: (x: number, y: number) => void = (x: number, y: number) => { - }; + @Consumer() onDrag: (x: number, y: number) => void = (x: number, y: number) => {}; build() { Button('changed') @@ -47,7 +46,6 @@ struct Child { }) } } - // [End Drag_Drop] @Component diff --git a/ArkUIKit/ProviderConsumer/screenshots/device/image1.png b/ArkUIKit/ProviderConsumer/screenshots/device/image1.png index 388aa1c5cef1559f87a57cbbce8fccf2f6159127..725b8fca6aae764d3f4cdb3798786e0f3a34f2c3 100644 Binary files a/ArkUIKit/ProviderConsumer/screenshots/device/image1.png and b/ArkUIKit/ProviderConsumer/screenshots/device/image1.png differ diff --git a/ArkUIKit/ProviderConsumer/screenshots/device/image2.png b/ArkUIKit/ProviderConsumer/screenshots/device/image2.png index 2f74fba9a56cad4b8602738a0996d18f90538787..e4f93ff9bbd66d813652578188e973ab9fb218e2 100644 Binary files a/ArkUIKit/ProviderConsumer/screenshots/device/image2.png and b/ArkUIKit/ProviderConsumer/screenshots/device/image2.png differ diff --git a/ArkUIKit/ReusableV2/.gitignore b/ArkUIKit/ReusableV2/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/ArkUIKit/ReusableV2/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/AppScope/app.json5 b/ArkUIKit/ReusableV2/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2b50ed97f69957a02bfbdecca38751c19d0fc4b5 --- /dev/null +++ b/ArkUIKit/ReusableV2/AppScope/app.json5 @@ -0,0 +1,23 @@ +/* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "app": { + "bundleName": "com.samples.reusablev2", + "vendor": "samples", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/ArkUIKit/ReusableV2/AppScope/resources/base/element/string.json b/ArkUIKit/ReusableV2/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..b7f9f702a3711aed9a60c35e95b5951d260c3c59 --- /dev/null +++ b/ArkUIKit/ReusableV2/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "ReusableV2" + } + ] +} diff --git a/ArkUIKit/ReusableV2/AppScope/resources/base/media/background.png b/ArkUIKit/ReusableV2/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/ArkUIKit/ReusableV2/AppScope/resources/base/media/background.png differ diff --git a/ArkUIKit/ReusableV2/AppScope/resources/base/media/foreground.png b/ArkUIKit/ReusableV2/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..eb9427585b36d14b12477435b6419d1f07b3e0bb Binary files /dev/null and b/ArkUIKit/ReusableV2/AppScope/resources/base/media/foreground.png differ diff --git a/ArkUIKit/ReusableV2/AppScope/resources/base/media/layered_image.json b/ArkUIKit/ReusableV2/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/ArkUIKit/ReusableV2/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/README_zh.md b/ArkUIKit/ReusableV2/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..4bd063570949718eaf64dd0d46af8cb44a76f519 --- /dev/null +++ b/ArkUIKit/ReusableV2/README_zh.md @@ -0,0 +1,188 @@ +# ArkUI使用@ReusableV2装饰器:组件复用指南文档示例 + +### 介绍 + +本示例通过使用[ArkUI指南文档](https://docs.openharmony.cn/pages/v6.0/zh-cn/application-dev/ui/state-management/arkts-basic-syntax-overview.md)中各场景的开发示例,展示在工程中,帮助开发者更好地理解ArkUI提供的组件及组件属性并合理使用。该工程中展示的代码详细描述可查如下链接: + +### 1.[线性容器(Column)](https://docs.openharmony.cn/pages/v6.0/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-column.md) + +### 2.[文本显示器(Text)](https://docs.openharmony.cn/pages/v5.1/en/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-text.md) + +### 3.[Button](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-button.md) + +## 预览效果 + +![](screenshots/device/image1.jpeg) + +![](screenshots/device/image3.jpeg) + +![](screenshots/device/imag3.jpeg) + +![](screenshots/device/image2.jpeg) + +![](screenshots/device/image4.jpeg) + +## 具体实现 +1. 基本功能与适用范围 + 核心作用:优化组件性能,减少反复创建销毁组件的开销 + 适用范围:仅能装饰 @ComponentV2 标记的 V2 自定义组件 + 主要特性: + 组件回收回收至复用池而非销毁 + 复用池中的组件自动冻结,不响应状态变化 + 复用时前自动重置状态变量,确保组件纯净性 + 启用方式:在 @ComponentV2 前添加 @ReusableV2 装饰器 +2. 生命周期与状态管理 + 关键生命周期: + aboutToRecycle():组件被回收时调用 + aboutToReuse():组件被复用时调用 + 状态重置规则: + @Local:使用定义时的初始值 + @Param:使用外部传入值或本地初始值 + @Computed:重新计算 + @Monitor:重置并触发回调 + 自动冻结机制:回收期间组件自动冻结,不响应状态变化 +3. 使用方式与配置 + 基本语法: + @ReusableV2 + @ComponentV2 + struct MyComponent { + // 组件实现 + } + 复用选项配置: + ReusableV2Component() + .reuse({ reuseId: () => 'custom-id' }) + 默认行为:未指定 reuseId 时使用组件名作为默认 ID + + +## 使用说明 + +### 1.在进入主页面后,点击页面按钮进行查看 + +## 工程目录结构 + + +``` +├─ AppScope +│ ├─ app.json5 +│ └─ resources +│ └─ base +│ ├─ element +│ │ └─ string.json +│ └─ media +│ ├─ background.png +│ ├─ foreground.png +│ └─ layered_image.json +├─ code-linter.json5 +├─ entry +│ ├─ hvigorfile.ts +│ ├─ obfuscation-rules.txt +│ ├─ oh-package.json5 +│ └─ src +│ ├─ main +│ │ ├─ ets +│ │ │ ├─ common // 复用组件 +│ │ │ │ ├─ NormalV2Component.ets +│ │ │ │ ├─ ReusableV2Component.ets +│ │ │ │ ├─ ReusableV2Component1.ets +│ │ │ │ ├─ ReusableV2Component2.ets +│ │ │ │ ├─ ReusableV2Component3.ets +│ │ │ │ ├─ ReusableV2Component4.ets +│ │ │ │ ├─ ReusableV2Component5.ets +│ │ │ │ ├─ ReusableV2Component6.ets +│ │ │ │ ├─ ReusableV2Component7.ets +│ │ │ │ ├─ ReusableV2Component8.ets +│ │ │ │ └─ ReusableV2Component9.ets +│ │ │ ├─ entryability +│ │ │ │ └─ EntryAbility.ets +│ │ │ ├─ entrybackupability +│ │ │ │ └─ EntryBackupAbility.ets +│ │ │ ├─ pages +│ │ │ │ └─ Index.ets // 主页面 +│ │ │ └─ view +│ │ │ ├─ Page1.ets // 装饰器说明 +│ │ │ ├─ Page10.ets // 接口说明 +│ │ │ ├─ Page11.ets // 使用限制 +│ │ │ ├─ Page12.ets // V1和V2支持部分混用场景 +│ │ │ ├─ Page13.ets // 回收与复用的生命周期 +│ │ │ ├─ Page2.ets // 复用阶段的冻结 +│ │ │ ├─ Page3.ets // 复用前的组件内状态变量重置 +│ │ │ ├─ Page4.ets // 简化复用前的组件内状态变量重置 +│ │ │ ├─ Page5.ets // 在if组件中使用通过改变if组件的条件可以控制组件回收/复用。 +│ │ │ ├─ Page6.ets // 在Repeat组件中使用 +│ │ │ ├─ Page7.ets // 在Repeat组件非懒加载场景的each属性中使用 +│ │ │ ├─ Page8.ets // 在ForEach组件中使用 +│ │ │ └─ Page9.ets // 在LazyForEach组件中使用 +│ │ ├─ module.json5 +│ │ └─ resources +│ │ ├─ base +│ │ │ ├─ element +│ │ │ │ ├─ color.json +│ │ │ │ ├─ float.json +│ │ │ │ └─ string.json +│ │ │ ├─ media +│ │ │ │ ├─ background.png +│ │ │ │ ├─ foreground.png +│ │ │ │ ├─ layered_image.json +│ │ │ │ └─ startIcon.png +│ │ │ └─ profile +│ │ │ ├─ backup_config.json +│ │ │ └─ main_pages.json +│ │ ├─ dark +│ │ │ └─ element +│ │ │ └─ color.json +│ │ └─ rawfile +│ ├─ mock +│ │ └─ mock-config.json5 +│ ├─ ohosTest +│ │ ├─ ets +│ │ │ └─ test +│ │ │ ├─ Ability.test.ets +│ │ │ ├─ index.test.ets +│ │ │ └─ List.test.ets +│ │ └─ module.json5 +│ └─ test +│ ├─ List.test.ets +│ └─ LocalUnit.test.ets +├─ hvigor +│ └─ hvigor-config.json5 +├─ hvigorfile.ts +├─ oh-package-lock.json5 +├─ oh-package.json5 +├─ README_zh.md +└─ screenshots // 预览图片 + └─ device + ├─ image1.png + ├─ image2.png + └─ image3.png + +``` + +````` +### 相关权限 + +不涉及。 + +### 依赖 + +不涉及。 + +### 约束与限制 + +1.本示例仅支持标准系统上运行, 支持设备:RK3568。 + +2.本示例为Stage模型,支持API20版本SDK,版本号:6.0.0.33,镜像版本号:OpenHarmony_6.0.0.33。 + +3.本示例需要使用DevEco Studio 6.0.0 Canary1 (Build Version: 6.0.0.270, built on May 9, 2025)及以上版本才可编译运行。 + +### 下载 + +如需单独下载本工程,执行如下命令: + +```` +git init +git config core.sparsecheckout true +echo code/DocsSample/ArkUISample/ReusableV2 > .git/info/sparse-checkout +git remote add origin https://gitcode.com/openharmony/applications_app_samples.git +git pull origin master +```` +````` \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/build-profile.json5 b/ArkUIKit/ReusableV2/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3ca5a93fb814017ac4c398aacbdf17b1d8b0a237 --- /dev/null +++ b/ArkUIKit/ReusableV2/build-profile.json5 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "6.0.0(20)", + "compatibleSdkVersion": "6.0.0(20)", + "targetSdkVersion": "6.0.0(20)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/code-linter.json5 b/ArkUIKit/ReusableV2/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..5c4682f8164874ec7e9cb8f99ff8b3228ffbc126 --- /dev/null +++ b/ArkUIKit/ReusableV2/code-linter.json5 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/.gitignore b/ArkUIKit/ReusableV2/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/build-profile.json5 b/ArkUIKit/ReusableV2/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..9016faf39f8a65cf648bae246a53575510fe8b9f --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/build-profile.json5 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "apiType": "stageMode", + "buildOption": { + "resOptions": { + "copyCodeResource": { + "enable": false + } + } + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/hvigorfile.ts b/ArkUIKit/ReusableV2/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f8b117a17af3b2d7cb87a7680e29e2bb8ccd5b46 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/hvigorfile.ts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/obfuscation-rules.txt b/ArkUIKit/ReusableV2/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/oh-package.json5 b/ArkUIKit/ReusableV2/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..10cda399b0aec3099b257299a57d284393e4e55a --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/oh-package.json5 @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/common/NormalV2Component.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/common/NormalV2Component.ets new file mode 100644 index 0000000000000000000000000000000000000000..ceab27198c4b294381418bd9d2d408954ffd2f90 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/common/NormalV2Component.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//[Start NormalV2Component] +import { ReusableV2Component } from './ReusableV2Component1'; +@ComponentV2 +export struct NormalV2Component { + @Require @Param condition: boolean; + build() { + if (this.condition) { + ReusableV2Component() + } + } +} +//[End NormalV2Component] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component.ets new file mode 100644 index 0000000000000000000000000000000000000000..0f0176c6405a694570c1599078a28b395967c7f0 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// [Start ReusableV2Component] +@ComponentV2 +export struct ReusableV2Component { + aboutToAppear() { + } + aboutToDisappear() { + } + aboutToRecycle() { + } + aboutToReuse() { + } + build() { + Column() { + Text('ReusableV2Component') + } + } +} +// [End ReusableV2Component] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component1.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component1.ets new file mode 100644 index 0000000000000000000000000000000000000000..6b8776daf027bf08b9a1eaf5b59b8a050c0801c9 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component1.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// [Start ReusableV2Component1] +@ReusableV2 // 装饰ComponentV2的自定义组件 +@ComponentV2 +export struct ReusableV2Component { + @Local message: string = 'Hello World'; + build () { + Column() { + Text(this.message) + } + } +} +// [End ReusableV2Component1] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component2.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component2.ets new file mode 100644 index 0000000000000000000000000000000000000000..88b5014ed3961b7b55249243d8488aa880bdb68a --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component2.ets @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//[Start ReusableV2Component2] +import { info, Info } from '../view/Page5'; +@ReusableV2 +@ComponentV2 +export struct ReusableV2Component2 { + @Local info: Info = info; // 仅做演示使用,并不建议@Local赋值全局变量 + @Monitor('info.age') + onValChange() { + } + aboutToRecycle() { + this.info.age++; + } + aboutToReuse() { + this.info.age++; + } + onRender(): string { + return this.info.age.toString(); + } + build() { + Column() { + Text(this.onRender()) + } + } +} +//[Start ReusableV2Component2] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component3.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component3.ets new file mode 100644 index 0000000000000000000000000000000000000000..022458c4db8f56c1ee74ec8c020d56d74d218ee7 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component3.ets @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//[Start ReusableV2Component3] +import { Info1 } from '../view/Page6'; +@ReusableV2 +@ComponentV2 +export struct ReusableV2Component3 { + @Local val: number = 0; + @Local info: Info1 = new Info1(25); + @Param paramLocal: number = 1; + @Require @Param paramOut: number; + @Require @Param @Once paramOnce: number; + @Event changeParam: () => void; + @Provider('selfProvider') selfProvider: number = 0; + @Consumer('inherit') inheritConsumer: number = 0; + @Consumer('selfConsumer') selfConsumer: number = 0; + noDecoVariable: number = 0; // 未加装饰器,被视作常量 + noDecoInfo: Info1 = new Info1(30); // 未加装饰器,被视作常量 + readonly readOnlyVariable: number = 0; // readonly常量 + @Computed + get plusParam() { + return this.paramLocal + this.paramOut + this.paramOnce; + } + @Monitor('val') + onValChange(monitor: IMonitor) { + } + @Monitor('plusParam') + onPlusParamChange(monitor: IMonitor) { + } + build() { + Column() { + Column() { + Text($r('app.string.EntryAbility_title8')) + Text(`val: ${this.val}`).onClick(()=>{this.val++;}) + Text(`info.age: ${this.info.age}`).onClick(()=>{this.info.age++;}) + Text(`paramLocal: ${this.paramLocal}`).onClick(()=>{/* 无外部传入的Local无法本地修改 */}) + Text(`selfProvider: ${this.selfProvider}`).onClick(()=>{this.selfProvider++;}) + Text(`selfConsumer: ${this.selfConsumer}`).onClick(()=>{this.selfConsumer++;}) + }.borderWidth(2) + Column() { + Text($r('app.string.EntryAbility_title9')) + Text(`paramOut: ${this.paramOut}`).onClick(()=>{this.changeParam();}) + Text(`paramOnce: ${this.paramOnce}`).onClick(()=>{this.paramOnce++;}) + }.borderWidth(2) + Column() { + Text($r('app.string.EntryAbility_title10')) + Text(`inheritConsumer: ${this.inheritConsumer}`).onClick(()=>{this.inheritConsumer++;}) + Text(`plusParam: ${this.plusParam}`) + }.borderWidth(2) + Column() { + Text($r('app.string.EntryAbility_title11')) + Text(`noDecoVariable: ${this.noDecoVariable}`) + Text(`noDecoInfo.age: ${this.noDecoInfo.age}`).onClick(()=>{this.noDecoInfo.age++;}) // 能够触发刷新但是复用时不会被重置 + Text(`readOnlyVariable: ${this.readOnlyVariable}`) + }.borderWidth(2) + } + } +} +//[End ReusableV2Component3] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component4.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component4.ets new file mode 100644 index 0000000000000000000000000000000000000000..e0edf68ff5f953b7a9afa8d25b81c23e93c6f6da --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component4.ets @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//[Start ReusableV2Component4] +import { Info2 } from '../view/Page7'; +@ReusableV2 +@ComponentV2 +export struct ReusableV2Component4 { + noDecoInfo: Info2 = new Info2(30); // 未加装饰器,被视作常量 + @Monitor('noDecoInfo.age') + onAgeChange(monitor: IMonitor) { + } + aboutToRecycle() { + this.noDecoInfo.age = 25; + } + aboutToReuse() { + this.noDecoInfo.age = 35; + } + build() { + Column() { + Column() { + Text(`noDecoInfo.age: ${this.noDecoInfo.age}`) + .onClick(()=>{this.noDecoInfo.age++;}) // 能够触发刷新但是不会被重置 + } + } + } +} +//[End ReusableV2Component4] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component5.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component5.ets new file mode 100644 index 0000000000000000000000000000000000000000..6d72d9de6bb4aa076e04bfe0d8e09d020ac81a2a --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component5.ets @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//[Start ReusableV2Component5] +@ReusableV2 +@ComponentV2 +export struct ReusableV2Component5 { + @Local message: string = 'Hello World'; + aboutToRecycle() { + } + aboutToReuse() { + } + build() { + Column() { + Text(this.message) + } + } +} +//[End ReusableV2Component5] diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component6.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component6.ets new file mode 100644 index 0000000000000000000000000000000000000000..b8978f486ae02f95520286835f2cbe769e9b6751 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component6.ets @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@ReusableV2 +@ComponentV2 +export struct ReusableV2Component6 { + @Require @Param num: number; + aboutToAppear() { + } + aboutToRecycle() { + } + aboutToReuse() { + } + build() { + Column() { + Text(`${this.num}`).fontSize(50) + } + } +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component7.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component7.ets new file mode 100644 index 0000000000000000000000000000000000000000..55105a0aea3daa4d7890dbbff43ea1fccb4e743e --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component7.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//[Start ReusableV2Component7] +@ReusableV2 +@ComponentV2 +export struct ReusableV2Component7 { + @Require @Param num: number; + aboutToAppear() { + } + aboutToRecycle() { + } + aboutToReuse() { + } + build() { + Column() { + Text(`${this.num}`) + } + } +} +//[End ReusableV2Component7] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component8.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component8.ets new file mode 100644 index 0000000000000000000000000000000000000000..7ad0c420344a52eb31e5369d9bdfff23e5c1bb6c --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component8.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//[Start ReusableV2Component8] +@ReusableV2 +@ComponentV2 +export struct ReusableV2Component8 { + @Require @Param num: number; + aboutToAppear() { + } + aboutToRecycle() { + } + aboutToReuse() { + } + build() { + Column() { + Text(`${this.num}`) + } + } +} +//[End ReusableV2Component8] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component9.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component9.ets new file mode 100644 index 0000000000000000000000000000000000000000..01ae2d3ff94720f49d74b2fa55dc3962c6622fb2 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/common/ReusableV2Component9.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//[Start ReusableV2Component9] +@ReusableV2 +@ComponentV2 +export struct ReusableV2Component9 { + @Require @Param num: number; + aboutToAppear() { + } + aboutToRecycle() { + } + aboutToReuse() { + } + build() { + Column() { + Text(`child: ${this.num}`) + } + } +} +//[End ReusableV2Component9] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/entryability/EntryAbility.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..b00c7951038a8d8352cb1f20522945281a923f67 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,61 @@ +/* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + try { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + } catch (err) { + hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err)); + } + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..5e01109340ebf3a222e2dcfc7145d93c15eccdb5 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,29 @@ +/* Copyright (c) 2025 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/pages/Index.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..db87e0ad869a60e0c8cd6256085ad11b1a6c5016 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//[Start Interface_Description] +import { router } from '@kit.ArkUI'; + +@Entry +@ComponentV2 +struct Index { + + build() { + Column() { + Button('page1').onClick((event: ClickEvent) => { + router.pushUrl({url:'view/Page1'}) + }) + Button('page2').onClick((event: ClickEvent) => { + router.pushUrl({url:'view/Page2'}) + }) + Button('page3').onClick((event: ClickEvent) => { + router.pushUrl({url:'view/Page3'}) + }) + Button('page4').onClick((event: ClickEvent) => { + router.pushUrl({url:'view/Page4'}) + }) + Button('page5').onClick((event: ClickEvent) => { + router.pushUrl({url:'view/Page5'}) + }) + Button('page6').onClick((event: ClickEvent) => { + router.pushUrl({url:'view/Page6'}) + }) + Button('page7').onClick((event: ClickEvent) => { + router.pushUrl({url:'view/Page7'}) + }) + Button('page8').onClick((event: ClickEvent) => { + router.pushUrl({url:'view/Page8'}) + }) + Button('page9').onClick((event: ClickEvent) => { + router.pushUrl({url:'view/Page9'}) + }) + Button('page10').onClick((event: ClickEvent) => { + router.pushUrl({url:'view/Page10'}) + }) + Button('page11').onClick((event: ClickEvent) => { + router.pushUrl({url:'view/Page11'}) + }) + Button('page12').onClick((event: ClickEvent) => { + router.pushUrl({url:'view/Page11'}) + }) + Button('page13').onClick((event: ClickEvent) => { + router.pushUrl({url:'view/Page13'}) + }) + } + } +} +//[End Interface_Description] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page1.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page1.ets new file mode 100644 index 0000000000000000000000000000000000000000..f8f251de57142d76495d0bfe4acba063e6892013 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page1.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ReusableV2Component } from '../common/ReusableV2Component1' +//[Start Interface Description] +@Entry +@ComponentV2 +struct Page1 { + + build() { + Column() { + ReusableV2Component() + .reuse({reuseId: () => 'reuseComponent'}) // 使用'reuseComponent'作为reuseId + ReusableV2Component() + .reuse({reuseId: () => ''}) // 使用空字符串将默认使用组件名'ReusableV2Component'作为reuseId + ReusableV2Component() // 未指定reuseId将默认使用组件名'ReusableV2Component'作为reuseId + } + } +} +//[End Interface Description] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page10.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page10.ets new file mode 100644 index 0000000000000000000000000000000000000000..3603dda1cfc3a384964e2eee73712ed44bde6924 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page10.ets @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// [Start Use_in_Repeat_component] +import { ReusableV2Component7 } from '../common/ReusableV2Component7'; +@Entry +@ComponentV2 +struct Page10 { + @Local simpleList: number[] = [1, 2, 3, 4, 5]; + @Local condition: boolean = true; + build() { + Column() { + // $r('app.string.EntryAbility_title1')需要替换为开发者所需的字符串(图像、数字等)资源文件 + Button($r('app.string.EntryAbility_title1')).onClick(()=>{this.condition=!this.condition;}) + Button($r('app.string.EntryAbility_title2')).onClick(()=>{this.simpleList.push(this.simpleList.length+1);}) + Button($r('app.string.EntryAbility_title3')).onClick(()=>{this.simpleList.pop();}) + Button($r('app.string.EntryAbility_title4')).onClick(()=>{this.simpleList[0]++;}) + if (this.condition) { + List({ space: 10 }) { + Repeat(this.simpleList) + .each((obj: RepeatItem) => { + ListItem() { + Column() { + ReusableV2Component7({ num: obj.item }) + } + } + }) + } + } + } + } +} +// [End Use_in_Repeat_component] diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page11.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page11.ets new file mode 100644 index 0000000000000000000000000000000000000000..84a5f61fe66f97ed83f03b2bdda76425cbe3668f --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page11.ets @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// [Start Rep_each_list_Comp] +import { ReusableV2Component8 } from '../common/ReusableV2Component8'; +@Entry +@ComponentV2 +struct Page11 { + @Local simpleList: number[] = [1, 2, 3, 4, 5]; + @Local condition: boolean = true; + + build() { + Column() { + // $r('app.string.EntryAbility_title1')需要替换为开发者所需的字符串(图像、数字等)资源文件 + Button($r('app.string.EntryAbility_title1')).onClick(()=>{this.condition=!this.condition;}) + Button($r('app.string.EntryAbility_title2')).onClick(()=>{this.simpleList.push(this.simpleList.length+1);}) + Button($r('app.string.EntryAbility_title3')).onClick(()=>{this.simpleList.pop();}) + Button($r('app.string.EntryAbility_title4')).onClick(()=>{this.simpleList[0]++;}) + if (this.condition) { + List({ space: 10 }) { + Repeat(this.simpleList) + .each((obj: RepeatItem) => { + ListItem() { + Column() { + ReusableV2Component8({ num: obj.item }) + } + } + }) + } + } + } + } +} +// [End Rep_each_list_Comp] diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page12.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page12.ets new file mode 100644 index 0000000000000000000000000000000000000000..ea2c6398e563c6bde83d32d6061c2e96c7006e1d --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page12.ets @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// [Start Use_in_ForEach_component] +import { ReusableV2Component9 } from '../common/ReusableV2Component9'; +@Entry +@ComponentV2 +struct Page12 { + @Local simpleList: number[] = [0, 1, 2, 3, 4, 5]; + + build() { + Column() { + ForEach(this.simpleList, (num: number, index) => { + Row() { + Button($r('app.string.EntryAbility_title13')).onClick(()=>{this.simpleList[index]++;}) + ReusableV2Component9({ num: num }) + } + }) // 每次修改完key发生变化 + } + } +} +// [End Use_in_ForEach_component] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page13.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page13.ets new file mode 100644 index 0000000000000000000000000000000000000000..8f8dec730b7889333ec917219c15390b47df1217 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page13.ets @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// [Start Using_LazyForEach_component] +class BasicDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + private originDataArray: StringData[] = []; + + public totalCount(): number { + return 0; + } + + public getData(index: number): StringData { + return this.originDataArray[index]; + } + + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + console.info('add listener'); + this.listeners.push(listener); + } + } + + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + console.info('remove listener'); + this.listeners.splice(pos, 1); + } + } + + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } + + notifyDatasetChange(operations: DataOperation[]): void { + this.listeners.forEach(listener => { + listener.onDatasetChange(operations); + }) + } +} + +class MyDataSource extends BasicDataSource { + private dataArray: StringData[] = []; + + public totalCount(): number { + return this.dataArray.length; + } + + public getData(index: number): StringData { + return this.dataArray[index]; + } + + public addData(index: number, data: StringData): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + public pushData(data: StringData): void { + this.dataArray.push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } +} + +@ObservedV2 +class StringData { + @Trace public message: string; + constructor(message: string) { + this.message = message; + } +} + +@Entry +@ComponentV2 +struct Index { + data: MyDataSource = new MyDataSource(); // 数据源 + + aboutToAppear() { + for (let i = 0; i <= 200; i++) { + this.data.pushData(new StringData('Hello' + i)); + } + } + build() { + List({ space: 3 }) { + LazyForEach(this.data, (item: StringData, index: number) => { + ListItem() { + Column() { + Text(item.message) + ChildComponent({ data: item.message }) + .onClick(() => { + item.message += '!'; // message为@Trace装饰的变量,可观察变化 + }) + } + } + }) + }.cachedCount(5) + } +} + +@ReusableV2 +@ComponentV2 +struct ChildComponent { + @Param @Require data: string; + aboutToAppear(): void { + } + aboutToDisappear(): void { + } + aboutToReuse(): void { + + } + aboutToRecycle(): void { + + } + build() { + Row() { + Text(this.data).fontSize(50) + } + } +} +// [End Using_LazyForEach_component] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page2.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page2.ets new file mode 100644 index 0000000000000000000000000000000000000000..24f50f5370ac7d03776fb697b3c217e908ea4c97 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page2.ets @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//[Start Usage restrictions] +@Entry +@ComponentV2 +struct Page13 { + build() { + Column() { + ReusableV2Component() // 正确用法 + V1Component() + } + } +} +@ReusableV2 +@ComponentV2 +struct ReusableV2Component { + build() { + } +} +@Builder +function v2ReusableBuilder() { + ReusableV2Component() +} +@Component +struct V1Component { + build() { + Column() { + ReusableV2Component() // 错误用法,编译报错 + V2ReusableBuilder() // 错误用法,较复杂场景,运行时报错 + } + } +} +//[End Usage restrictions] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page3.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page3.ets new file mode 100644 index 0000000000000000000000000000000000000000..c2ea0ca1ddd8d5efb3532284fa4c3e0593ff7de2 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page3.ets @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//[Start The_lifecycle_of_recycling_and_reuse] +@Entry +@ComponentV2 +struct Page3 { + @Local arr: number[] = [1, 2, 3, 4, 5]; + build() { + Column(){ + List(){ + Repeat(this.arr) + .each(() => {}) + .virtualScroll() + .templateId(() => 'a') + .template('a', (ri) => { + ListItem() { + Column() { + ReusableV2Component1({ val: ri.item}) // 暂不支持,编译期报错 + ReusableV2Builder(ri.item) // 暂不支持,运行时报错 + NormalV2Component({ val: ri.item}) // 支持普通V2自定义组件下面包含V2复用组件 + } + } + }) + } + } + } +} + +@ComponentV2 +struct NormalV2Component { + @Require @Param val: number; + build() { + ReusableV2Component1({ val: this.val }) + } +} + +// @ReusableV2 +@ComponentV2 +struct ReusableV2Component1 { + @Require @Param val: number; + build() { + Column() { + Text(`val: ${this.val}`) + } + } +} + + +@Builder +function reusableV2Builder(param: number) { + ReusableV2Component1({ val: param }) +} +//[End The_lifecycle_of_recycling_and_reuse] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page4.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page4.ets new file mode 100644 index 0000000000000000000000000000000000000000..decd438d1c391ecf8a475ae8d14e147b9418a47b --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page4.ets @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//[Start Freezing_during_the_reuse_phase] +import { NormalV2Component } from '../common/NormalV2Component'; +@Entry +@ComponentV2 +struct Page4 { + @Local condition1: boolean = false; + @Local condition2: boolean = true; + build() { + Column(){ + Button('step1. appear') + .onClick(() => { + this.condition1 = true; + }) + Button('step2. recycle') + .onClick(() => { + this.condition2 = false; + }) + Button('step3. reuse') + .onClick(() => { + this.condition2 = true; + }) + Button('step4. disappear') + .onClick(() => { + this.condition1 = false; + }) + if (this.condition1) { + NormalV2Component({ condition: this.condition2 }) + } + } + } +} +//[End Freezing_during_the_reuse_phase] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page5.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page5.ets new file mode 100644 index 0000000000000000000000000000000000000000..977c75f355479c98eb591e67452107b03e77c398 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page5.ets @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//[Start Reset_the_internal_state_variables_of_the_component_before_reuse] +import { ReusableV2Component2 } from '../common/ReusableV2Component2'; +@ObservedV2 +export class Info { + @Trace public age: number = 25; +} +export const info: Info = new Info(); + +@Entry +@ComponentV2 +struct Page5 { + @Local condition: boolean = true; + + build() { + Column() { + // $r('app.string.EntryAbility_title6')需要替换为开发者所需的字符串(图像、数字等)资源文件。 + Button($r('app.string.EntryAbility_title6')).onClick(()=>{this.condition=!this.condition;}) + Button($r('app.string.EntryAbility_title7')).onClick(()=>{info.age++;}) + if (this.condition) { + ReusableV2Component2() + } + } + } +} +//[End Reset_the_internal_state_variables_of_the_component_before_reuse] \ No newline at end of file diff --git a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/LoginRegisterPage.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page6.ets similarity index 32% rename from ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/LoginRegisterPage.ets rename to ArkUIKit/ReusableV2/entry/src/main/ets/view/Page6.ets index 3998f3dcea363e128b1ac349478d1b75c0ce33df..e97115013d89af88cba0e01816772721a4dee492 100644 --- a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/LoginRegisterPage.ets +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page6.ets @@ -12,43 +12,41 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +//[Start Reset_the_internal_state_variables_of_the_component_before_reuse1] +import { ReusableV2Component3 } from '../common/ReusableV2Component3'; +@ObservedV2 +export class Info1 { + @Trace public age: number; + constructor(age: number) { + this.age = age; + } +} -import { ComponentCard } from '../../common/Card'; -import resource from '../../common/resource'; - -// [Start the_example_of_text_input] @Entry -@Component -export struct LoginRegisterPage { +@ComponentV2 +struct Page6 { + @Local local: number = 0; + @Provider('inherit') inheritProvider: number = 100; + @Local condition: boolean = true; build() { - // [StartExclude the_example_of_text_input] - NavDestination() { - Column({ space: 12 }) { - ComponentCard({ title: $r('app.string.LoginRegisterPage_title') }) { - // [EndExclude the_example_of_text_input] - Column({ space: 12 }) { - TextInput({ placeholder: 'input your username' }) - .id('username') - .onSubmit((enterKeyType) => { - console.info(enterKeyType + resource.resourceToString($r('app.string.LoginRegisterPage_textContent'))); - }) - TextInput({ placeholder: 'input your password' }) - .id('password') - .type(InputType.Password) - .onSubmit((enterKeyType) => { - console.info(enterKeyType + resource.resourceToString($r('app.string.LoginRegisterPage_textContent'))); - }) - Button($r('app.string.LoginRegisterPage_Button_3')) - .width('100%') + Column() { + // $r('app.string.EntryAbility_title6')需要替换为开发者所需的字符串(图像、数字等)资源文件。 + Button($r('app.string.EntryAbility_title6')).onClick(()=>{this.condition=!this.condition;}) + Column() { + Text($r('app.string.EntryAbility_title12')) + Text(`local: ${this.local}`).onClick(()=>{this.local++;}) + Text(`inheritProvider: ${this.inheritProvider}`).onClick(()=>{this.inheritProvider++;}) + }.borderWidth(2) + if (this.condition) { + ReusableV2Component3({ + paramOut: this.local, + paramOnce: this.local, + changeParam: () => { + this.local++; } - } + }) } - .width('100%') - .height('100%') - .padding({ left: 12, right: 12 }) } - // [End the_example_of_text_input] - .backgroundColor('#f1f2f3') - .title($r('app.string.LoginRegisterPage_title')) } -} \ No newline at end of file +} +//[End Reset_the_internal_state_variables_of_the_component_before_reuse1] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page7.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page7.ets new file mode 100644 index 0000000000000000000000000000000000000000..a1701c6579e97960ae39192f4d18a492a7d113fa --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page7.ets @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//[Start Use_in_if_component] +import { ReusableV2Component4 } from '../common/ReusableV2Component4'; +@ObservedV2 +export class Info2 { + @Trace public age: number; + constructor(age: number) { + this.age = age; + } +} + +@Entry +@ComponentV2 +struct Page7 { + @Local condition: boolean = true; + + build() { + Column() { + // $r('app.string.EntryAbility_title6')需要替换为开发者所需的字符串(图像、数字等)资源文件。 + Button($r('app.string.EntryAbility_title6')).onClick(()=>{this.condition=!this.condition;}) + if (this.condition) { + ReusableV2Component4() + } + } + } +} +//[End Use_in_if_component] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page8.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page8.ets new file mode 100644 index 0000000000000000000000000000000000000000..8d3c25708bf8d3023f28a5c7488758ad26bf2bc6 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page8.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// [Start Use_in_Repeat_component] +import { ReusableV2Component5 } from '../common/ReusableV2Component5'; +@Entry +@ComponentV2 +struct Page8 { + @Local condition: boolean = true; + + build() { + Column() { + // $r('app.string.EntryAbility_title6')需要替换为开发者所需的字符串(图像、数字等)资源文件。 + Button($r('app.string.EntryAbility_title6')).onClick(()=>{this.condition=!this.condition;}) // 点击切换回收/复用状态 + if (this.condition) { + ReusableV2Component5() + } + } + } +} +// [End Use_in_Repeat_component] \ No newline at end of file diff --git a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/ProhibitSelectMenu/DisableMenuItems.ets b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page9.ets similarity index 34% rename from ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/ProhibitSelectMenu/DisableMenuItems.ets rename to ArkUIKit/ReusableV2/entry/src/main/ets/view/Page9.ets index 0a8773f3bb31d75a22f836c68e2f58e68e103d40..349c5e57b8302bf2092ae71a6e59a3a41795fd2c 100644 --- a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/ProhibitSelectMenu/DisableMenuItems.ets +++ b/ArkUIKit/ReusableV2/entry/src/main/ets/view/Page9.ets @@ -12,52 +12,45 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -// [Start DisableMenuItems] -import { TextMenuController } from '@kit.ArkUI'; - +// [Start Use_in_the_'each'_attribute_of_the_Repeat_component_in_non_lazy_loading_scenarios] +import { ReusableV2Component6 } from '../common/ReusableV2Component6'; @Entry -@Component -export struct DisableMenuItems { - aboutToAppear(): void { - // 禁用搜索和翻译 - TextMenuController.disableMenuItems([TextMenuItemId.SEARCH, TextMenuItemId.TRANSLATE]) - } +@ComponentV2 +struct Page9 { + @Local condition: boolean = true; + @Local simpleList: number[] = []; - aboutToDisappear(): void { - // 页面消失时恢复系统服务菜单项 - TextMenuController.disableMenuItems([]) + aboutToAppear(): void { + for (let i = 0; i < 100; i++) { + this.simpleList.push(i) + } } build() { - // [StartExclude DisableMenuItems] - NavDestination() { - // [EndExclude DisableMenuItems] - Row() { - Column() { - TextInput({ text: $r('app.string.ProhibitSelectMenu_content') }) - .height(60) - .fontStyle(FontStyle.Italic) - .fontWeight(FontWeight.Bold) - .textAlign(TextAlign.Center) - .caretStyle({ width: '4vp' }) - .editMenuOptions({ - onCreateMenu: (menuItems: Array) => { - // menuItems不包含搜索和翻译 - return menuItems; - }, - onMenuItemClick: (menuItem: TextMenuItem, textRange: TextRange) => { - return false - } - }) - }.width('100%') + Column() { + // $r('app.string.EntryAbility_title5')需要替换为开发者所需的字符串(图像、数字等)资源文件。 + Button($r('app.string.EntryAbility_title5')).onClick(() => { + this.condition = !this.condition; + }) + if (this.condition) { + // 此处仅做演示使用,让复用池中填充3个组件 + ReusableV2Component6({ num: 0 }) + ReusableV2Component6({ num: 0 }) + ReusableV2Component6({ num: 0 }) } - .height('100%') - // [StartExclude DisableMenuItems] + List({ space: 10 }) { + Repeat(this.simpleList) + .virtualScroll() + .each((obj: RepeatItem) => { + ListItem() { + Column() { + ReusableV2Component6({ num: obj.item }) + } + } + }) + }.height('50%') + .cachedCount(2) } - .backgroundColor('#f1f2f3') - .title($r('app.string.ProhibitSelectMenu_title_2')) - // [EndExclude DisableMenuItems] } } -// [End DisableMenuItems] \ No newline at end of file +// [End Use_in_the_'each'_attribute_of_the_Repeat_component_in_non_lazy_loading_scenarios] \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/module.json5 b/ArkUIKit/ReusableV2/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..cb355a9800296830aef540ce9a3f53769d502465 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/module.json5 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "default" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "ohos.want.action.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/resources/base/element/color.json b/ArkUIKit/ReusableV2/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/resources/base/element/float.json b/ArkUIKit/ReusableV2/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..a0a93dd91fd48f08f3a9532c76e9b26e68d4c034 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/resources/base/element/string.json b/ArkUIKit/ReusableV2/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..7eb7b3dbbbf572a9be86853a4f6a210dff14d092 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/resources/base/element/string.json @@ -0,0 +1,55 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + },{ + "name": "EntryAbility_title1", + "value": "删除/创建Repeatcon" + },{ + "name": "EntryAbility_title2", + "value": "增加元素" + },{ + "name": "EntryAbility_title3", + "value": "删除元素" + },{ + "name": "EntryAbility_title4", + "value": "更改元素" + },{ + "name": "EntryAbility_title5", + "value": "改变condition" + },{ + "name": "EntryAbility_title6", + "value": "回收/复用" + },{ + "name": "EntryAbility_title7", + "value": "改值" + },{ + "name": "EntryAbility_title8", + "value": "重置为本地初始值的变量" + },{ + "name": "EntryAbility_title9", + "value": "重置为外部传入的变量" + },{ + "name": "EntryAbility_title10", + "value": "根据父组件情况决定" + },{ + "name": "EntryAbility_title11", + "value": "不被重置" + },{ + "name": "EntryAbility_title12", + "value": "父组件变量" + },{ + "name": "EntryAbility_title13", + "value": "点击修改" + } + ] +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/resources/base/media/background.png b/ArkUIKit/ReusableV2/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/ArkUIKit/ReusableV2/entry/src/main/resources/base/media/background.png differ diff --git a/ArkUIKit/ReusableV2/entry/src/main/resources/base/media/foreground.png b/ArkUIKit/ReusableV2/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/ArkUIKit/ReusableV2/entry/src/main/resources/base/media/foreground.png differ diff --git a/ArkUIKit/ReusableV2/entry/src/main/resources/base/media/layered_image.json b/ArkUIKit/ReusableV2/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/resources/base/media/startIcon.png b/ArkUIKit/ReusableV2/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/ArkUIKit/ReusableV2/entry/src/main/resources/base/media/startIcon.png differ diff --git a/ArkUIKit/ReusableV2/entry/src/main/resources/base/profile/backup_config.json b/ArkUIKit/ReusableV2/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/resources/base/profile/main_pages.json b/ArkUIKit/ReusableV2/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..0702b23699bbfed6a3688c12da82c528bede2a2d --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,18 @@ +{ + "src": [ + "pages/Index", + "view/Page1", + "view/Page2", + "view/Page3", + "view/Page4", + "view/Page5", + "view/Page6", + "view/Page7", + "view/Page8", + "view/Page9", + "view/Page10", + "view/Page11", + "view/Page12", + "view/Page13" + ] +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/resources/dark/element/color.json b/ArkUIKit/ReusableV2/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/main/syscap.json b/ArkUIKit/ReusableV2/entry/src/main/syscap.json new file mode 100644 index 0000000000000000000000000000000000000000..19b9dd01ee502b28d0496336f3bc9c2ab9469d77 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/main/syscap.json @@ -0,0 +1,12 @@ +{ + "devices": { + "general": ["default"], + "custom": [ + { + "xts": [ + "SystemCapability.Graphic.Graphic2D.NativeDrawing" + ] + } + ] + } +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/mock/mock-config.json5 b/ArkUIKit/ReusableV2/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..323d1d611fecf4ecb751976e3a71500b3712a445 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/mock/mock-config.json5 @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/ohosTest/ets/test/Ability.test.ets b/ArkUIKit/ReusableV2/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..7f30942b81554a399e89aa253c7089eca4f8d8d1 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/ohosTest/ets/test/List.test.ets b/ArkUIKit/ReusableV2/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..d95118bb8d1512e3f9e7a82b9017194bb49faed8 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import abilityTest from './Ability.test'; +import IndexTest from './index.test'; + +export default function testsuite() { + abilityTest(); + IndexTest() +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/ohosTest/ets/test/index.test.ets b/ArkUIKit/ReusableV2/entry/src/ohosTest/ets/test/index.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..baaa89c5f11bb2451efa124d2e2244d95ccad443 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/ohosTest/ets/test/index.test.ets @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { describe, it, expect, beforeAll } from '@ohos/hypium'; +// 导入测试依赖kit +import { abilityDelegatorRegistry, Driver, ON, MouseButton,MatchPattern, UiDirection } from '@kit.TestKit'; +import { UIAbility, Want } from '@kit.AbilityKit'; +import { Point } from '@ohos.UiTest'; +const delegator: abilityDelegatorRegistry.AbilityDelegator = abilityDelegatorRegistry.getAbilityDelegator(); +const bundleName = abilityDelegatorRegistry.getArguments().bundleName; +let abilityDelegator: abilityDelegatorRegistry.AbilityDelegator = abilityDelegatorRegistry.getAbilityDelegator(); +let want: Want; + +async function getResourceString(resource: Resource): Promise { + let manage = abilityDelegator.getAppContext().resourceManager; + let textString: string = await manage.getStringValue(resource); + return textString; +} + +export default function IndexTest(){ + describe('IndexTest', () => { + + beforeAll(async () => { + want = { + bundleName: bundleName, + abilityName: 'EntryAbility' + }; + await delegator.startAbility(want); + await sleep(2000); + const ability: UIAbility = await delegator.getCurrentTopAbility(); + console.info("get top ability"); + expect(ability.context.abilityInfo.name).assertEqual('EntryAbility'); + }) + + /** + * @tc.number :Index_Start_0100 + * @tc.name :Index_Start_0100 + * @tc.desc :测试打开应用 + * @tc.level :level10 + * @tc.size : MediumTest + * @tc.type : Function + */ + + it("Index_Start_0100", 0, async (done: Function) => { + try { + const want: Want = { + bundleName: bundleName, + abilityName: 'com.example.reusablev2' + }; + + // 启动 IndexAbility + await delegator.startAbility(want); + await sleep(2000); + + const ability: UIAbility = await delegator.getCurrentTopAbility(); + expect(ability.context.abilityInfo.name).assertEqual('IndexAbility'); + + done(); + } catch (error) { + console.error("Index test failed:", error); + done(); + } + }); + + /** + * @tc.number :testS@ReusableV21_0101 + * @tc.name :testS@ReusableV21_0101 + * @tc.desc :测试打开接口说明页面 + * @tc.level :level1 + * @tc.size : MediumTest + * @tc.type : Function + */ + it('testS@testS@ReusableV21_0101', 0, async (done: Function) => { + let driver = Driver.create(); + let button_list = await driver.findComponent(ON.text('page1', MatchPattern.CONTAINS)); + + await button_list.click(); + await driver.delayMs(1000); + await driver.pressBack(); + done(); + }); + /** + * @tc.number :testS@ReusableV21_0102 + * @tc.name :testS@ReusableV21_0102 + * @tc.desc :测试打开使用限制页面 + * @tc.level :level1 + * @tc.size : MediumTest + * @tc.type : Function + */ + it('testS@ReusableV21_0102', 0, async (done: Function) => { + let driver = Driver.create(); + let button_list = await driver.findComponent(ON.text('page2', MatchPattern.CONTAINS)); + + await button_list.click(); + await driver.delayMs(1000); + await driver.pressBack(); + done(); + }); + + /** + * @tc.number :testS@ReusableV21_0103 + * @tc.name :testS@ReusableV21_0103 + * @tc.desc :测试打开回收与复用的生命周期页面 + * @tc.level :level1 + * @tc.size : MediumTest + * @tc.type : Function + */ + + it('testS@ReusableV21_0103', 0, async (done: Function) => { + let driver = Driver.create(); + let button_list = await driver.findComponent(ON.text('page3', MatchPattern.CONTAINS)); + + await button_list.click(); + await driver.delayMs(1000); + await driver.pressBack(); + done(); + }); + /** + * @tc.number :testS@ReusableV21_0104 + * @tc.name :testS@ReusableV21_0104 + * @tc.desc :测试打开复用阶段的冻结页面 + * @tc.level :level1 + * @tc.size : MediumTest + * @tc.type : Function + */ + it('testS@ReusableV21_0104', 0, async (done: Function) => { + let driver = Driver.create(); + let button_list = await driver.findComponent(ON.text('page4', MatchPattern.CONTAINS)); + + await button_list.click(); + await driver.delayMs(1000); + + // // 分别查找并断言每个子项的存在性 + let subItem = await driver.findComponent(ON.text('step1. appear', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + + let subItem2 = await driver.findComponent(ON.text('step2. recycle', MatchPattern.CONTAINS)); + expect(subItem2 === null).assertFalse(); + + let subItem3 = await driver.findComponent(ON.text('step3. reuse', MatchPattern.CONTAINS)); + expect(subItem3 === null).assertFalse(); + + let subItem4 = await driver.findComponent(ON.text('step4. disappear', MatchPattern.CONTAINS)); + expect(subItem3 === null).assertFalse(); + + // 点击每个子项 + await subItem.click(); + await driver.delayMs(1000); + + await subItem2.click(); + await driver.delayMs(1000); + + await subItem3.click(); + await driver.delayMs(1000); + + await subItem4.click(); + await driver.delayMs(1000); + + + await driver.pressBack(); + done(); + }); + /** + * @tc.number :testS@ReusableV21_0105 + * @tc.name :testS@ReusableV21_0105 + * @tc.desc :测试打开复用前的组件内状态变量重置页面 + * @tc.level :level1 + * @tc.size : MediumTest + * @tc.type : Function + */ + it('testS@ReusableV21_0105', 0, async (done: Function) => { + let driver = Driver.create(); + let button_list = await driver.findComponent(ON.text('page5', MatchPattern.CONTAINS)); + await button_list.click(); + await driver.delayMs(1000); + // // 分别查找并断言每个子项的存在性 + let subItem = await driver.findComponent(ON.text('复用/回收', MatchPattern.CONTAINS)); + + let subItem2 = await driver.findComponent(ON.text('改值', MatchPattern.CONTAINS)); + // 点击每个子项 + await subItem.click(); + await driver.delayMs(1000); + await subItem2.click(); + await driver.delayMs(1000); + await driver.pressBack(); + done(); + }); + /** + * @tc.number :testS@ReusableV21_0106 + * @tc.name :testS@ReusableV21_0106 + * @tc.desc :测试打开复用前的组件内状态变量重置优化页面 + * @tc.level :level1 + * @tc.size : MediumTest + * @tc.type : Function + */ + it('testS@ReusableV21_0106', 0, async (done: Function) => { + let driver = Driver.create(); + let button_list = await driver.findComponent(ON.text('page6', MatchPattern.CONTAINS)); + + await button_list.click(); + await driver.delayMs(1000); + // 分别查找并断言每个子项的存在性 + let subItem = await driver.findComponent(ON.text('回收/复用', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + // 点击每个子项 + await subItem.click(); + await driver.delayMs(1000); + await driver.pressBack(); + done(); + }); + /** + * @tc.number :testS@ReusableV21_0107 + * @tc.name :testS@ReusableV21_0107 + * @tc.desc :测试打开在if组件中使用页面 + * @tc.level :level1 + * @tc.size : MediumTest + * @tc.type : Function + */ + it('testS@ReusableV21_0107', 0, async (done: Function) => { + let driver = Driver.create(); + let button_list = await driver.findComponent(ON.text('page7', MatchPattern.CONTAINS)); + + await button_list.click(); + await driver.delayMs(1000); + // // 分别查找并断言每个子项的存在性 + let subItem = await driver.findComponent(ON.text('回收/复用', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + // 点击每个子项 + await subItem.click(); + await driver.delayMs(1000); + await driver.pressBack(); + done(); + }); + /** + * @tc.number :testS@ReusableV21_0108 + * @tc.name :testS@ReusableV21_0108 + * @tc.desc :测试打开在Repeat组件中使用页面 + * @tc.level :level1 + * @tc.size : MediumTest + * @tc.type : Function + */ + it('testS@ReusableV21_0108', 0, async (done: Function) => { + let driver = Driver.create(); + let button_list = await driver.findComponent(ON.text('page8', MatchPattern.CONTAINS)); + + await button_list.click(); + await driver.delayMs(1000); + // // 分别查找并断言每个子项的存在性 + let subItem = await driver.findComponent(ON.text('回收/复用', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + // 点击每个子项 + await subItem.click(); + await driver.delayMs(1000); + await driver.pressBack(); + done(); + }); + /** + * @tc.number :testS@ReusableV21_0109 + * @tc.name :testS@ReusableV21_0109 + * @tc.desc :测试打开在Repeat组件非懒加载场景的each属性中使用页面 + * @tc.level :level1 + * @tc.size : MediumTest + * @tc.type : Function + */ + it('testS@ReusableV21_0109', 0, async (done: Function) => { + let driver = Driver.create(); + let button_list = await driver.findComponent(ON.text('page9', MatchPattern.CONTAINS)); + + await button_list.click(); + await driver.delayMs(1000); + // // 分别查找并断言每个子项的存在性 + let subItem = await driver.findComponent(ON.text('改变condition', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + // 点击每个子项 + await subItem.click(); + await driver.delayMs(1000); + await driver.pressBack(); + done(); + }); + /** + * @tc.number :testS@ReusableV21_0110 + * @tc.name :testS@ReusableV21_0110 + * @tc.desc :测试打开在ForEach组件中使用页面 + * @tc.level :level1 + * @tc.size : MediumTest + * @tc.type : Function + */ + it('testS@ReusableV21_0110', 0, async (done: Function) => { + let driver = Driver.create(); + let button_list = await driver.findComponent(ON.text('page10', MatchPattern.CONTAINS)); + + await button_list.click(); + await driver.delayMs(1000); + let subItem = await driver.findComponent(ON.text('删除/创建Repeat', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + + let subItem2 = await driver.findComponent(ON.text('增加元素', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + + let subItem3 = await driver.findComponent(ON.text('删除元素', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + + let subItem4 = await driver.findComponent(ON.text('更改元素', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + + // 点击每个子项 + await subItem.click(); + await driver.delayMs(1000); + + await subItem2.click(); + await driver.delayMs(1000); + + await subItem3.click(); + await driver.delayMs(1000); + + await subItem4.click(); + await driver.delayMs(1000); + + await driver.pressBack(); + done(); + }); + /** + * @tc.number :testS@ReusableV21_0111 + * @tc.name :testS@ReusableV21_0111 + * @tc.desc :测试打开在Repeat组件非懒加载场景的each属性中使用 + * @tc.level :level1 + * @tc.size : MediumTest + * @tc.type : Function + */ + it('testS@ReusableV21_0111', 0, async (done: Function) => { + let driver = Driver.create(); + let button_list = await driver.findComponent(ON.text('page11', MatchPattern.CONTAINS)); + + await button_list.click(); + await driver.delayMs(1000); + let subItem = await driver.findComponent(ON.text('删除/创建Repeat', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + + let subItem2 = await driver.findComponent(ON.text('增加元素', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + + let subItem3 = await driver.findComponent(ON.text('删除元素', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + + let subItem4 = await driver.findComponent(ON.text('更改元素', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + + // // 点击每个子项 + await subItem.click(); + await driver.delayMs(1000); + + await subItem2.click(); + await driver.delayMs(1000); + + await subItem3.click(); + await driver.delayMs(1000); + + await subItem4.click(); + await driver.delayMs(1000); + + await driver.pressBack(); + done(); + }); + /** + * @tc.number :testS@ReusableV21_0112 + * @tc.name :testS@ReusableV21_0112 + * @tc.desc :测试打开在ForEach组件中使用页面 + * @tc.level :level1 + * @tc.size : MediumTest + * @tc.type : Function + */ + it('testS@ReusableV21_0112', 0, async (done: Function) => { + let driver = Driver.create(); + let button_list = await driver.findComponent(ON.text('page12', MatchPattern.CONTAINS)); + + await button_list.click(); + await driver.delayMs(1000); + let subItem = await driver.findComponent(ON.text('删除/创建Repeat', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + + let subItem2 = await driver.findComponent(ON.text('增加元素', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + + let subItem3 = await driver.findComponent(ON.text('删除元素', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + + let subItem4 = await driver.findComponent(ON.text('更改元素', MatchPattern.CONTAINS)); + expect(subItem === null).assertFalse(); + + // // 点击每个子项 + await subItem.click(); + await driver.delayMs(1000); + + await subItem2.click(); + await driver.delayMs(1000); + + await subItem3.click(); + await driver.delayMs(1000); + + await subItem4.click(); + await driver.delayMs(1000); + + await driver.pressBack(); + done(); + }); + /** + * @tc.number :testS@ReusableV21_0113 + * @tc.name :testS@ReusableV21_0113 + * @tc.desc :测试打开测试打开在LazyForEach组件中使用页面 + * @tc.level :level1 + * @tc.size : MediumTest + * @tc.type : Function + */ + it('testS@ReusableV21_0113', 0, async (done: Function) => { + let driver = Driver.create(); + let button_list = await driver.findComponent(ON.text('page13', MatchPattern.CONTAINS)); + + await button_list.click(); + await driver.delayMs(1000); + await driver.pressBack(); + done(); + }); + }) +} + + + +function sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); +} diff --git a/ArkUIKit/ReusableV2/entry/src/ohosTest/module.json5 b/ArkUIKit/ReusableV2/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..59667117c86b64ab9863f7b382c435ae4a3c32fa --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/ohosTest/module.json5 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "default" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/ArkUIKit/ReusableV2/entry/src/ohosTest/syscap.json b/ArkUIKit/ReusableV2/entry/src/ohosTest/syscap.json new file mode 100644 index 0000000000000000000000000000000000000000..19b9dd01ee502b28d0496336f3bc9c2ab9469d77 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/ohosTest/syscap.json @@ -0,0 +1,12 @@ +{ + "devices": { + "general": ["default"], + "custom": [ + { + "xts": [ + "SystemCapability.Graphic.Graphic2D.NativeDrawing" + ] + } + ] + } +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/test/List.test.ets b/ArkUIKit/ReusableV2/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..a60c87c5cbb0badf7c3fd8975034590e6fafa992 --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/test/List.test.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/entry/src/test/LocalUnit.test.ets b/ArkUIKit/ReusableV2/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..841bfd77e56060e50ec0924302a5ae624e76e3aa --- /dev/null +++ b/ArkUIKit/ReusableV2/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/hvigor/hvigor-config.json5 b/ArkUIKit/ReusableV2/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3b057578a1bb4d591ee53054e39ab0154fc2e43a --- /dev/null +++ b/ArkUIKit/ReusableV2/hvigor/hvigor-config.json5 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "modelVersion": "6.0.0", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | "ultrafine" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + // "optimizationStrategy": "memory" /* Define the optimization strategy. Value: [ "memory" | "performance" ]. Default: "memory" */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/ArkUIKit/ReusableV2/hvigorfile.ts b/ArkUIKit/ReusableV2/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..ae9086af35844176c08f1be3772d081d95d267c6 --- /dev/null +++ b/ArkUIKit/ReusableV2/hvigorfile.ts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/ArkUIKit/ReusableV2/oh-package.json5 b/ArkUIKit/ReusableV2/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..837c0ff9f35a6bb9eea849fead7955c19bcdec8d --- /dev/null +++ b/ArkUIKit/ReusableV2/oh-package.json5 @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "modelVersion": "6.0.0", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.24", + "@ohos/hamock": "1.0.0" + } +} diff --git a/ArkUIKit/ReusableV2/ohoTest.md b/ArkUIKit/ReusableV2/ohoTest.md new file mode 100644 index 0000000000000000000000000000000000000000..5f59cb333d94328a1329b60800e202ef9e1fb246 --- /dev/null +++ b/ArkUIKit/ReusableV2/ohoTest.md @@ -0,0 +1,19 @@ +# FormHost 测试用例归档 +## 用例表 + + +| 测试功能 | 预置条件 | 输入 | 预期输出 |是否自动 | 测试结果 +|--------------|----------|------|-----|------|------ +| 拉起应用 | 设备正常运行 | | 成功拉起应用 | 是 | Pass | +| 打开打开接口说明页面 | 设备正常运行 | | 成功打开 | 是 | Pass | +| 打开使用限制页面 | 设备正常运行 | | 成功打开 | 是 | Pass | +| 打开回收与复用的生命周期页面 | 设备正常运行 | | 成功打开 | 是 | Pass | +| 打开打开复用阶段的冻结页面 | 设备正常运行 | | 成功打开 | 是 | Pass | +| 打开复用前的组件内状态变量重置页面 | 设备正常运行 | | 成功打开 | 是 | Pass | +| 打开复用前的组件内状态变量重置优化页面 | 设备正常运行 | | 成功拉起应用 | 是 | Pass | +| 打开在if组件中使用页面 | 设备正常运行 | | 成功拉起应用 | 是 | Pass | +| 打开在Repeat组件中使用页面| 设备正常运行 | | 成功拉起应用 | 是 | Pass | +| 打开在在Repeat组件非懒加载场景的each属性中使用| 设备正常运行 | | 成功拉起应用 | 是 | Pass | +| 打开在ForEach组件中使用页面 | 设备正常运行 | 成功拉起应用 | 是 | Pass | +| 在LazyForEach组件中使用 | 设备正常运行 | 成功拉起应用 | 是 | Pass | + diff --git a/ArkUIKit/ReusableV2/screenshots/device/imag3.jpeg b/ArkUIKit/ReusableV2/screenshots/device/imag3.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..72a507acf09042fa80e0840a593c1f20c18599e0 Binary files /dev/null and b/ArkUIKit/ReusableV2/screenshots/device/imag3.jpeg differ diff --git a/ArkUIKit/ReusableV2/screenshots/device/image.jpeg b/ArkUIKit/ReusableV2/screenshots/device/image.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..205aec59ad659f7d990e476f0964df10f049f030 Binary files /dev/null and b/ArkUIKit/ReusableV2/screenshots/device/image.jpeg differ diff --git a/ArkUIKit/ReusableV2/screenshots/device/image1.jpeg b/ArkUIKit/ReusableV2/screenshots/device/image1.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..8573270e27a7dc8b34934cbd003d67d1fc2e4ec4 Binary files /dev/null and b/ArkUIKit/ReusableV2/screenshots/device/image1.jpeg differ diff --git a/ArkUIKit/ReusableV2/screenshots/device/image2.jpeg b/ArkUIKit/ReusableV2/screenshots/device/image2.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..47891bd6b065e409c233ab1ac2e2de63219d9dd5 Binary files /dev/null and b/ArkUIKit/ReusableV2/screenshots/device/image2.jpeg differ diff --git a/ArkUIKit/ReusableV2/screenshots/device/image4.jpeg b/ArkUIKit/ReusableV2/screenshots/device/image4.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..883d28ce3702984dab89427c5ea82d418eb7fb1f Binary files /dev/null and b/ArkUIKit/ReusableV2/screenshots/device/image4.jpeg differ diff --git a/ArkUIKit/StateMigrationProject/entry/src/main/ets/pages/componentstatemigration/StateComplexV1.ets b/ArkUIKit/StateMigrationProject/entry/src/main/ets/pages/componentstatemigration/StateComplexV1.ets index d06bceee2b504c59da34ce001806a18a74b83e17..9e528dbf97d8cd9dce4740b27f85fa680cbf9529 100644 --- a/ArkUIKit/StateMigrationProject/entry/src/main/ets/pages/componentstatemigration/StateComplexV1.ets +++ b/ArkUIKit/StateMigrationProject/entry/src/main/ets/pages/componentstatemigration/StateComplexV1.ets @@ -19,7 +19,7 @@ class Child3 { @Component @Entry -struct example1 { +struct Example1 { @State child: Child3 = new Child3(); build() { diff --git a/ArkUIKit/StateMigrationProject/entry/src/main/ets/pages/componentstatemigration/StateComplexV2.ets b/ArkUIKit/StateMigrationProject/entry/src/main/ets/pages/componentstatemigration/StateComplexV2.ets index 96827be670c4faf4a3609302d8ab5c8874650ecb..2db3ca995dbb8e390313e59888a5b0d0ab68328e 100644 --- a/ArkUIKit/StateMigrationProject/entry/src/main/ets/pages/componentstatemigration/StateComplexV2.ets +++ b/ArkUIKit/StateMigrationProject/entry/src/main/ets/pages/componentstatemigration/StateComplexV2.ets @@ -20,7 +20,7 @@ class Child4 { @ComponentV2 @Entry -struct example2 { +struct Example2 { @Local child: Child4 = new Child4(); build() { diff --git a/ArkUIKit/TextComponent/README_zh.md b/ArkUIKit/TextComponent/README_zh.md index 235bbb74258986d97d416b9f8a7a1b6d34170729..ab15c9cac147f5fbd448da360d086a64195f6548 100644 --- a/ArkUIKit/TextComponent/README_zh.md +++ b/ArkUIKit/TextComponent/README_zh.md @@ -2,7 +2,7 @@ ### 介绍 -中各场景的开发示例,展示在工程中,帮助开发者更好地理解ArkUI提供的组件及组件属性并合理使用。该工程中展示的代码详细描述可查如下链接: +在工程中包含各场景的开发示例,可帮助开发者更好地理解ArkUI提供的组件及组件属性并合理使用。该工程中展示的代码详细描述可查如下链接: 本示例通过使用[ArkUI指南文档](https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/ui/arkts-common-components-text-display.md)中各场景的开发示例,展示在工程中,帮助开发者更好地理解ArkUI提供的组件及组件属性并合理使用。该工程中展示的代码详细描述可查如下链接: 1. [文本显示 (Text/Span)](https://gitCode.com/openharmony/docs/blob/master/zh-cn/application-dev/ui/arkts-common-components-text-display.md)。 @@ -16,9 +16,9 @@ ### 效果预览 -| 首页 | 文本显示组件目录 | 创建文本示例 | -|-------------------------------------|-------------------------------------|-------------------------------------| -| ![](screenshots/device/image1.jpeg) | ![](screenshots/device/image2.jpeg) | ![](screenshots/device/image3.jpeg) | +| 首页 | 文本显示组件目录 | 创建文本示例 | +|------------------------------------|-------------------------------------|-------------------------------------| +| ![](screenshots/device/image1.png) | ![](screenshots/device/image2.jpeg) | ![](screenshots/device/image3.jpeg) | ### 具体实现 diff --git a/ArkUIKit/TextComponent/entry/src/main/ets/entryability/EntryAbility.ets b/ArkUIKit/TextComponent/entry/src/main/ets/entryability/EntryAbility.ets index 700540fa446cdc55f77f1b9d8540de49986b17df..250fdf3ee733805ca5ab544cd71d1ce4b3ae8895 100644 --- a/ArkUIKit/TextComponent/entry/src/main/ets/entryability/EntryAbility.ets +++ b/ArkUIKit/TextComponent/entry/src/main/ets/entryability/EntryAbility.ets @@ -45,15 +45,15 @@ export default class EntryAbility extends UIAbility { hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); }); } - // [Start cursor_avoid_part2] + // [End cursor_avoid_part2] onWindowStageDestroy(): void { - // Main window is destroyed, release UI related resources - hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); } onForeground(): void { - // Ability has brought to foreground - hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); } onBackground(): void { diff --git a/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolAddEvent.ets b/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolAddEvent.ets index 71ba4fee4887c860e88b26891eb510181c96afd9..c0bfc866a5ba83e207370f3e3361c372f0ca7e0a 100644 --- a/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolAddEvent.ets +++ b/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolAddEvent.ets @@ -28,7 +28,6 @@ export struct SymbolGlyphSpanAddEvent { ComponentCard({ title: $r('app.string.SymbolGlyphSpanAddEvent_title') }) { // [Start symbol_glyph_span_add_event] SymbolGlyph($r('sys.symbol.ohos_wifi')) - .id('symbolGlyph1') .fontSize(96) .fontColor([this.wifiColor]) .onClick(() => { diff --git a/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolAddToText.ets b/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolAddToText.ets index 0c7d401cdf69b425e584d92e7328157ab9e704fa..0c29a2f18863482f4c4e43b3bc34403b947c64e3 100644 --- a/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolAddToText.ets +++ b/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolAddToText.ets @@ -31,10 +31,8 @@ export struct SymbolGlyphSpanAddToText { .fontWeight(FontWeight.Normal) .fontSize(96) } - // [StartExclude creat_symbol_span] - .id('1') - // [EndExclude creat_symbol_span] // [End creat_symbol_span] + .id('1') } ComponentCard({ title: $r('app.string.SymbolGlyphSpanAddToText_title_2') }) { @@ -48,9 +46,6 @@ export struct SymbolGlyphSpanAddToText { .renderingStrategy(SymbolRenderingStrategy.SINGLE) .fontColor([Color.Black, Color.Green, Color.White]) } - // [StartExclude symbol_span_font_size] - .id('2') - // [EndExclude symbol_span_font_size] } Column() { @@ -61,9 +56,6 @@ export struct SymbolGlyphSpanAddToText { .renderingStrategy(SymbolRenderingStrategy.SINGLE) .fontColor([Color.Black, Color.Green, Color.White]) } - // [StartExclude symbol_span_font_size] - .id('3') - // [EndExclude symbol_span_font_size] } Column() { @@ -74,12 +66,8 @@ export struct SymbolGlyphSpanAddToText { .renderingStrategy(SymbolRenderingStrategy.SINGLE) .fontColor([Color.Black, Color.Green, Color.White]) } - // [StartExclude symbol_span_font_size] - .id('4') - // [EndExclude symbol_span_font_size] } } - // [End symbol_span_font_size] } @@ -93,9 +81,6 @@ export struct SymbolGlyphSpanAddToText { .fontWeight(FontWeight.Lighter) .fontSize(96) } - // [StartExclude symbol_span_font_weight] - .id('5') - // [EndExclude symbol_span_font_weight] } Column() { @@ -105,9 +90,6 @@ export struct SymbolGlyphSpanAddToText { .fontWeight(FontWeight.Normal) .fontSize(96) } - // [StartExclude symbol_span_font_weight] - .id('6') - // [EndExclude symbol_span_font_weight] } Column() { @@ -117,12 +99,8 @@ export struct SymbolGlyphSpanAddToText { .fontWeight(FontWeight.Bold) .fontSize(96) } - // [StartExclude symbol_span_font_weight] - .id('7') - // [EndExclude symbol_span_font_weight] } } - // [End symbol_span_font_weight] } @@ -136,9 +114,6 @@ export struct SymbolGlyphSpanAddToText { .fontSize(96) .fontColor([Color.Black]) } - // [StartExclude symbol_span_font_color] - .id('8') - // [EndExclude symbol_span_font_color] } Column() { @@ -148,9 +123,6 @@ export struct SymbolGlyphSpanAddToText { .fontSize(96) .fontColor([Color.Green]) } - // [StartExclude symbol_span_font_color] - .id('9') - // [EndExclude symbol_span_font_color] } Column() { @@ -160,12 +132,8 @@ export struct SymbolGlyphSpanAddToText { .fontSize(96) .fontColor([Color.Pink]) } - // [StartExclude symbol_span_font_color] - .id('10') - // [EndExclude symbol_span_font_color] } } - // [End symbol_span_font_color] } @@ -173,6 +141,7 @@ export struct SymbolGlyphSpanAddToText { // [Start symbol_span_rendering_strategy] Row() { Column() { + // 'app.string.SymbolAddToText_Text_1'资源文件中的value值为"单色" Text($r('app.string.SymbolAddToText_Text_1')); Text() { SymbolSpan($r('sys.symbol.ohos_folder_badge_plus')) @@ -180,12 +149,10 @@ export struct SymbolGlyphSpanAddToText { .renderingStrategy(SymbolRenderingStrategy.SINGLE) .fontColor([Color.Black, Color.Green, Color.White]) } - // [StartExclude symbol_span_rendering_strategy] - .id('11') - // [EndExclude symbol_span_rendering_strategy] } Column() { + // 'app.string.SymbolAddToText_Text_2'资源文件中的value值为"多色" Text($r('app.string.SymbolAddToText_Text_2')); Text() { SymbolSpan($r('sys.symbol.ohos_folder_badge_plus')) @@ -193,12 +160,10 @@ export struct SymbolGlyphSpanAddToText { .renderingStrategy(SymbolRenderingStrategy.MULTIPLE_COLOR) .fontColor([Color.Black, Color.Green, Color.White]) } - // [StartExclude symbol_span_rendering_strategy] - .id('12') - // [EndExclude symbol_span_rendering_strategy] } Column() { + // 'app.string.SymbolAddToText_Text_3'资源文件中的value值为"分层" Text($r('app.string.SymbolAddToText_Text_3')); Text() { SymbolSpan($r('sys.symbol.ohos_folder_badge_plus')) @@ -206,12 +171,8 @@ export struct SymbolGlyphSpanAddToText { .renderingStrategy(SymbolRenderingStrategy.MULTIPLE_OPACITY) .fontColor([Color.Black, Color.Green, Color.White]) } - // [StartExclude symbol_span_rendering_strategy] - .id('13') - // [EndExclude symbol_span_rendering_strategy] } } - // [End symbol_span_rendering_strategy] } @@ -219,42 +180,35 @@ export struct SymbolGlyphSpanAddToText { // [Start symbol_span_effect_strategy] Row() { Column() { + // 'app.string.SymbolAddToText_Text_4'资源文件中的value值为"无动效" Text($r('app.string.SymbolAddToText_Text_4')); Text() { SymbolSpan($r('sys.symbol.ohos_wifi')) .fontSize(96) .effectStrategy(SymbolEffectStrategy.NONE) } - // [StartExclude symbol_span_effect_strategy] - .id('14') - // [EndExclude symbol_span_effect_strategy] } Column() { + // 'app.string.SymbolAddToText_Text_5'资源文件中的value值为"整体缩放动效" Text($r('app.string.SymbolAddToText_Text_5')); Text() { SymbolSpan($r('sys.symbol.ohos_wifi')) .fontSize(96) .effectStrategy(SymbolEffectStrategy.SCALE) } - // [StartExclude symbol_span_effect_strategy] - .id('15') - // [EndExclude symbol_span_effect_strategy] } Column() { + // 'app.string.SymbolAddToText_Text_6'资源文件中的value值为"层级动效" Text($r('app.string.SymbolAddToText_Text_6')); Text() { SymbolSpan($r('sys.symbol.ohos_wifi')) .fontSize(96) .effectStrategy(SymbolEffectStrategy.HIERARCHICAL) } - // [StartExclude symbol_span_effect_strategy] - .id('16') - // [EndExclude symbol_span_effect_strategy] } } - // [End symbol_span_effect_strategy] } } diff --git a/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolCustomIconAnimation.ets b/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolCustomIconAnimation.ets index 7c599cfcf27d8fb9e799e04796eb3d393550d88b..6f205374b4b542bec3602e92016648317b62e000 100644 --- a/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolCustomIconAnimation.ets +++ b/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolCustomIconAnimation.ets @@ -39,13 +39,13 @@ export struct SymbolGlyphSpanCustomIconAnimation { ComponentCard({ title: $r('app.string.SymbolGlyphSpanCustomIconAnimation_title_1') }) { // [Start symbol_variable_color] Column() { + // 'app.string.SymbolCustomIconAnimation_Text_1'资源文件中的value值为"可变颜色动效" Text($r('app.string.SymbolCustomIconAnimation_Text_1')); SymbolGlyph($r('sys.symbol.ohos_wifi')) - // [StartExclude symbol_variable_color] - .id('1') - // [EndExclude symbol_variable_color] .fontSize(96) .symbolEffect(new HierarchicalSymbolEffect(EffectFillStyle.ITERATIVE), this.isActive) + // 'app.string.SymbolGlyphSpanCustomIconAnimation_Button_1'资源文件中的value值为"关闭" + // 'app.string.SymbolGlyphSpanCustomIconAnimation_Button_2'资源文件中的value值为"播放" Button(this.isActive ? $r('app.string.SymbolGlyphSpanCustomIconAnimation_Button_1') : $r('app.string.SymbolGlyphSpanCustomIconAnimation_Button_2')).onClick(() => { this.isActive = !this.isActive; }) @@ -55,11 +55,9 @@ export struct SymbolGlyphSpanCustomIconAnimation { ComponentCard({ title: $r('app.string.SymbolGlyphSpanCustomIconAnimation_title_2') }) { // [Start symbol_bouncing_effect] Column() { + // 'app.string.SymbolCustomIconAnimation_Text_2'资源文件中的value值为"弹跳动效" Text($r('app.string.SymbolCustomIconAnimation_Text_2')); SymbolGlyph($r('sys.symbol.ellipsis_message_1')) - // [StartExclude symbol_bouncing_effect] - .id('2') - // [EndExclude symbol_bouncing_effect] .fontSize(96) .fontColor([Color.Gray]) .symbolEffect(new BounceSymbolEffect(EffectScope.WHOLE, EffectDirection.UP), this.triggerValueReplace) @@ -72,11 +70,9 @@ export struct SymbolGlyphSpanCustomIconAnimation { ComponentCard({ title: $r('app.string.SymbolGlyphSpanCustomIconAnimation_title_3') }) { // [Start symbol_disable_effect] Column() { + // 'app.string.SymbolCustomIconAnimation_Text_3'资源文件中的value值为"禁用动效" Text($r('app.string.SymbolCustomIconAnimation_Text_3')); SymbolGlyph(this.replaceFlag ? $r('sys.symbol.eye_slash') : $r('sys.symbol.eye')) - // [StartExclude symbol_disable_effect] - .id('3') - // [EndExclude symbol_disable_effect] .fontSize(96) .renderingStrategy(this.renderMode) .symbolEffect(new ReplaceSymbolEffect(EffectScope.LAYER, ReplaceEffectType.SLASH_OVERLAY), @@ -91,11 +87,9 @@ export struct SymbolGlyphSpanCustomIconAnimation { ComponentCard({ title: $r('app.string.SymbolGlyphSpanCustomIconAnimation_title_4') }) { // [Start symbol_quick_replacement] Column() { + // 'app.string.SymbolCustomIconAnimation_Text_4'资源文件中的value值为"快速替换动效" Text($r('app.string.SymbolCustomIconAnimation_Text_4')); SymbolGlyph(this.replaceFlag ? $r('sys.symbol.checkmark_circle') : $r('sys.symbol.repeat_1')) - // [StartExclude symbol_quick_replacement] - .id('4') - // [EndExclude symbol_quick_replacement] .fontSize(96) .symbolEffect(new ReplaceSymbolEffect(EffectScope.WHOLE, ReplaceEffectType.CROSS_FADE), this.triggerValueReplace) diff --git a/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolSceneExample.ets b/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolSceneExample.ets index a390156deb9c806ef7852bccd4d414d16ff60fa5..783fca22d8d6a821a372d655754bf406e3a0aa8e 100644 --- a/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolSceneExample.ets +++ b/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolSceneExample.ets @@ -14,279 +14,236 @@ */ import { ComponentCard } from '../../common/Card'; -import resource from '../../common/resource'; // [Start symbol_glyph_span_scene_example] +// resourceGetString封装工具,从资源中获取字符串 +import resourceGetString from '../../common/resource'; + @Entry @Component -export struct SymbolGlyphSpanSceneExample { +struct SymbolMusicDemo { @State triggerValueReplace: number = 0; @State symbolSources: Resource[] = [$r('sys.symbol.repeat'), $r('sys.symbol.repeat_1'), $r('sys.symbol.arrow_left_arrow_right')]; @State symbolSourcesIndex: number = 0; - @State symbolText: string[] = [resource.resourceToString($r('app.string.SymbolSceneExample_Text_1')), - resource.resourceToString($r('app.string.SymbolSceneExample_Text_2')), - resource.resourceToString($r('app.string.SymbolSceneExample_Text_3'))]; + @State symbolText: string[] = [ + // 'app.string.SymbolShadowAndColor_Text_1'资源文件中的value值为"阴影能力" + resourceGetString.resourceToString($r('app.string.SymbolSceneExample_Text_1')), + // 'app.string.SymbolShadowAndColor_Text_1'资源文件中的value值为"阴影能力" + resourceGetString.resourceToString($r('app.string.SymbolSceneExample_Text_2')), + // 'app.string.SymbolShadowAndColor_Text_1'资源文件中的value值为"阴影能力" + resourceGetString.resourceToString($r('app.string.SymbolSceneExample_Text_3')), + ]; @State symbolTextIndex: number = 0; @State fontColorValue: ResourceColor = Color.Grey; @State fontColorValue1: ResourceColor = '#E8E8E8'; build() { - // [StartExclude symbol_glyph_span_scene_example] - NavDestination() { - Column({ space: 12 }) { - ComponentCard({ title: $r('app.string.SymbolGlyphSpanSceneExample_title') }) { - // [EndExclude symbol_glyph_span_scene_example] - Column({ space: 10 }) { - Row() { - Text() { - Span(resource.resourceToString($r('app.string.SymbolSceneExample_Text_4'))) - .fontSize(20) - .fontWeight(FontWeight.Bolder) - Span('(101)') - } - // [StartExclude symbol_glyph_span_scene_example] - .id('text1') - // [EndExclude symbol_glyph_span_scene_example] - } - - Row() { - Row({ space: 5 }) { - SymbolGlyph(this.symbolSources[this.symbolSourcesIndex]) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph1') - // [EndExclude symbol_glyph_span_scene_example] - .symbolEffect(new ReplaceSymbolEffect(EffectScope.WHOLE), this.triggerValueReplace) - .fontSize(20) - .fontColor([this.fontColorValue]) - Text(this.symbolText[this.symbolTextIndex]) - .fontColor(this.fontColorValue) - } - .onClick(() => { - this.symbolTextIndex++; - this.symbolSourcesIndex++; - this.triggerValueReplace++; - if (this.symbolSourcesIndex > (this.symbolSources.length - 1)) { - this.symbolSourcesIndex = 0; - this.triggerValueReplace = 0; - } - if (this.symbolTextIndex > (this.symbolText.length - 1)) { - this.symbolTextIndex = 0; - } - }) - .width('75%') - - Row({ space: 5 }) { - Text() { - SymbolSpan($r('sys.symbol.arrow_down_circle_badge_vip_circle_filled')) - .fontColor([this.fontColorValue]) - .fontSize(20) - } - // [StartExclude symbol_glyph_span_scene_example] - .id('text2') - // [EndExclude symbol_glyph_span_scene_example] - - Text() { - SymbolSpan($r('sys.symbol.heart_badge_plus')) - .fontColor([this.fontColorValue]) - .fontSize(20) - } - // [StartExclude symbol_glyph_span_scene_example] - .id('text3') - // [EndExclude symbol_glyph_span_scene_example] - - Text() { - SymbolSpan($r('sys.symbol.ohos_trash')) - .fontColor([this.fontColorValue]) - .fontSize(20) - } - // [StartExclude symbol_glyph_span_scene_example] - .id('text4') - // [EndExclude symbol_glyph_span_scene_example] - } - .width('25%') - } - - Divider().width(5).color(this.fontColorValue1).width('98%') - Row() { - Row() { - Text($r('app.string.SymbolSceneExample_Text_5')) - }.width('82%') - - Row({ space: 5 }) { - SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph2') - // [EndExclude symbol_glyph_span_scene_example] - .fontColor([this.fontColorValue]) - .fontSize(20) - SymbolGlyph($r('sys.symbol.trash')) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph3') - // [EndExclude symbol_glyph_span_scene_example] - .fontColor([this.fontColorValue]) - .fontSize(20) - } - } - - Divider().width(5).color(this.fontColorValue1).width('98%') - Row() { - Row() { - Text($r('app.string.SymbolSceneExample_Text_6')) - }.width('82%') - - Row({ space: 5 }) { - SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph4') - // [EndExclude symbol_glyph_span_scene_example] - .fontColor([this.fontColorValue]) - .fontSize(20) - SymbolGlyph($r('sys.symbol.trash')) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph5') - // [EndExclude symbol_glyph_span_scene_example] - .fontColor([this.fontColorValue]) - .fontSize(20) - } - } - - Divider().width(5).color(this.fontColorValue1).width('98%') - Row() { - Row() { - Text($r('app.string.SymbolSceneExample_Text_7')) - }.width('82%') + Column({ space: 10 }) { + Row() { + Text() { + // 'app.string.SymbolShadowAndColor_Text_1'资源文件中的value值为"阴影能力" + Span(resourceGetString.resourceToString($r('app.string.SymbolSceneExample_Text_4'))) + .fontSize(20) + .fontWeight(FontWeight.Bolder) + Span('(101)') + } + } - Row({ space: 5 }) { - SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph6') - // [EndExclude symbol_glyph_span_scene_example] - .fontColor([this.fontColorValue]) - .fontSize(20) - SymbolGlyph($r('sys.symbol.trash')) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph7') - // [EndExclude symbol_glyph_span_scene_example] - .fontColor([this.fontColorValue]) - .fontSize(20) - } - } + Row() { + Row({ space: 5 }) { + SymbolGlyph(this.symbolSources[this.symbolSourcesIndex]) + .symbolEffect(new ReplaceSymbolEffect(EffectScope.WHOLE), this.triggerValueReplace) + .fontSize(20) + .fontColor([this.fontColorValue]) + Text(this.symbolText[this.symbolTextIndex]) + .fontColor(this.fontColorValue) + } + .onClick(() => { + this.symbolTextIndex++; + this.symbolSourcesIndex++; + this.triggerValueReplace++; + if (this.symbolSourcesIndex > (this.symbolSources.length - 1)) { + this.symbolSourcesIndex = 0; + this.triggerValueReplace = 0; + } + if (this.symbolTextIndex > (this.symbolText.length - 1)) { + this.symbolTextIndex = 0; + } + }) + .width('75%') + + Row({ space: 5 }) { + Text() { + SymbolSpan($r('sys.symbol.arrow_down_circle_badge_vip_circle_filled')) + .fontColor([this.fontColorValue]) + .fontSize(20) + } - Divider().width(5).color(this.fontColorValue1).width('98%') - Row() { - Row() { - Text($r('app.string.SymbolSceneExample_Text_8')) - }.width('82%') + Text() { + SymbolSpan($r('sys.symbol.heart_badge_plus')) + .fontColor([this.fontColorValue]) + .fontSize(20) + } - Row({ space: 5 }) { - SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph8') - // [EndExclude symbol_glyph_span_scene_example] - .fontColor([this.fontColorValue]) - .fontSize(20) - SymbolGlyph($r('sys.symbol.trash')) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph9') - // [EndExclude symbol_glyph_span_scene_example]s - .fontColor([this.fontColorValue]) - .fontSize(20) - } - } + Text() { + SymbolSpan($r('sys.symbol.ohos_trash')) + .fontColor([this.fontColorValue]) + .fontSize(20) + } + } + .width('25%') + } - Divider().width(5).color(this.fontColorValue1).width('98%') - Row() { - Row() { - Text($r('app.string.SymbolSceneExample_Text_9')) - }.width('82%') + Divider().width(5).color(this.fontColorValue1).width('98%') + Row() { + Row() { + // 'app.string.SymbolShadowAndColor_Text_1'资源文件中的value值为"阴影能力" + Text($r('app.string.SymbolSceneExample_Text_5')) + }.width('82%') + + Row({ space: 5 }) { + SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) + .fontColor([this.fontColorValue]) + .fontSize(20) + SymbolGlyph($r('sys.symbol.trash')) + .fontColor([this.fontColorValue]) + .fontSize(20) + } + } - Row({ space: 5 }) { - SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph10') - // [EndExclude symbol_glyph_span_scene_example] - .fontColor([this.fontColorValue]) - .fontSize(20) - SymbolGlyph($r('sys.symbol.trash')) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph11') - // [EndExclude symbol_glyph_span_scene_example] - .fontColor([this.fontColorValue]) - .fontSize(20) - } - } + Divider().width(5).color(this.fontColorValue1).width('98%') + Row() { + Row() { + // 'app.string.SymbolShadowAndColor_Text_1'资源文件中的value值为"阴影能力" + Text($r('app.string.SymbolSceneExample_Text_6')) + }.width('82%') + + Row({ space: 5 }) { + SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) + .fontColor([this.fontColorValue]) + .fontSize(20) + SymbolGlyph($r('sys.symbol.trash')) + .fontColor([this.fontColorValue]) + .fontSize(20) + } + } - Divider().width(5).color(this.fontColorValue1).width('98%') - Row() { - Row() { - Text($r('app.string.SymbolSceneExample_Text_10')) - }.width('82%') + Divider().width(5).color(this.fontColorValue1).width('98%') + Row() { + Row() { + // 'app.string.SymbolShadowAndColor_Text_1'资源文件中的value值为"阴影能力" + Text($r('app.string.SymbolSceneExample_Text_7')) + }.width('82%') + + Row({ space: 5 }) { + SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) + .fontColor([this.fontColorValue]) + .fontSize(20) + SymbolGlyph($r('sys.symbol.trash')) + .fontColor([this.fontColorValue]) + .fontSize(20) + } + } - Row({ space: 5 }) { - SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph12') - // [EndExclude symbol_glyph_span_scene_example] - .fontColor([this.fontColorValue]) - .fontSize(20) - SymbolGlyph($r('sys.symbol.trash')) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph13') - // [EndExclude symbol_glyph_span_scene_example] - .fontColor([this.fontColorValue]) - .fontSize(20) - } - } + Divider().width(5).color(this.fontColorValue1).width('98%') + Row() { + Row() { + // 'app.string.SymbolShadowAndColor_Text_1'资源文件中的value值为"阴影能力" + Text($r('app.string.SymbolSceneExample_Text_8')) + }.width('82%') + + Row({ space: 5 }) { + SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) + .fontColor([this.fontColorValue]) + .fontSize(20) + SymbolGlyph($r('sys.symbol.trash')) + .fontColor([this.fontColorValue]) + .fontSize(20) + } + } - Divider().width(5).color(this.fontColorValue1).width('98%') - Row() { - Row() { - Text($r('app.string.SymbolSceneExample_Text_11')) - }.width('82%') + Divider().width(5).color(this.fontColorValue1).width('98%') + Row() { + Row() { + // 'app.string.SymbolShadowAndColor_Text_1'资源文件中的value值为"阴影能力" + Text($r('app.string.SymbolSceneExample_Text_9')) + }.width('82%') + + Row({ space: 5 }) { + SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) + .fontColor([this.fontColorValue]) + .fontSize(20) + SymbolGlyph($r('sys.symbol.trash')) + .fontColor([this.fontColorValue]) + .fontSize(20) + } + } - Row({ space: 5 }) { - SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph14') - // [EndExclude symbol_glyph_span_scene_example] - .fontColor([this.fontColorValue]) - .fontSize(20) - SymbolGlyph($r('sys.symbol.trash')) - // [StartExclude symbol_glyph_span_scene_example] - .id('symbolGlyph15') - // [EndExclude symbol_glyph_span_scene_example] - .fontColor([this.fontColorValue]) - .fontSize(20) - } - } + Divider().width(5).color(this.fontColorValue1).width('98%') + Row() { + Row() { + // 'app.string.SymbolShadowAndColor_Text_1'资源文件中的value值为"阴影能力" + Text($r('app.string.SymbolSceneExample_Text_10')) + }.width('82%') + + Row({ space: 5 }) { + SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) + .fontColor([this.fontColorValue]) + .fontSize(20) + SymbolGlyph($r('sys.symbol.trash')) + .fontColor([this.fontColorValue]) + .fontSize(20) + } + } - Divider().width(5).color(this.fontColorValue1).width('98%') - Column() { - Text($r('app.string.SymbolSceneExample_Text_12')) - } - .alignItems(HorizontalAlign.Center) - .width('98%') - } - .alignItems(HorizontalAlign.Start) - .width('100%') - .height(400) - .padding({ - left: 10, - top: 10 - }) - // [StartExclude symbol_glyph_span_scene_example] + Divider().width(5).color(this.fontColorValue1).width('98%') + Row() { + Row() { + // 'app.string.SymbolShadowAndColor_Text_1'资源文件中的value值为"阴影能力" + Text($r('app.string.SymbolSceneExample_Text_11')) + }.width('82%') + + Row({ space: 5 }) { + SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) + .fontColor([this.fontColorValue]) + .fontSize(20) + SymbolGlyph($r('sys.symbol.trash')) + .fontColor([this.fontColorValue]) + .fontSize(20) } } - .width('100%') - .height('100%') - .padding({ left: 12, right: 12 }) - // [EndExclude symbol_glyph_span_scene_example] + + Divider().width(5).color(this.fontColorValue1).width('98%') + Column() { + // 'app.string.SymbolShadowAndColor_Text_1'资源文件中的value值为"阴影能力" + Text($r('app.string.SymbolSceneExample_Text_12')) + } + .alignItems(HorizontalAlign.Center) + .width('98%') } - // [StartExclude symbol_glyph_span_scene_example] - .backgroundColor('#f1f2f3') - .title($r('app.string.SymbolGlyphSpanSceneExample_title')) - // [EndExclude symbol_glyph_span_scene_example] + .alignItems(HorizontalAlign.Start) + .width('100%') + .height(400) + .padding({ + left: 10, + top: 10 + }) } } -// [End symbol_glyph_span_scene_example] \ No newline at end of file +// [End symbol_glyph_span_scene_example] +@Builder +export function SymbolGlyphSpanSceneExample() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ title: $r('app.string.SymbolGlyphSpanSceneExample_title') }) { + SymbolMusicDemo() + } + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.SymbolGlyphSpanSceneExample_title')) +} \ No newline at end of file diff --git a/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolShadowAndColor.ets b/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolShadowAndColor.ets index 4e6af21624a3f5dbf4f9227b52478a8464f380af..816e4fa3883c4746e7e85fdc436f920b0ed6dce5 100644 --- a/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolShadowAndColor.ets +++ b/ArkUIKit/TextComponent/entry/src/main/ets/pages/symbol/SymbolShadowAndColor.ets @@ -46,12 +46,14 @@ export struct SymbolShadowAndColor { ComponentCard({ title: $r('app.string.SymbolShadowAndColor_title_1') }) { // [Start shadow_color_1] Column() { + // 'app.string.SymbolShadowAndColor_Text_1'资源文件中的value值为"阴影能力" Text($r('app.string.SymbolShadowAndColor_Text_1')); SymbolGlyph($r('sys.symbol.ohos_wifi')) - .id('1') .fontSize(96) .symbolEffect(new HierarchicalSymbolEffect(EffectFillStyle.ITERATIVE), !this.isActive) .symbolShadow(this.options) + // 'app.string.SymbolGlyphSpanCustomIconAnimation_Button_1'资源文件中的value值为"关闭" + // 'app.string.SymbolGlyphSpanCustomIconAnimation_Button_2'资源文件中的value值为"播放" Button(!this.isActive ? $r('app.string.SymbolGlyphSpanCustomIconAnimation_Button_1') : $r('app.string.SymbolGlyphSpanCustomIconAnimation_Button_2')).onClick(() => { this.isActive = !this.isActive; }) @@ -61,8 +63,8 @@ export struct SymbolShadowAndColor { ComponentCard({ title: $r('app.string.SymbolShadowAndColor_title_2') }) { // [Start shadow_color_2] Column() { + // 'app.string.SymbolShadowAndColor_Text_2'资源文件中的value值为"径向渐变" Text($r('app.string.SymbolShadowAndColor_Text_2')) - .id('2') .fontSize(18) .fontColor(0xCCCCCC) .textAlign(TextAlign.Center) diff --git a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textImageMixedLayout/TextImageAttribute.ets b/ArkUIKit/TextComponent/entry/src/main/ets/pages/textImageMixedLayout/TextImageAttribute.ets index aa84a3be456a302235a50863e09292de5abd3850..72d74329ae0b540f78f312dfaab990b99d606f63 100644 --- a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textImageMixedLayout/TextImageAttribute.ets +++ b/ArkUIKit/TextComponent/entry/src/main/ets/pages/textImageMixedLayout/TextImageAttribute.ets @@ -13,14 +13,20 @@ * limitations under the License. */ -import resource from '../../common/resource'; // [Start textImage_attribute] +// resourceGetString封装工具,从资源中获取字符串 +import resourceGetString from '../../common/resource'; import { image } from '@kit.ImageKit'; import { LengthMetrics } from '@kit.ArkUI'; +import { hilog } from '@kit.PerformanceAnalysisKit'; + +const TAG = '[Sample_Textcomponent]'; +const DOMAIN = 0xF811; +const BUNDLE = 'Textcomponent_'; @Entry @Component -export struct TextImageAttribute { +struct styled_string_demo { @State message: string = 'Hello World'; imagePixelMap: image.PixelMap | undefined = undefined; @State imagePixelMap3: image.PixelMap | undefined = undefined; @@ -38,8 +44,8 @@ export struct TextImageAttribute { }]); async aboutToAppear() { - console.info('aboutToAppear initial imagePixelMap'); - this.imagePixelMap = await this.getPixmapFromMedia($r('app.media.startIcon')); + hilog.info(DOMAIN, TAG, BUNDLE + 'aboutToAppear initial imagePixelMap'); + this.imagePixelMap = await this.getPixmapFromMedia($r('app.media.sky')); } private async getPixmapFromMedia(resource: Resource) { @@ -64,7 +70,8 @@ export struct TextImageAttribute { boldTextStyle: TextStyle = new TextStyle({ fontWeight: FontWeight.Bold }); //创建含段落样式的对象paragraphStyledString1 paragraphStyledString1: MutableStyledString = - new MutableStyledString(resource.resourceToString($r('app.string.TextImageAttribute_Content_1')), [ + // 'app.string.TextImageAttribute_Content_1'资源文件中的value值为"\n高质量冲洗照片,高清冲印3/4/5/6寸包邮塑封,品质保证," + new MutableStyledString(resourceGetString.resourceToString($r('app.string.TextImageAttribute_Content_1')), [ { start: 0, length: 28, @@ -78,7 +85,8 @@ export struct TextImageAttribute { styledValue: this.lineHeightStyle1 } ]); - paragraphStyledString2: MutableStyledString = new MutableStyledString(resource.resourceToString($r('app.string.TextImageAttribute_Content_2')), [ + // 'app.string.TextImageAttribute_Content_2'资源文件中的value值为"\n限时直降5.15元 限量增送" + paragraphStyledString2: MutableStyledString = new MutableStyledString(resourceGetString.resourceToString($r('app.string.TextImageAttribute_Content_2')), [ { start: 0, length: 5, @@ -110,7 +118,8 @@ export struct TextImageAttribute { styledValue: new TextStyle({ fontColor: Color.Grey, fontSize: LengthMetrics.vp(14) }) } ]); - paragraphStyledString3: MutableStyledString = new MutableStyledString(resource.resourceToString($r('app.string.TextImageAttribute_Content_3')), [ + // 'app.string.TextImageAttribute_Content_3'资源文件中的value值为"\n¥22.50 销量400万+" + paragraphStyledString3: MutableStyledString = new MutableStyledString(resourceGetString.resourceToString($r('app.string.TextImageAttribute_Content_3')), [ { start: 0, length: 15, @@ -156,46 +165,46 @@ export struct TextImageAttribute { ]); build() { - // [StartExclude textImage_attribute] - NavDestination() { - // [EndExclude textImage_attribute] - Row() { - Column({ space: 10 }) { - Text(undefined, { controller: this.controller }) - .copyOption(CopyOptions.InApp) - .draggable(true) - .backgroundColor('#FFFFFF') - .borderRadius(5) - .width(210) - - Button($r('app.string.textImageMixedLayout_content')) - .onClick(() => { - if (this.imagePixelMap !== undefined) { - this.mutableStr = new MutableStyledString(new ImageAttachment({ - value: this.imagePixelMap, - size: { width: 210, height: 190 }, - verticalAlign: ImageSpanAlignment.BASELINE, - objectFit: ImageFit.Fill, - layoutStyle: { - borderRadius: LengthMetrics.vp(5) - } - })); - this.paragraphStyledString1.appendStyledString(this.paragraphStyledString2); - this.paragraphStyledString1.appendStyledString(this.paragraphStyledString3); - this.mutableStr.appendStyledString(this.paragraphStyledString1); - this.controller.setStyledString(this.mutableStr); - } - }) - } - .width('100%') + Row() { + Column({ space: 10 }) { + Text(undefined, { controller: this.controller }) + .copyOption(CopyOptions.InApp) + .draggable(true) + .backgroundColor('#FFFFFF') + .borderRadius(5) + .width(210) + // 'app.string.textImageMixedLayout_content'资源文件中的value值为"点击查看商品详情" + Button($r('app.string.textImageMixedLayout_content')) + .onClick(() => { + if (this.imagePixelMap !== undefined) { + this.mutableStr = new MutableStyledString(new ImageAttachment({ + value: this.imagePixelMap, + size: { width: 210, height: 190 }, + verticalAlign: ImageSpanAlignment.BASELINE, + objectFit: ImageFit.Fill, + layoutStyle: { + borderRadius: LengthMetrics.vp(5) + } + })); + this.paragraphStyledString1.appendStyledString(this.paragraphStyledString2); + this.paragraphStyledString1.appendStyledString(this.paragraphStyledString3); + this.mutableStr.appendStyledString(this.paragraphStyledString1); + this.controller.setStyledString(this.mutableStr); + } + }) } - .height('100%') - .backgroundColor('#F8F8FF') - // [StartExclude textImage_attribute] + .width('100%') } - .backgroundColor('#f1f2f3') - .title($r('app.string.TextImage_MixedLayout_Text_2')) - // [EndExclude textImage_attribute] + .height('100%') + .backgroundColor('#F8F8FF') } } // [End textImage_attribute] +@Builder +export function TextImageAttribute() { + NavDestination() { + styled_string_demo() + } + .backgroundColor('#f1f2f3') + .title($r('app.string.TextImage_MixedLayout_Text_2')) +} \ No newline at end of file diff --git a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textImageMixedLayout/TextImageComponent.ets b/ArkUIKit/TextComponent/entry/src/main/ets/pages/textImageMixedLayout/TextImageComponent.ets index 04d97c4d9b09681dac0fc6d53272081b94fe2512..aa1c61d3134d7259fd41531fde9fca4212cd7645 100644 --- a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textImageMixedLayout/TextImageComponent.ets +++ b/ArkUIKit/TextComponent/entry/src/main/ets/pages/textImageMixedLayout/TextImageComponent.ets @@ -13,7 +13,6 @@ * limitations under the License. */ - @Entry @Component export struct TextImageComponent { @@ -21,15 +20,16 @@ export struct TextImageComponent { NavDestination() { // [Start textImage_component] Text() { - ImageSpan($r('app.media.startIcon')) + ImageSpan($r('app.media.hot_sale')) .width(50) .height(30) .borderRadius(5) .verticalAlign(ImageSpanAlignment.FOLLOW_PARAGRAPH) + // 'app.string.TextImage_MixedLayout_Content_1'资源文件中的value值为"惊喜价 ¥1299" Span($r('app.string.TextImage_MixedLayout_Content_1')) .fontSize(25) .fontColor(Color.Red) - Span($r('app.string.TextImage_MixedLayout_Content_2')) + Span('1599') .decoration({ type: TextDecorationType.LineThrough, color: Color.Grey, diff --git a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textImageMixedLayout/index.ets b/ArkUIKit/TextComponent/entry/src/main/ets/pages/textImageMixedLayout/index.ets index 9f9f940fa2e232e2d0f33174a79d4bbdc8ffe5b9..cb17e65f6205756a573a493c10eec97b5f2ee789 100644 --- a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textImageMixedLayout/index.ets +++ b/ArkUIKit/TextComponent/entry/src/main/ets/pages/textImageMixedLayout/index.ets @@ -16,18 +16,19 @@ import { CompletedRoutableCard } from '../../common/Card'; import { Route } from '../../common/Route'; import resource from '../../common/resource'; -import { router } from '@kit.ArkUI'; +import { TextImageComponent } from './TextImageComponent'; +import { TextImageAttribute } from './TextImageAttribute'; export const TEXT_IMAGE_MIXED_LAYOUT: string = 'TextImageMixedLayout'; const routes: Route[] = [ { - name: 'textImageMixedLayout/TextImageComponent', + name: `${TEXT_IMAGE_MIXED_LAYOUT}/TextImageComponent`, title: resource.resourceToString($r('app.string.TextImage_MixedLayout_Text_1')), description: $r('app.string.TextImage_MixedLayout_Component_desc') }, { - name: `textImageMixedLayout/TextImageAttribute`, + name: `${TEXT_IMAGE_MIXED_LAYOUT}/TextImageAttribute`, title: resource.resourceToString($r('app.string.TextImage_MixedLayout_Text_2')), description: $r('app.string.TextImage_MixedLayout_Attribute_desc') } @@ -37,23 +38,17 @@ const routes: Route[] = [ export function TextImageMixedLayoutDestination(name: string) { if (name === TEXT_IMAGE_MIXED_LAYOUT) { PropertyStringExample(); + } else if (name === routes[0].name) { + TextImageComponent(); + } else if (name === routes[1].name) { + TextImageAttribute(); } } @Entry @Component struct PropertyStringExample { - goToSample(url: string): void { - router.pushUrl({ - url: url, - }, router.RouterMode.Single, (err) => { - if (err) { - console.error(`pushUrl failed, code is ${err.code}, message is ${err.message}`); - return; - } - console.info('pushUrl success'); - }) - } + @Consume pathStack: NavPathStack; build() { NavDestination() { @@ -64,7 +59,7 @@ struct PropertyStringExample { } .width('100%') .onClick(() => { - this.goToSample('pages/' + route.name); + this.pathStack.pushPath({ name: route.name }); }) }) } diff --git a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/ProhibitSelectMenu/DisableSystemServiceMenuItems.ets b/ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/ProhibitSelectMenu/DisableSystemServiceMenuItems.ets deleted file mode 100644 index 4607bc89f7e1dbc18b5af68b3f0043cfe8c87dfc..0000000000000000000000000000000000000000 --- a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/ProhibitSelectMenu/DisableSystemServiceMenuItems.ets +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// [Start DisableSystemServiceMenuItems] -import { TextMenuController } from '@kit.ArkUI'; - -@Entry -@Component -export struct DisableSystemServiceMenuItems { - aboutToAppear(): void { - // 禁用所有系统服务菜单项 - TextMenuController.disableSystemServiceMenuItems(true) - } - - aboutToDisappear(): void { - // 页面消失时恢复系统服务菜单项 - TextMenuController.disableSystemServiceMenuItems(false) - } - - build() { - // [StartExclude DisableSystemServiceMenuItems] - NavDestination() { - // [EndExclude DisableSystemServiceMenuItems] - Row() { - Column() { - TextInput({ text: $r('app.string.ProhibitSelectMenu_content') }) - .height(60) - .fontStyle(FontStyle.Italic) - .fontWeight(FontWeight.Bold) - .textAlign(TextAlign.Center) - .caretStyle({ width: '4vp' }) - .editMenuOptions({ - onCreateMenu: (menuItems: Array) => { - // menuItems不包含被屏蔽的系统菜单项 - return menuItems - }, - onMenuItemClick: (menuItem: TextMenuItem, textRange: TextRange) => { - return false - } - }) - }.width('100%') - } - .height('100%') - // [StartExclude DisableSystemServiceMenuItems] - } - .backgroundColor('#f1f2f3') - .title($r('app.string.ProhibitSelectMenu_title_1')) - // [EndExclude DisableSystemServiceMenuItems] - } -} -// [End DisableSystemServiceMenuItems] \ No newline at end of file diff --git a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/ProhibitSelectMenu/index.ets b/ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/ProhibitSelectMenu/index.ets deleted file mode 100644 index 02745f2782ffa5a6de15e9ac2d22ded4ab920f83..0000000000000000000000000000000000000000 --- a/ArkUIKit/TextComponent/entry/src/main/ets/pages/textInput/ProhibitSelectMenu/index.ets +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { CompletedRoutableCard } from '../../../common/Card'; -import resource from '../../../common/resource'; -import { Route } from '../../../common/Route'; -import { DisableMenuItems } from './DisableMenuItems'; -import { DisableSystemServiceMenuItems } from './DisableSystemServiceMenuItems'; -import { router } from '@kit.ArkUI'; - -export const PROHIBIT_SELECT_MENU_ROUTE: string = 'textInput/ProhibitSelectMenu'; -const routes: Route[] = [ - { - name: `${PROHIBIT_SELECT_MENU_ROUTE}/DisableSystemServiceMenuItems`, - title: resource.resourceToString($r('app.string.ProhibitSelectMenu_title_1')), - description: $r('app.string.ProhibitSelectMenu_description_1') - }, - { - name: `${PROHIBIT_SELECT_MENU_ROUTE}/DisableMenuItems`, - title: resource.resourceToString($r('app.string.ProhibitSelectMenu_title_2')), - description: $r('app.string.ProhibitSelectMenu_description_2') - } -]; - -@Builder -export function ProhibitSelectDestination(name: string) { - if (name === routes[0].name) { - DisableSystemServiceMenuItems(); - } else if (name === routes[1].name) { - DisableMenuItems(); - } -} - -@Entry -@Component -export struct ProhibitSelectionMenu { - @Consume pathStack: NavPathStack; - - goToSample(url: string): void { - router.pushUrl({ - url: url, - }, router.RouterMode.Single, (err) => { - if (err) { - return; - } - }) - } - - build() { - NavDestination() { - Scroll() { - List({ space: 12 }) { - ForEach(routes, (route: Route) => { - ListItem() { - CompletedRoutableCard({ title: route.title, description: route.description }) - } - .width('100%') - .onClick(() => { - this.goToSample('pages/' + route.name); - }) - }) - } - .contentStartOffset(56) - .padding({ left: 16, right: 16 }) - }.id('scroll_') - } - .backgroundColor('#f1f3f5') - .title('app.string.ProhibitSelectionMenu_title', { - backgroundBlurStyle: BlurStyle.COMPONENT_THICK, - barStyle: BarStyle.STACK - }) - } -} - - diff --git a/ArkUIKit/TextComponent/entry/src/main/resources/base/media/hot_sale.png b/ArkUIKit/TextComponent/entry/src/main/resources/base/media/hot_sale.png new file mode 100644 index 0000000000000000000000000000000000000000..ce0dc4a9eba89b7566a4c3bf66a0567998da41d9 Binary files /dev/null and b/ArkUIKit/TextComponent/entry/src/main/resources/base/media/hot_sale.png differ diff --git a/ArkUIKit/TextComponent/entry/src/main/resources/base/media/sky.png b/ArkUIKit/TextComponent/entry/src/main/resources/base/media/sky.png new file mode 100644 index 0000000000000000000000000000000000000000..cefef637437e863f14dfe8fc755633718eea75ae Binary files /dev/null and b/ArkUIKit/TextComponent/entry/src/main/resources/base/media/sky.png differ diff --git a/ArkUIKit/TextComponent/string.json b/ArkUIKit/TextComponent/string.json index 1b0a68e1258b29a2eff8f7d0602c5193d2b9ad57..c63167d40b493e8bfcf62bb6b03e1283028ec2fc 100644 --- a/ArkUIKit/TextComponent/string.json +++ b/ArkUIKit/TextComponent/string.json @@ -18,7 +18,7 @@ }, { "name": "pageIndex_TextInput", - "value": "文本输入(TextInput/TextArea)" + "value": "文本输入(TextInput/TextArea/Search)" }, { "name": "pageIndex_RichEditor", diff --git a/ArkUIKit/UIContext/README_zh.md b/ArkUIKit/UIContext/README_zh.md index 9e04cec8d24a26cd34a7da42b4851a05b65d3785..e5ec65a3d10b689702b73f107be145a104e21a14 100644 --- a/ArkUIKit/UIContext/README_zh.md +++ b/ArkUIKit/UIContext/README_zh.md @@ -35,7 +35,7 @@ entry/src/main/ets/ | |---LocalStoragePage.ets // 使用UIContext接口替换全局接口 entry/src/ohosTest/ |---ets -| |---index.test.ets // 对应页面测试代码 +| |---Index.test.ets // 对应页面测试代码 | |---LocalStoragePage.test.ets // 对应页面测试代码 ``` diff --git a/ArkUIKit/createCustomComponents/entry/src/main/ets/component/ParentComponent.ets b/ArkUIKit/createCustomComponents/entry/src/main/ets/component/ParentComponent.ets index 7b37974e6b9bfdb3499ca5ed44294083ab7d8d3b..bc16df278af73b7b6da3bec155bb680092b8e90f 100644 --- a/ArkUIKit/createCustomComponents/entry/src/main/ets/component/ParentComponent.ets +++ b/ArkUIKit/createCustomComponents/entry/src/main/ets/component/ParentComponent.ets @@ -15,7 +15,7 @@ // [Start HelloComponent_Hello] @Component struct HelloComponent { - @State message: string | Resource = 'Hello, World!'; + @State message: string = 'Hello, World!'; build() { // HelloComponent自定义组件组合系统组件Row和Text @@ -39,8 +39,7 @@ struct ParentComponent { Text('ArkUI message') HelloComponent({ message: 'Hello World!' }) Divider() - // $r('app.string.Hello_The_world')需要替换为开发者所需的资源文件 - HelloComponent({ message: $r('app.string.Hello_The_world') }) + HelloComponent({ message: 'Hello ArkTS!' }) } } } diff --git a/ArkUIKit/createCustomComponents/entry/src/main/ets/component/StaticCodeV1.ets b/ArkUIKit/createCustomComponents/entry/src/main/ets/component/StaticCodeV1.ets index dc790478f600dc1dbee6c440f2ac948d42c8e51c..bc1f5ede15f5c4668bc25a19b478c05360e333bb 100644 --- a/ArkUIKit/createCustomComponents/entry/src/main/ets/component/StaticCodeV1.ets +++ b/ArkUIKit/createCustomComponents/entry/src/main/ets/component/StaticCodeV1.ets @@ -24,7 +24,7 @@ struct MyComponent { // [StartExclude Static_code_V1] build() { Column() { - // $r('app.string.static_code')需要替换为开发者所需的资源文件 + // app.string.static_code资源文件中的value值为'静态代码块不生效' Text(MyComponent.a === '' ? $r('app.string.static_code') : MyComponent.a) } .width('100%') diff --git a/ArkUIKit/createCustomComponents/entry/src/main/resources/base/element/string.json b/ArkUIKit/createCustomComponents/entry/src/main/resources/base/element/string.json index 6765ec81890b1f8db3c314fc9651c2936b14a5e1..86f8e0a48c9dace0d279c10d768fe87f3079e2fb 100644 --- a/ArkUIKit/createCustomComponents/entry/src/main/resources/base/element/string.json +++ b/ArkUIKit/createCustomComponents/entry/src/main/resources/base/element/string.json @@ -12,10 +12,6 @@ "name": "EntryAbility_label", "value": "label" }, - { - "name": "Hello_The_world", - "value": "你好,世界!" - }, { "name": "static_code", "value": "静态代码块不生效" diff --git a/ArkUIKit/native_node_sample/entry/src/main/cpp/TextMaker.cpp b/ArkUIKit/native_node_sample/entry/src/main/cpp/TextMaker.cpp index f0ac984290f0a6522b0203bb1b81bd57330e17fa..c1212d8fe94b587d32bb6fdeefa502f92c5a4977 100644 --- a/ArkUIKit/native_node_sample/entry/src/main/cpp/TextMaker.cpp +++ b/ArkUIKit/native_node_sample/entry/src/main/cpp/TextMaker.cpp @@ -582,10 +582,16 @@ void setTextInput4(ArkUI_NodeHandle &textInput4) ArkUI_AttributeItem ShowCounterColorItem = {.value = showCounterArray, .size = 3, .object = options}; // 获取TextInput文本输入框未达到和超出最大字符数时计数器的颜色 - OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "Manager", "GetCounterTextColor: 0x%{public}X - GetCounterTextOverflowColor: 0x%{public}X",OH_ArkUI_ShowCounterConfig_GetCounterTextColor(options), + OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "Manager", + "GetCounterTextColor: 0x%{public}X GetCounterTextOverflowColor: 0x%{public}X", + OH_ArkUI_ShowCounterConfig_GetCounterTextColor(options), OH_ArkUI_ShowCounterConfig_GetCounterTextOverflowColor(options)); Manager::nodeAPI_->setAttribute(textInput4, NODE_TEXT_INPUT_SHOW_COUNTER, &ShowCounterColorItem); + + // 设置文本选中识别属性 + ArkUI_NumberValue selectValue = {.i32 = true}; + ArkUI_AttributeItem selectValueItem = {&selectValue, VALUE_1}; + Manager::nodeAPI_->setAttribute(textInput4, NODE_TEXT_INPUT_ENABLE_SELECTED_DATA_DETECTOR, &selectValueItem); } static void setTextArea1Val(ArkUI_NodeHandle &textArea1) @@ -668,8 +674,9 @@ void setTextArea1(ArkUI_NodeHandle &textArea1) ArkUI_AttributeItem ShowCounterColorItem = {.value = showCounterArray, .size = 3, .object = options}; // 设置TextArea文本输入框未达到和超出最大字符数时计数器的颜色 - OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "Manager", "GetCounterTextColor: 0x%{public}X - GetCounterTextOverflowColor: 0x%{public}X",OH_ArkUI_ShowCounterConfig_GetCounterTextColor(options), + OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "Manager", + "GetCounterTextColor: 0x%{public}X GetCounterTextOverflowColor: 0x%{public}X", + OH_ArkUI_ShowCounterConfig_GetCounterTextColor(options), OH_ArkUI_ShowCounterConfig_GetCounterTextOverflowColor(options)); Manager::nodeAPI_->setAttribute(textArea1, NODE_TEXT_AREA_SHOW_COUNTER, &ShowCounterColorItem); @@ -1022,6 +1029,11 @@ void setTextArea4(ArkUI_NodeHandle &textArea4) ArkUI_NumberValue textAreaScrollBarColor = { .u32 = 0xFFFFE4E1 }; ArkUI_AttributeItem textAreaScrollBarColorItem = {&textAreaScrollBarColor, VALUE_1}; Manager::nodeAPI_->setAttribute(textArea4, NODE_TEXT_AREA_SCROLL_BAR_COLOR, &textAreaScrollBarColorItem); + + // 设置文本选中识别属性 + ArkUI_NumberValue selectValue = {.i32 = true}; + ArkUI_AttributeItem selectValueItem = {&selectValue, VALUE_1}; + Manager::nodeAPI_->setAttribute(textArea4, NODE_TEXT_AREA_ENABLE_SELECTED_DATA_DETECTOR, &selectValueItem); } void setCustomKeyboard(ArkUI_NodeHandle &textArea5) @@ -1187,6 +1199,10 @@ void setText9(ArkUI_NodeHandle &text9) ArkUI_NumberValue value[] = {{.f32 = 2.0}}; ArkUI_AttributeItem item = {value, sizeof(value)/ sizeof(ArkUI_NumberValue)}; Manager::nodeAPI_->setAttribute(text9, NODE_TEXT_LINE_HEIGHT_MULTIPLE, &item); + // 设置文本选中识别属性 + ArkUI_NumberValue selectValue = {.i32 = true}; + ArkUI_AttributeItem selectValueItem = {&selectValue, VALUE_1}; + Manager::nodeAPI_->setAttribute(text9, NODE_TEXT_ENABLE_SELECTED_DATA_DETECTOR, &selectValueItem); } void setText10(ArkUI_NodeHandle &text10) diff --git a/ArkUIKit/native_node_sample/entry/src/main/cpp/imagespan_manager.cpp b/ArkUIKit/native_node_sample/entry/src/main/cpp/imagespan_manager.cpp index 7addf3697e65ea412d428ee6dc2eda4458ee9a95..ee39e6026bb1c8052cb8df38be8ebe7e5fd5b78d 100644 --- a/ArkUIKit/native_node_sample/entry/src/main/cpp/imagespan_manager.cpp +++ b/ArkUIKit/native_node_sample/entry/src/main/cpp/imagespan_manager.cpp @@ -47,7 +47,7 @@ struct AttributeScope { }; AttributeScope g_attributeArray[] = { - {ARKUI_NODE_IMAGE_SPAN, NODE_IMAGE_SPAN_SRC, NODE_IMAGE_SPAN_BASELINE_OFFSET, NODE_IMAGE_SPAN_SUPPORT_SVG2}, + {ARKUI_NODE_IMAGE_SPAN, NODE_IMAGE_SPAN_SRC, NODE_IMAGE_SPAN_SUPPORT_SVG2}, {ARKUI_NODE_IMAGE, NODE_BACKGROUND_IMAGE, NODE_IMAGE_ORIENTATION}, {ARKUI_NODE_LOADING_PROGRESS, NODE_LOADING_PROGRESS_COLOR, NODE_LOADING_PROGRESS_ENABLE_LOADING}, {ARKUI_NODE_PROGRESS, NODE_PROGRESS_VALUE, NODE_PROGRESS_LINEAR_STYLE}, @@ -112,6 +112,7 @@ static std::map attributeValueMap = { {NODE_IMAGE_SPAN_VERTICAL_ALIGNMENT, {imageSpanValue2, 1, nullptr, nullptr}}, {NODE_IMAGE_SPAN_ALT, {commonValue1, 1, BACKGROUND_PATH, nullptr}}, {NODE_IMAGE_SPAN_BASELINE_OFFSET, {commonValue1, 1, nullptr, nullptr}}, + {NODE_IMAGE_SPAN_COLOR_FILTER, {imageValue8, 20, nullptr, nullptr}}, {NODE_IMAGE_SPAN_SUPPORT_SVG2, {commonValue1, 1, nullptr, nullptr}}, // ARKUI_NODE_IMAGE {NODE_BACKGROUND_IMAGE, {commonValue1, 1, BACKGROUND_PATH, nullptr}}, diff --git a/ArkUIKit/native_node_sample/entry/src/main/ets/pages/page_imagespan.ets b/ArkUIKit/native_node_sample/entry/src/main/ets/pages/page_imagespan.ets index 8453ee8c113e198b55e3cbc678ccd14af73890b1..167612ee91bb18473f6d0d4eabbc644bdd7d94c7 100644 --- a/ArkUIKit/native_node_sample/entry/src/main/ets/pages/page_imagespan.ets +++ b/ArkUIKit/native_node_sample/entry/src/main/ets/pages/page_imagespan.ets @@ -140,6 +140,14 @@ struct Index { this.attributeType = 'BASELINE_OFFSET' this.attributeTypeId = 3003 }) + MenuItem({ content: 'COLOR_FILTER' }).width('50%').onChange(()=> { + this.attributeType = 'COLOR_FILTER' + this.attributeTypeId = 3004 + }) + MenuItem({ content: 'SUPPORT_SVG2' }).width('50%').onChange(()=> { + this.attributeType = 'SUPPORT_SVG2' + this.attributeTypeId = 3005 + }) } } // add image attributeType