diff --git a/code/DocsSample/ArkUISample/TextComponent/README_zh.md b/code/DocsSample/ArkUISample/TextComponent/README_zh.md index 6a4f33d9d0a343d390790fd80d6a7a89803d588b..0952c25ee9e2666917e5d729056c90d7e6b229ea 100644 --- a/code/DocsSample/ArkUISample/TextComponent/README_zh.md +++ b/code/DocsSample/ArkUISample/TextComponent/README_zh.md @@ -4,13 +4,19 @@ 本示例通过使用[ArkUI指南文档](https://gitee.com/openharmony/docs/tree/master/zh-cn/application-dev/ui)中各场景的开发示例,展示在工程中,帮助开发者更好地理解ArkUI提供的组件及组件属性并合理使用。该工程中展示的代码详细描述可查如下链接: -1. [文本显示 (Text/Span)](https://gitee.com/openharmony/docs/blob/OpenHarmony-5.0.1-Release/zh-cn/application-dev/ui/arkts-common-components-text-display.md)。 -2. [文本输入 (TextInput/TextArea)](https://gitee.com/openharmony/docs/blob/OpenHarmony-5.0.1-Release/zh-cn/application-dev/ui/arkts-common-components-text-input.md)。 +1. [文本显示 (Text/Span)](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/ui/arkts-common-components-text-display.md)。 +2. [文本输入 (TextInput/TextArea)](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/ui/arkts-common-components-text-input.md)。 +3. [富文本 (RichEditor)](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/ui/arkts-common-components-richeditor.md)。 +4. [图标小符号 (SymbolGlyph/SymbolSpan)](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/ui/arkts-common-components-symbol.md)。 +5. [属性字符串 (StyledString/MutableStyledString)](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/ui/arkts-styled-string.md)。 +6. [Text组件的文本绘制与显示](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/ui/ndk-styled-string.md)。 +7. [监听输入框事件](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/ui/ndk-textarea-event.md)。 + ### 效果预览 -| 首页 | 文本显示组件目录 | 创建文本示例 | -|------------------------------------|------------------------------------|------------------------------------| -| ![](screenshots/device/image1.png) | ![](screenshots/device/image2.png) | ![](screenshots/device/image3.png) | +| 首页 | 文本显示组件目录 | 创建文本示例 | +|-------------------------------------| ----------------------------------- | ----------------------------------- | +| ![](screenshots/device/image1.jpeg) | ![](screenshots/device/image2.jpeg) | ![](screenshots/device/image3.jpeg) | ### 使用说明 @@ -23,30 +29,69 @@ 4. 通过自动测试框架可进行测试及维护。 ### 工程目录 + ``` entry/src/main/ets/ |---entryability |---pages -| |---text //文本显示 +| |---ndk // ndk接口使用文本 +| | |---index.ets +| | |---TextDrawingDisplay.ets +| | |---ListenTextBoxEvents.ets +| |---propertyString // 属性字符串 +| | |---CreateApply.ets +| | |---index.ets +| | |---StyledStringGestureStyle.ets +| | |---StyledStringHtml.ets +| | |---StyledStringImageAttachment.ets +| | |---StyledStringParagraphStyle.ets +| | |---StyledStringSceneExample.ets +| | |---StyledStringStyle.ets +| |---richEditor // 富文本 +| | |---AddBuilderDecoratorContent.ets +| | |---AddEvent.ets +| | |---AddImageContent.ets +| | |---AddSymbolSpanContent.ets +| | |---AddTextContent.ets +| | |---BackplaneHighlighting.ets +| | |---CreateRichEditor.ets +| | |---GetGraphicInfoInComponent.ets +| | |---index.ets +| | |---SetAttributes.ets +| | |---SetUserPresetTextStyles.ets +| |---symbol // 图标小符号 +| | |---CreatSymbolGlyph.ets +| | |---index.ets +| | |---SymbolAddEvent.ets +| | |---SymbolAddToText.ets +| | |---SymbolCustomIconAnimation.ets +| | |---SymbolSceneExample.ets +| |---text // 文本显示 +| | |---AIMenu.ets | | |---CreatText.ets | | |---CustomTextStyle.ets | | |---index.ets +| | |---SelectMenu.ets | | |---TextAddEvent.ets | | |---TextHotSearch.ets | | |---TextSpan.ets -| |---testInput //文本输入 +| |---testInput // 文本输入 +| | |---AutoFill.ets | | |---CreatTextInput.ets +| | |---CursorAvoidance.ets | | |---CustomTextInputStyle.ets | | |---index.ets | | |---KeyboardAvoidance.ets | | |---LoginRegisterPage.ets -| | |---SetTextInputType.ets -| | |---TextInputAddEvent.ets +| | |---SelectMenu.ets +| | |---SetOmissionProperty.ets +| | |---SetTextInputType.ets +| | |---TextInputAddEvent.ets |---pages -| |---Index.ets // 应用主页面 +| |---Index.ets // 应用主页面 entry/src/ohosTest/ |---ets -| |---index.test.ets // 示例代码测试代码 +| |---index.test.ets // 示例代码测试代码 ``` ### 相关权限 @@ -61,9 +106,9 @@ entry/src/ohosTest/ 1.本示例仅支持标准系统上运行, 支持设备:RK3568。 -2.本示例为Stage模型,支持API14版本SDK,版本号:5.0.2.57,镜像版本号:OpenHarmony_5.0.2.57。 +2.本示例为Stage模型,支持API20版本SDK,版本号:6.0.0.34,镜像版本号:OpenHarmony_6.0.0.34。 -3.本示例需要使用DevEco Studio NEXT Developer Preview2 (Build Version: 5.0.5.306, built on December 12, 2024)及以上版本才可编译运行。 +3.本示例需要使用DevEco Studio 6.0.0及以上版本才可编译运行。 ### 下载 diff --git a/code/DocsSample/ArkUISample/TextComponent/build-profile.json5 b/code/DocsSample/ArkUISample/TextComponent/build-profile.json5 index 9a067264a40737cf79d1d8ae7c574b8d2cc87ce0..a515b0108ca94fd9d2bf77a9617ad8cbcfb66d07 100644 --- a/code/DocsSample/ArkUISample/TextComponent/build-profile.json5 +++ b/code/DocsSample/ArkUISample/TextComponent/build-profile.json5 @@ -20,9 +20,9 @@ { "name": "default", "signingConfig": "default", - "compileSdkVersion": 14, - "compatibleSdkVersion": 14, - "targetSdkVersion": 14, + "compileSdkVersion": 20, + "compatibleSdkVersion": 20, + "targetSdkVersion": 20, "runtimeOS": "OpenHarmony", "buildOption": { "strictMode": { diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/build-profile.json5 b/code/DocsSample/ArkUISample/TextComponent/entry/build-profile.json5 index e7569e3056e27af38e9991b7ea73ec10f3ba8a05..8bbe548ca77166375df1b97f53c10c7b4b7e46ad 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/build-profile.json5 +++ b/code/DocsSample/ArkUISample/TextComponent/entry/build-profile.json5 @@ -16,6 +16,16 @@ { "apiType": "stageMode", "buildOption": { + "externalNativeOptions": { + "path": "./src/main/cpp/CMakeLists.txt", + "arguments": "", + "cppFlags": "", + "abiFilters": [ + "x86_64", + "armeabi-v7a", + "arm64-v8a" + ] + } }, "buildOptionSet": [ { @@ -29,6 +39,12 @@ ] } } + }, + "nativeLib": { + "debugSymbol": { + "strip": true, + "exclude": [] + } } }, ], diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/oh-package.json5 b/code/DocsSample/ArkUISample/TextComponent/entry/oh-package.json5 index c9cb6c8174858277c9b0d465a51547dcab16d5ff..118bdd4fe7699368a010e04c24f5bfc887cf1298 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/oh-package.json5 +++ b/code/DocsSample/ArkUISample/TextComponent/entry/oh-package.json5 @@ -20,6 +20,7 @@ "main": "", "author": "", "license": "", - "dependencies": {} -} - + "dependencies": { + "libentry.so": "file:./src/main/cpp/types/libentry" + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/cpp/CMakeLists.txt b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b5320e1e1747df47b80c52ac3b1dbaa738cb5319 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/cpp/CMakeLists.txt @@ -0,0 +1,15 @@ +# the minimum version of CMake. +cmake_minimum_required(VERSION 3.5.0) +project(TextComponent) + +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) +target_link_libraries(entry PUBLIC libace_napi.z.so libnative_drawing.so libace_ndk.z.so) \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/cpp/napi_init.cpp b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/cpp/napi_init.cpp new file mode 100644 index 0000000000000000000000000000000000000000..03b8bc38c7f21e29ac387679e6be3e894c5a8873 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/cpp/napi_init.cpp @@ -0,0 +1,194 @@ +/* + * 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. + */ +#include "napi/native_api.h" +#include "arkui/styled_string.h" +#include "arkui/native_node.h" +#include +#include +#include +#include +#include +#include + +static napi_value CreateNativeNode(napi_env env, napi_callback_info info) +{ + const int fontSize = 28; + const int textSize = 400; + const int maxLines = 10; + size_t argc = 1; + napi_value args[1]; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + ArkUI_NodeContentHandle rootSlot = nullptr; + OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &rootSlot); + + ArkUI_NativeNodeAPI_1 *nodeApi = reinterpret_cast( + OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1")); + if (nodeApi == nullptr) { + return nullptr; + } + // 创建一个Column容器组件 + ArkUI_NodeHandle column = nodeApi->createNode(ARKUI_NODE_COLUMN); + ArkUI_NumberValue colWidth[] = {{.f32 = 300}}; + ArkUI_AttributeItem widthItem = {.value = colWidth, .size = 1}; + nodeApi->setAttribute(column, NODE_WIDTH, &widthItem); + // 创建Text组件 + ArkUI_NodeHandle text = nodeApi->createNode(ARKUI_NODE_TEXT); + ArkUI_NumberValue textWidth[] = {{.f32 = 300}}; + ArkUI_AttributeItem textWidthItem = {.value = textWidth, .size = 1}; + nodeApi->setAttribute(text, NODE_WIDTH, &textWidthItem); + + ArkUI_NumberValue textHeight[] = {{.f32 = 100}}; + ArkUI_AttributeItem textHeightItem = {.value = textHeight, .size = 1}; + nodeApi->setAttribute(text, NODE_HEIGHT, &textHeightItem); + + ArkUI_NumberValue borderWidth[] = {{.f32 = 1}}; + ArkUI_AttributeItem borderWidthItem = {.value = borderWidth, .size = 1}; + nodeApi->setAttribute(text, NODE_BORDER_WIDTH, &borderWidthItem); + + // typographyStyle表示段落样式。 + OH_Drawing_TypographyStyle *typographyStyle = OH_Drawing_CreateTypographyStyle(); + // 文字居中显示 + OH_Drawing_SetTypographyTextAlign(typographyStyle, OH_Drawing_TextAlign::TEXT_ALIGN_CENTER); + OH_Drawing_SetTypographyTextMaxLines(typographyStyle, maxLines); + ArkUI_StyledString *styledString = OH_ArkUI_StyledString_Create(typographyStyle, OH_Drawing_CreateFontCollection()); + // 创建文本样式,设置字体和颜色。 + OH_Drawing_TextStyle *textStyle = OH_Drawing_CreateTextStyle(); + OH_Drawing_SetTextStyleFontSize(textStyle, fontSize); + OH_Drawing_SetTextStyleColor(textStyle, OH_Drawing_ColorSetArgb(0xFF, 0x70, 0x70, 0x70)); + // 文本样式的设置有顺序。 + OH_ArkUI_StyledString_PushTextStyle(styledString, textStyle); + OH_ArkUI_StyledString_AddText(styledString, "Hello"); + OH_ArkUI_StyledString_PopTextStyle(styledString); + // 在Hello和World中间插入100x100的占位。 + OH_Drawing_PlaceholderSpan placeHolder{ + .width = 100, + .height = 100, + }; + OH_ArkUI_StyledString_AddPlaceholder(styledString, &placeHolder); + OH_Drawing_TextStyle *worldTextStyle = OH_Drawing_CreateTextStyle(); + OH_Drawing_SetTextStyleFontSize(worldTextStyle, fontSize); + OH_Drawing_SetTextStyleColor(worldTextStyle, OH_Drawing_ColorSetArgb(0xFF, 0x27, 0x87, 0xD9)); + OH_ArkUI_StyledString_PushTextStyle(styledString, worldTextStyle); + OH_ArkUI_StyledString_AddText(styledString, "World!"); + OH_ArkUI_StyledString_PopTextStyle(styledString); + OH_Drawing_Typography *typography = OH_ArkUI_StyledString_CreateTypography(styledString); + OH_Drawing_TypographyLayout(typography, textSize); + ArkUI_AttributeItem styledStringItem = {.object = styledString}; + nodeApi->setAttribute(text, NODE_TEXT_CONTENT_WITH_STYLED_STRING, &styledStringItem); + + OH_ArkUI_StyledString_Destroy(styledString); + // Text作为Column子组件 + nodeApi->addChild(column, text); + OH_ArkUI_NodeContent_AddNode(rootSlot, column); + return nullptr; +} +static napi_value CreateTextAreaNode(napi_env env, napi_callback_info info) +{ + size_t argc = 1; + napi_value args[1]; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + ArkUI_NodeContentHandle rootSlot = nullptr; + OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &rootSlot); + + ArkUI_NativeNodeAPI_1 *nodeApi = reinterpret_cast( + OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1")); + if (nodeApi == nullptr) { + return nullptr; + } + ArkUI_NodeHandle column = nodeApi->createNode(ARKUI_NODE_COLUMN); + ArkUI_NumberValue colWidth[] = {{.f32 = 300}}; + ArkUI_AttributeItem widthItem = {.value = colWidth, .size = 1}; + nodeApi->setAttribute(column, NODE_WIDTH, &widthItem); + + ArkUI_NodeHandle text = nodeApi->createNode(ARKUI_NODE_TEXT); + ArkUI_NumberValue textWidth[] = {{.f32 = 300}}; + ArkUI_AttributeItem textWidthItem = {.value = textWidth, .size = 1}; + nodeApi->setAttribute(text, NODE_WIDTH, &textWidthItem); + nodeApi->addChild(column, text); + + ArkUI_NodeHandle selectionText = nodeApi->createNode(ARKUI_NODE_TEXT); + ArkUI_NumberValue selectionTextWidth[] = {{.f32 = 300}}; + ArkUI_AttributeItem selectionTextWidthItem = {.value = selectionTextWidth, .size = 1}; + nodeApi->setAttribute(selectionText, NODE_WIDTH, &selectionTextWidthItem); + nodeApi->addChild(column, selectionText); + + ArkUI_NodeHandle textArea = nodeApi->createNode(ARKUI_NODE_TEXT_AREA); + ArkUI_NumberValue textAreaWidth[] = {{.f32 = 300}}; + ArkUI_AttributeItem textAreaWidthItem = {.value = textAreaWidth, .size = 1}; + nodeApi->setAttribute(textArea, NODE_WIDTH, &textAreaWidthItem); + + ArkUI_NumberValue borderWidth[] = {{.f32 = 1}}; + ArkUI_AttributeItem borderWidthItem = {.value = borderWidth, .size = 1}; + nodeApi->setAttribute(textArea, NODE_BORDER_WIDTH, &borderWidthItem); + + const ArkUI_AttributeItem *attributeItem = nodeApi->getAttribute(textArea, NODE_UNIQUE_ID); + auto id = attributeItem->value[0].i32; + nodeApi->registerNodeEvent(textArea, NODE_TEXT_AREA_ON_CHANGE, id, text); + nodeApi->registerNodeEvent(textArea, NODE_TEXT_AREA_ON_PASTE, id, text); + nodeApi->registerNodeEvent(textArea, NODE_TEXT_AREA_ON_TEXT_SELECTION_CHANGE, id, selectionText); + nodeApi->registerNodeEventReceiver([](ArkUI_NodeEvent *event) { + ArkUI_NodeEventType eventType = OH_ArkUI_NodeEvent_GetEventType(event); + ArkUI_AttributeItem content; + if (eventType == NODE_TEXT_AREA_ON_CHANGE || eventType == NODE_TEXT_AREA_ON_PASTE) { + ArkUI_StringAsyncEvent *stringEvent = OH_ArkUI_NodeEvent_GetStringAsyncEvent(event); + content = {.string = stringEvent->pStr }; + } else if (eventType == NODE_TEXT_AREA_ON_TEXT_SELECTION_CHANGE) { + ArkUI_NodeComponentEvent *componentEvent = OH_ArkUI_NodeEvent_GetNodeComponentEvent(event); + std::stringstream selectContent; + selectContent << "start: " << componentEvent->data[0].i32 << " , end: " << componentEvent->data[1].i32; + content = {.string = selectContent.str().c_str() }; + } else { + return; + } + ArkUI_NodeHandle textNode = reinterpret_cast(OH_ArkUI_NodeEvent_GetUserData(event)); + if (textNode) { + ArkUI_NativeNodeAPI_1 *nodeApi = reinterpret_cast( + OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1")); + nodeApi->setAttribute(textNode, NODE_TEXT_CONTENT, &content); + } + }); + nodeApi->addChild(column, textArea); + OH_ArkUI_NodeContent_AddNode(rootSlot, column); + return nullptr; +} + +EXTERN_C_START +static napi_value Init(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + { "createNativeNode", nullptr, CreateNativeNode, nullptr, nullptr, nullptr, napi_default, nullptr }, + { "createTextAreaNode", nullptr, CreateTextAreaNode, 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); +} diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/cpp/types/libentry/index.d.ts b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/cpp/types/libentry/index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..d0214ce4ff991fa8b6662fab9ac34a8437956901 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/cpp/types/libentry/index.d.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export const createNativeNode: (content: Object) => void; +export const createTextAreaNode: (content: Object) => void; \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/cpp/types/libentry/oh-package.json5 b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/cpp/types/libentry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2826cc7d6bd199c1008bb51d898dffa922201e6c --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/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/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/common/Card.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/common/Card.ets index 0cb4a246cf373fd6a3e883042ccd3d9abe1d2f79..8a5d71ab7914f99cbbfac51282bceff22857dad8 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/common/Card.ets +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/common/Card.ets @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + @Component export struct CompletedRoutableCard { @Prop @@ -104,8 +104,7 @@ export struct RoutableCard { @Component export struct ComponentCard { @Prop - @Require - title: ResourceStr; + title?: ResourceStr; @BuilderParam content: () => void; @Prop description?: ResourceStr; @@ -115,9 +114,10 @@ export struct ComponentCard { Text(this.title) .fontSize(14) .fontColor('#666') - Row({ space: 12}) { + Row({ space: 12 }) { this.content(); } + if (this.description) { Text(this.description) .backgroundColor('#eee') diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/entryability/EntryAbility.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/entryability/EntryAbility.ets index a3cf7a1471f18cd0c4374787818cd6a0ce5c9db6..f85e945903c56eec3b80c0e60f8efd688b7555e2 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/entryability/EntryAbility.ets +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/entryability/EntryAbility.ets @@ -16,6 +16,7 @@ import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; +import { KeyboardAvoidMode } from '@kit.ArkUI'; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { @@ -31,12 +32,14 @@ export default class EntryAbility extends UIAbility { // Main window is created, set main page for this ability hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); - windowStage.loadContent('pages/Index', (err) => { + windowStage.loadContent('pages/Index', (err, data) => { + let keyboardAvoidMode = windowStage.getMainWindowSync().getUIContext().getKeyboardAvoidMode(); + windowStage.getMainWindowSync().getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.OFFSET_WITH_CARET); if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } - hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); }); } diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/Index.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/Index.ets index f340215e6ee72ea975163b679752e9589a1c60b3..0b620e6fb514d704192770e5dca477ddc72588e1 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/Index.ets +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/Index.ets @@ -18,6 +18,10 @@ import { RoutableCard } from '../common/Card'; import { Route } from '../common/Route'; import { TextDestination, TEXT_ROUTE_PREFIX } from './text'; import { TextInputDestination, INPUT_ROUTE_PREFIX } from './textInput'; +import { RichEditorDestination, RICH_EDITOR_ROUTE_PREFIX } from './richEditor'; +import { SymbolGlyphSpanDestination, SYMBOL_GLYPH_SPAN } from './symbol'; +import { PropertyStringDestination, PROPERTY_STRING_ROUTE_PREFIX } from './propertyString'; +import { NDKDestination, NDK_ROUTE_PREFIX } from './ndk'; import resource from '../common/resource'; const routes: Route[] = [ @@ -28,6 +32,22 @@ const routes: Route[] = [ { title: resource.resourceToString($r('app.string.pageIndex_TextInput')), name: INPUT_ROUTE_PREFIX + }, + { + title: resource.resourceToString($r('app.string.pageIndex_RichEditor')), + name: RICH_EDITOR_ROUTE_PREFIX + }, + { + title: resource.resourceToString($r('app.string.pageIndex_symbolGlyphSpan')), + name: SYMBOL_GLYPH_SPAN + }, + { + title: resource.resourceToString($r('app.string.pageIndex_PropertyString')), + name: PROPERTY_STRING_ROUTE_PREFIX + }, + { + title: resource.resourceToString($r('app.string.pageIndex_TextNDKUI')), + name: NDK_ROUTE_PREFIX } ]; @@ -37,6 +57,14 @@ function Destination(name: string) { TextDestination(name); } else if (name.startsWith(INPUT_ROUTE_PREFIX)) { TextInputDestination(name); + } else if (name.startsWith(RICH_EDITOR_ROUTE_PREFIX)) { + RichEditorDestination(name); + } else if (name.startsWith(SYMBOL_GLYPH_SPAN)) { + SymbolGlyphSpanDestination(name); + } else if (name.startsWith(PROPERTY_STRING_ROUTE_PREFIX)) { + PropertyStringDestination(name); + }else if (name.startsWith(NDK_ROUTE_PREFIX)) { + NDKDestination(name); } } @@ -93,4 +121,4 @@ struct Index { }) .navDestination(Destination) } -} +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/ndk/ListenTextBoxEvents.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/ndk/ListenTextBoxEvents.ets new file mode 100644 index 0000000000000000000000000000000000000000..ce81dd4ab61dc243e136f81cec83727d3d28cb5d --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/ndk/ListenTextBoxEvents.ets @@ -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. + */ + +import nativeNode from 'libentry.so'; +import { NodeContent } from '@kit.ArkUI'; + +@Entry +@Component +export struct ListenTextBoxEvents { + // 初始化NodeContent对象。 + private rootSlot = new NodeContent(); + + aboutToAppear(): void { + // 通过C-API创建节点,并添加到管理器nodeContent上 + nativeNode.createTextAreaNode(this.rootSlot); + } + + build() { + NavDestination() { + Column() { + Row() { + // 将NodeContent和ContentSlot占位组件绑定。 + ContentSlot(this.rootSlot) + }.layoutWeight(1) + } + .width('100%') + .height('100%') + }.title($r('app.string.ListenTextBoxEvents_NDK_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/ndk/TextDrawingDisplay.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/ndk/TextDrawingDisplay.ets new file mode 100644 index 0000000000000000000000000000000000000000..93eeefd62d1893a836bfd3e3d88950d66ad78995 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/ndk/TextDrawingDisplay.ets @@ -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. + */ + +import nativeNode from 'libentry.so'; +import { NodeContent } from '@kit.ArkUI'; + +@Entry +@Component +export struct TextDrawingDisplay { + // 初始化NodeContent对象。 + private rootSlot = new NodeContent(); + + aboutToAppear(): void { + // 通过C-API创建节点,并添加到管理器nodeContent上 + nativeNode.createNativeNode(this.rootSlot); + } + + build() { + NavDestination() { + Column() { + Row() { + // 将NodeContent和ContentSlot占位组件绑定。 + ContentSlot(this.rootSlot) + }.layoutWeight(1) + } + .width('100%') + .height('100%') + }.title($r('app.string.TextDrawingDisplay_NDK_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/ndk/index.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/ndk/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..d23cff77df6ffa3d4d156f6722cd9fa8dcdf794a --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/ndk/index.ets @@ -0,0 +1,75 @@ +/* + * 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 { ListenTextBoxEvents } from './ListenTextBoxEvents'; +import { TextDrawingDisplay } from './TextDrawingDisplay'; + +export const NDK_ROUTE_PREFIX: string = 'ndk'; + +const routes: Route[] = [ + { + name: `${NDK_ROUTE_PREFIX}/TextDrawingDisplay`, + title: resource.resourceToString($r('app.string.TextDrawingDisplay_NDK_title')), + description: $r('app.string.TextDrawingDisplay_NDK_desc') + }, + { + name: `${NDK_ROUTE_PREFIX}/ListenTextBoxEvents`, + title: resource.resourceToString($r('app.string.ListenTextBoxEvents_NDK_title')), + description: $r('app.string.ListenTextBoxEvents_NDK_desc') + } +]; + +@Builder +export function NDKDestination(name: string) { + if (name === NDK_ROUTE_PREFIX) { + NDKExample(); + } else if (name === routes[0].name) { + TextDrawingDisplay(); + } else if (name === routes[1].name) { + ListenTextBoxEvents(); + } +} + +@Entry +@Component +struct NDKExample { + @Consume pathStack: NavPathStack; + + build() { + NavDestination() { + List({ space: 12 }) { + ForEach(routes, (route: Route) => { + ListItem() { + CompletedRoutableCard({ title: route.title, description: route.description }) + } + .width('100%') + .onClick(() => { + this.pathStack.pushPath({ name: route.name }); + }) + }) + } + .contentStartOffset(56) + .padding({ left: 16, right: 16 }) + } + .backgroundColor('#f1f3f5') + .title($r('app.string.pageIndex_TextNDKUI'), { + backgroundBlurStyle: BlurStyle.COMPONENT_THICK, + barStyle: BarStyle.STACK + }) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/CreateApply.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/CreateApply.ets new file mode 100644 index 0000000000000000000000000000000000000000..6edcb481112deadf731e283604dc80101aeaa9e6 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/CreateApply.ets @@ -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. + */ + +import resource from '../../common/resource'; + +@Entry +@Component +struct styled_string_demo1 { + styledString1: StyledString = new StyledString(resource.resourceToString($r('app.string.CreateApply_Text_1'))); + mutableStyledString1: MutableStyledString = new MutableStyledString(resource.resourceToString($r('app.string.CreateApply_Text_2'))); + controller1: TextController = new TextController(); + controller2: TextController = new TextController(); + + async onPageShow() { + // 在生命周期onPageShow回调中绑定属性字符串 + this.controller1.setStyledString(this.styledString1); + } + + build() { + Column() { + // 显示属性字符串 + Text(undefined, { controller: this.controller1 }) + Text(undefined, { controller: this.controller2 }) + .onAppear(() => { + // 在组件onAppear回调中绑定属性字符串 + this.controller2.setStyledString(this.mutableStyledString1); + }) + } + .width('100%') + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringGestureStyle.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringGestureStyle.ets new file mode 100644 index 0000000000000000000000000000000000000000..11978543463ec3ed167bd1deb4d16c238a73acc7 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringGestureStyle.ets @@ -0,0 +1,148 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; +import { drawing } from '@kit.ArkGraphics2D'; + +let gUIContext: UIContext; + +class MyCustomSpan extends CustomSpan { + constructor(word: string, width: number, height: number, fontSize: number) { + super(); + this.word = word; + this.width = width; + this.height = height; + this.fontSize = fontSize; + } + + onMeasure(measureInfo: CustomSpanMeasureInfo): CustomSpanMetrics { + return { width: this.width, height: this.height }; + } + + onDraw(context: DrawContext, options: CustomSpanDrawInfo) { + let canvas = context.canvas; + + const brush = new drawing.Brush(); + brush.setColor({ + alpha: 255, + red: 0, + green: 0, + blue: 0 + }); + const font = new drawing.Font(); + font.setSize(gUIContext.vp2px(this.fontSize)); + const textBlob = + drawing.TextBlob.makeFromString(this.word.substring(0, 5), font, drawing.TextEncoding.TEXT_ENCODING_UTF8); + canvas.attachBrush(brush); + + this.onDrawRectByRadius(context, options.x, options.x + gUIContext.vp2px(this.width), options.lineTop, + options.lineBottom, 20); + brush.setColor({ + alpha: 255, + red: 255, + green: 255, + blue: 255 + }); + canvas.attachBrush(brush); + canvas.drawTextBlob(textBlob, options.x, options.lineBottom - 30); + brush.setColor({ + alpha: 255, + red: 255, + green: 228, + blue: 196 + }); + canvas.attachBrush(brush); + const textBlob1 = + drawing.TextBlob.makeFromString(this.word.substring(5), font, drawing.TextEncoding.TEXT_ENCODING_UTF8); + canvas.drawTextBlob(textBlob1, options.x + gUIContext.vp2px(100), options.lineBottom - 30); + + canvas.detachBrush(); + } + + onDrawRectByRadius(context: DrawContext, left: number, right: number, top: number, bottom: number, radius: number) { + let canvas = context.canvas; + let path = new drawing.Path(); + + // 画带radius的rect + path.moveTo(left + radius, top); + path.lineTo(right - radius, top); + path.arcTo(right - 2 * radius, top, right, top + 2 * radius, 270, 90); + path.lineTo(right, bottom - radius); + path.arcTo(right - 2 * radius, bottom - 2 * radius, right, bottom, 0, 90); + + path.lineTo(left + 2 * radius, bottom); + path.arcTo(left, bottom - 2 * radius, left + 2 * radius, bottom, 90, 90); + path.lineTo(left, top + 2 * radius); + path.arcTo(left, top, left + 2 * radius, top + 2 * radius, 180, 90); + + canvas.drawPath(path); + } + + setWord(word: string) { + this.word = word; + } + + public width: number = 160; + public word: string = 'drawing'; + public height: number = 10; + public fontSize: number = 16; +} + +@Entry +@Component +export struct StyledStringGestureStyle { + customSpan3: MyCustomSpan = new MyCustomSpan('99VIP88%off', 200, 40, 30); + textStyle: MutableStyledString = new MutableStyledString('123'); + textController: TextController = new TextController(); + isPageShow: boolean = true; + + aboutToAppear() { + gUIContext = this.getUIContext(); + } + + async onPageShow() { + if (!this.isPageShow) { + return; + } + this.isPageShow = false; + this.textController.setStyledString(new StyledString(this.customSpan3)); + } + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ title: $r('app.string.TStyledStringGestureStyle_title') }) { + // [Start styled_string_gesture_style] + Row() { + Column() { + Text(undefined, { controller: this.textController }) + .id('text1') + .copyOption(CopyOptions.InApp) + .fontSize(30) + } + .width('100%') + } + .height('100%') + // [End styled_string_gesture_style] + } + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.TStyledStringGestureStyle_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringHtml.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringHtml.ets new file mode 100644 index 0000000000000000000000000000000000000000..4d5eb81cf975b7867a933b584e01fc66ec7a0c8b --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringHtml.ets @@ -0,0 +1,98 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; +import { image } from '@kit.ImageKit'; +import { LengthMetrics } from '@kit.ArkUI'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct StyledStringHtml { + imagePixelMap: image.PixelMap | undefined = undefined; + @State html: string | undefined = undefined; + @State styledString: StyledString | undefined = undefined; + controller1: TextController = new TextController; + controller2: TextController = new TextController; + private uiContext: UIContext = this.getUIContext(); + + async aboutToAppear() { + console.info('aboutToAppear initial imagePixelMap'); + this.imagePixelMap = await this.getPixmapFromMedia($r('app.media.startIcon')); + } + + private async getPixmapFromMedia(resource: Resource) { + let unit8Array = await this.uiContext.getHostContext()?.resourceManager?.getMediaContent({ + bundleName: resource.bundleName, + moduleName: resource.moduleName, + id: resource.id + }); + let imageSource = image.createImageSource(unit8Array?.buffer.slice(0, unit8Array.buffer.byteLength)); + let createPixelMap: image.PixelMap = await imageSource.createPixelMap({ + desiredPixelFormat: image.PixelMapFormat.RGBA_8888 + }); + await imageSource.release(); + return createPixelMap; + } + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ title: $r('app.string.StyledStringHtml_title') }) { + // [Start styled_string_html] + Column() { + Text(undefined, { controller: this.controller1 }).height(100).id('text1') + Row() { + Button($r('app.string.StyledStringHtml_Button_1')).onClick(() => { + let mutableStyledString1: MutableStyledString = + new MutableStyledString(resource.resourceToString($r('app.string.StyledStringHtml_Text_1')), [{ + start: 0, + length: 6, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontColor: Color.Green, fontSize: LengthMetrics.px(50) }) + }]); + if (this.imagePixelMap !== undefined) { + let mutableStyledString2 = new MutableStyledString(new ImageAttachment({ + value: this.imagePixelMap, + size: { width: 50, height: 50 }, + })); + mutableStyledString1.appendStyledString(mutableStyledString2); + } + this.styledString = mutableStyledString1; + this.controller1.setStyledString(mutableStyledString1); + }).margin(5) + Button($r('app.string.StyledStringHtml_Button_2')).onClick(() => { + this.html = StyledString.toHtml(this.styledString); + }).margin(5) + Button($r('app.string.StyledStringHtml_Button_3')).onClick(async () => { + let styledString = await StyledString.fromHtml(this.html); + this.controller2.setStyledString(styledString); + }).margin(5) + } + + Text(undefined, { controller: this.controller2 }).height(100).id('text2') + Text(this.html).id('text3') + }.width('100%') + // [End styled_string_html] + } + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.StyledStringHtml_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringImageAttachment.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringImageAttachment.ets new file mode 100644 index 0000000000000000000000000000000000000000..c07afa4b0ae9e4d53971d006446482415e079f51 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringImageAttachment.ets @@ -0,0 +1,184 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; +import { image } from '@kit.ImageKit'; +import { LengthMetrics } from '@kit.ArkUI'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct StyledStringImageAttachment { + @State abled: boolean = true; + @State message: string = 'Hello World'; + imagePixelMap: image.PixelMap | undefined = undefined; + @State imagePixelMap3: image.PixelMap | undefined = undefined; + mutableStr: MutableStyledString = new MutableStyledString('123'); + controller: TextController = new TextController(); + mutableStr2: MutableStyledString = new MutableStyledString('This is set decoration line style to the mutableStr2', [{ + start: 0, + length: 15, + styledKey: StyledStringKey.DECORATION, + styledValue: new DecorationStyle({ + type: TextDecorationType.Overline, + color: Color.Orange, + style: TextDecorationStyle.DOUBLE + }) + }]); + + async aboutToAppear() { + console.info('aboutToAppear initial imagePixelMap'); + this.imagePixelMap = await this.getPixmapFromMedia($r('app.media.startIcon')); + } + + private async getPixmapFromMedia(resource: Resource) { + let unit8Array = await this.getUIContext().getHostContext()?.resourceManager?.getMediaContent({ + bundleName: resource.bundleName, + moduleName: resource.moduleName, + id: resource.id + }); + let imageSource = image.createImageSource(unit8Array?.buffer?.slice(0, unit8Array?.buffer?.byteLength)); + let createPixelMap: image.PixelMap = await imageSource.createPixelMap({ + desiredPixelFormat: image.PixelMapFormat.RGBA_8888 + }); + await imageSource.release(); + return createPixelMap; + } + + leadingMarginValue: ParagraphStyle = new ParagraphStyle({ leadingMargin: LengthMetrics.vp(5)}); + //行高样式对象 + lineHeightStyle1: LineHeightStyle= new LineHeightStyle(new LengthMetrics(24)); + //Bold样式 + boldTextStyle: TextStyle = new TextStyle({ fontWeight: FontWeight.Bold }); + //创建含段落样式的对象paragraphStyledString1 + paragraphStyledString1: MutableStyledString = + new MutableStyledString(resource.resourceToString($r('app.string.StyledStringImageAttachment_Text_1')), [ + { + start: 0, + length: 28, + styledKey: StyledStringKey.PARAGRAPH_STYLE, + styledValue: this.leadingMarginValue + }, + { + start: 14, + length: 9, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontSize: LengthMetrics.vp(14), fontColor: '#B22222' }) + }, + { + start: 24, + length: 4, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontSize: LengthMetrics.vp(14), fontWeight: FontWeight.Lighter }) + }, + { + start: 11, + length: 4, + styledKey: StyledStringKey.LINE_HEIGHT, + styledValue: this.lineHeightStyle1 + } + ]); + paragraphStyledString2: MutableStyledString = + new MutableStyledString(resource.resourceToString($r('app.string.StyledStringImageAttachment_Text_2')), [ + { + start: 0, + length: 5, + styledKey: StyledStringKey.PARAGRAPH_STYLE, + styledValue: this.leadingMarginValue + }, + { + start: 0, + length: 4, + styledKey: StyledStringKey.LINE_HEIGHT, + styledValue: new LineHeightStyle(new LengthMetrics(60)) + }, + { + start: 0, + length: 7, + styledKey: StyledStringKey.FONT, + styledValue: this.boldTextStyle + }, + { + start: 1, + length: 1, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontSize: LengthMetrics.vp(18) }) + }, + { + start: 2, + length: 2, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontSize: LengthMetrics.vp(36) }) + }, + { + start: 4, + length: 3, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontSize: LengthMetrics.vp(20) }) + }, + { + start: 7, + length: 9, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontColor: Color.Grey, fontSize: LengthMetrics.vp(14)}) + } + ]); + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ title: $r('app.string.StyledStringImageAttachment_title') }) { + // [Start styled_string_image_attachment] + Row() { + Column({ space: 10 }) { + Text(undefined, { controller: this.controller }) + .id('text1') + .copyOption(CopyOptions.InApp) + .draggable(true) + .backgroundColor('#FFFFFF') + .borderRadius(5) + + Button($r('app.string.StyledStringImageAttachment_Button_1')) + .enabled(this.abled) + .onClick(() => { + if (this.imagePixelMap !== undefined) { + this.mutableStr = new MutableStyledString(new ImageAttachment({ + value: this.imagePixelMap, + size: { width: 180, height: 160 }, + verticalAlign: ImageSpanAlignment.BASELINE, + objectFit: ImageFit.Fill + })); + this.paragraphStyledString1.appendStyledString(this.paragraphStyledString2); + this.mutableStr.appendStyledString(this.paragraphStyledString1); + this.controller.setStyledString(this.mutableStr); + } + this.abled = false; + }) + } + .width('100%') + } + .height('100%') + .backgroundColor('#F8F8FF') + // [End styled_string_image_attachment] + } + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.StyledStringImageAttachment_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringParagraphStyle.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringParagraphStyle.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4fd880165fd18ba4e55fd3819b8d0fe98948341 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringParagraphStyle.ets @@ -0,0 +1,106 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; +import { LengthMetrics } from '@kit.ArkUI'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct StyledStringParagraphStyle { + titleParagraphStyleAttr: ParagraphStyle = new ParagraphStyle({ textAlign: TextAlign.Center }); + //段落首行缩进15vp + paragraphStyleAttr1: ParagraphStyle = new ParagraphStyle({ textIndent: LengthMetrics.vp(15) }); + //行高样式对象 + lineHeightStyle1: LineHeightStyle= new LineHeightStyle(new LengthMetrics(24)); + //创建含段落样式的对象paragraphStyledString1 + paragraphStyledString1: MutableStyledString = + new MutableStyledString(resource.resourceToString($r('app.string.StyledStringParagraphStyle_Text_1')), [ + { + start: 0, + length: 4, + styledKey: StyledStringKey.PARAGRAPH_STYLE, + styledValue: this.titleParagraphStyleAttr + }, + { + start: 0, + length: 4, + styledKey: StyledStringKey.LINE_HEIGHT, + styledValue: new LineHeightStyle(new LengthMetrics(50)) + }, + { + start: 0, + length: 4, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontSize: LengthMetrics.vp(24), fontWeight: FontWeight.Bolder }) + }, + { + start: 5, + length: 3, + styledKey: StyledStringKey.PARAGRAPH_STYLE, + styledValue: this.paragraphStyleAttr1 + }, + { + start: 5, + length: 20, + styledKey: StyledStringKey.LINE_HEIGHT, + styledValue: this.lineHeightStyle1 + } + ]); + + //段落不设置缩进配置最大行数及超长显示方式 + paragraphStyleAttr3: ParagraphStyle = new ParagraphStyle({ + textAlign: TextAlign.End, + maxLines: 1, + wordBreak: WordBreak.BREAK_ALL, + overflow: TextOverflow.Ellipsis + }); + + controller: TextController = new TextController(); + + async onPageShow() { + this.controller.setStyledString(this.paragraphStyledString1); + } + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ title: $r('app.string.StyledStringParagraphStyle_title') }) { + // [Start styled_string_paragraph_style] + Column() { + Button($r('app.string.StyledStringParagraphStyle_Button_1')) + .onClick(() => { + this.paragraphStyledString1.replaceStyle({ + start: 5, + length: 3, + styledKey: StyledStringKey.PARAGRAPH_STYLE, + styledValue: this.paragraphStyleAttr3 + }); + this.controller.setStyledString(this.paragraphStyledString1); + }) + Text(undefined, { controller: this.controller }) + } + // [End styled_string_paragraph_style] + } + + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.StyledStringParagraphStyle_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringSceneExample.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringSceneExample.ets new file mode 100644 index 0000000000000000000000000000000000000000..60a3431b1bef0a10142e77e9cb291b7669ec8f20 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringSceneExample.ets @@ -0,0 +1,175 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; +import { LengthMetrics } from '@kit.ArkUI'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct StyledStringSceneExample { + alignCenterParagraphStyleAttr: ParagraphStyle = new ParagraphStyle({ textAlign: TextAlign.Center }); + //行高样式对象 + lineHeightStyle1: LineHeightStyle = new LineHeightStyle(LengthMetrics.vp(24)); + //Bold样式 + boldTextStyle: TextStyle = new TextStyle({ fontWeight: FontWeight.Bold }); + //创建含段落样式的对象paragraphStyledString1 + paragraphStyledString1: MutableStyledString = + new MutableStyledString(resource.resourceToString($r('app.string.StyledStringSceneExample_Text_1')), [ + { + start: 0, + length: 4, + styledKey: StyledStringKey.PARAGRAPH_STYLE, + styledValue: this.alignCenterParagraphStyleAttr + }, + { + start: 0, + length: 4, + styledKey: StyledStringKey.LINE_HEIGHT, + styledValue: new LineHeightStyle(LengthMetrics.vp(40)) + }, + { + start: 11, + length: 14, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontSize: LengthMetrics.vp(14), fontColor: Color.Grey }) + }, + { + start: 11, + length: 4, + styledKey: StyledStringKey.PARAGRAPH_STYLE, + styledValue: this.alignCenterParagraphStyleAttr + }, + { + start: 11, + length: 4, + styledKey: StyledStringKey.LINE_HEIGHT, + styledValue: this.lineHeightStyle1 + } + ]); + paragraphStyledString2: MutableStyledString = + new MutableStyledString(resource.resourceToString($r('app.string.StyledStringSceneExample_Text_2')), [ + { + start: 0, + length: 4, + styledKey: StyledStringKey.PARAGRAPH_STYLE, + styledValue: this.alignCenterParagraphStyleAttr + }, + { + start: 0, + length: 4, + styledKey: StyledStringKey.LINE_HEIGHT, + styledValue: new LineHeightStyle(LengthMetrics.vp(60)) + }, + { + start: 0, + length: 6, + styledKey: StyledStringKey.FONT, + styledValue: this.boldTextStyle + }, + { + start: 1, + length: 1, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontSize: LengthMetrics.vp(18) }) + }, + { + start: 2, + length: 4, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontSize: LengthMetrics.vp(40) }) + }, + { + start: 6, + length: 3, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontColor: Color.Grey, fontSize: LengthMetrics.vp(14) }) + }, + { + start: 6, + length: 3, + styledKey: StyledStringKey.DECORATION, + styledValue: new DecorationStyle({ type: TextDecorationType.LineThrough, color: Color.Grey }) + } + ]); + paragraphStyledString3: MutableStyledString = + new MutableStyledString(resource.resourceToString($r('app.string.StyledStringSceneExample_Text_3')), [ + { + start: 0, + length: 4, + styledKey: StyledStringKey.PARAGRAPH_STYLE, + styledValue: this.alignCenterParagraphStyleAttr + }, + { + start: 0, + length: 4, + styledKey: StyledStringKey.LINE_HEIGHT, + styledValue: new LineHeightStyle(LengthMetrics.vp(30)) + }, + { + start: 1, + length: 2, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontColor: '#FFD700', fontWeight: FontWeight.Bold }) + }, + { + start: 4, + length: 2, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontColor: '#FFD700', fontWeight: FontWeight.Bold }) + } + ]); + controller: TextController = new TextController(); + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ title: $r('app.string.StyledStringSceneExample_title') }) { + // [Start styled_string_scene_example] + Row() { + Column({ space: 5 }) { + Text(undefined, { controller: this.controller }) + .id('text1') + .width(240) + .copyOption(CopyOptions.InApp) + .draggable(true) + .onAppear(() => { + this.paragraphStyledString2.appendStyledString(this.paragraphStyledString3); + this.paragraphStyledString1.appendStyledString(this.paragraphStyledString2); + this.controller.setStyledString(this.paragraphStyledString1); + }) + + Button($r('app.string.StyledStringSceneExample_Button_1')) + .width(200) + .fontColor(Color.White) + .fontSize(18) + .backgroundColor('#3CB371') + .margin({ bottom: 10 }) + } + .borderWidth(1).borderColor('#FFDEAD') + .margin({ left: 10 }) + } + .height('60%') + // [End styled_string_scene_example] + } + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.StyledStringSceneExample_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringStyle.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringStyle.ets new file mode 100644 index 0000000000000000000000000000000000000000..683fbda11d832edaa62f9db8680052e37f252e8d --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/StyledStringStyle.ets @@ -0,0 +1,155 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; +import { LengthMetrics, LengthUnit } from '@kit.ArkUI'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct StyledStringStyle { + textStyleAttrs: TextStyle = new TextStyle({ + fontWeight: FontWeight.Bolder, + fontSize: LengthMetrics.vp(24), + fontStyle: FontStyle.Italic + }); + + mutableStyledString1: MutableStyledString = + new MutableStyledString(resource.resourceToString($r('app.string.StyledStringStyle_Text_1')), [ + { + start: 2, + length: 2, + styledKey: StyledStringKey.FONT, + styledValue: this.textStyleAttrs + }, + { + start: 7, + length: 4, + styledKey: StyledStringKey.FONT, + styledValue: new TextStyle({ fontColor: Color.Orange, fontSize: LengthMetrics.vp(12) }) + } + ]); + mutableStyledString2: MutableStyledString = + new MutableStyledString(resource.resourceToString($r('app.string.StyledStringStyle_Text_2')), [ + { + start: 0, + length: 3, + styledKey: StyledStringKey.TEXT_SHADOW, + styledValue: new TextShadowStyle({ + radius: 5, + type: ShadowType.COLOR, + color: Color.Red, + offsetX: 10, + offsetY: 10 + }) + } + ]); + mutableStyledString3: MutableStyledString = + new MutableStyledString(resource.resourceToString($r('app.string.StyledStringStyle_Text_3')), [ + { + start: 0, + length: 3, + styledKey: StyledStringKey.DECORATION, + styledValue: new DecorationStyle({ type: TextDecorationType.LineThrough, color: Color.Red }) + } + ]); + mutableStyledString4: MutableStyledString = + new MutableStyledString(resource.resourceToString($r('app.string.StyledStringStyle_Text_4')), [ + { + start: 0, + length: 3, + styledKey: StyledStringKey.BASELINE_OFFSET, + styledValue: new BaselineOffsetStyle(LengthMetrics.px(20)) + } + ]); + mutableStyledString5: MutableStyledString = + new MutableStyledString(resource.resourceToString($r('app.string.StyledStringStyle_Text_5')), [ + { + start: 8, + length: 3, + styledKey: StyledStringKey.LINE_HEIGHT, + styledValue: new LineHeightStyle(LengthMetrics.vp(50)) + } + ]); + mutableStyledString6: MutableStyledString = + new MutableStyledString(resource.resourceToString($r('app.string.StyledStringStyle_Text_6')), [ + { + start: 0, + length: 2, + styledKey: StyledStringKey.LETTER_SPACING, + styledValue: new LetterSpacingStyle(new LengthMetrics(20, LengthUnit.VP)) + } + ]); + + controller1: TextController = new TextController(); + controller2: TextController = new TextController(); + controller3: TextController = new TextController(); + controller4: TextController = new TextController(); + controller5: TextController = new TextController(); + controller6: TextController = new TextController(); + + async onPageShow() { + this.controller1.setStyledString(this.mutableStyledString1); + this.controller2.setStyledString(this.mutableStyledString2); + this.controller3.setStyledString(this.mutableStyledString3); + this.controller4.setStyledString(this.mutableStyledString4); + this.controller5.setStyledString(this.mutableStyledString5); + this.controller6.setStyledString(this.mutableStyledString6); + } + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ title: $r('app.string.StyledStringStyle_title_1') }) { + // [Start styled_string_text_style] + Text(undefined, { controller: this.controller1 }) + .id('1') + .margin({ top: 10 }) + // [End styled_string_text_style] + } + ComponentCard({ title: $r('app.string.StyledStringStyle_title_2') }) { + // [Start styled_string_text_shadow_style] + Text(undefined, { controller: this.controller2 }).id('2') + // [End styled_string_text_shadow_style] + } + ComponentCard({ title: $r('app.string.StyledStringStyle_title_3') }) { + // [Start styled_string_decoration_style] + Text(undefined, { controller: this.controller3 }).id('3') + // [End styled_string_decoration_style] + } + ComponentCard({ title: $r('app.string.StyledStringStyle_title_4') }) { + // [Start styled_string_baseline_offset_style] + Text(undefined, { controller: this.controller4 }).id('4') + // [End styled_string_baseline_offset_style] + } + ComponentCard({ title: $r('app.string.StyledStringStyle_title_5') }) { + // [Start styled_string_line_height_style] + Text(undefined, { controller: this.controller5 }).id('5') + // [End styled_string_line_height_style] + } + ComponentCard({ title: $r('app.string.StyledStringStyle_title_6') }) { + // [Start styled_string_letter_spacing_style] + Text(undefined, { controller: this.controller6 }).id('6') + // [End styled_string_letter_spacing_style] + } + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.StyledStringStyle_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/index.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..69a07844fb1c415d572492ccc8bb77d82e6a6758 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/propertyString/index.ets @@ -0,0 +1,105 @@ +/* + * 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 { Route } from '../../common/Route'; +import resource from '../../common/resource'; +import { router } from '@kit.ArkUI'; + +export const PROPERTY_STRING_ROUTE_PREFIX: string = 'propertyString'; + +const routes: Route[] = [ + { + name: `${PROPERTY_STRING_ROUTE_PREFIX}/CreateApply`, + title: resource.resourceToString($r('app.string.Create_Apply_StyledString_MutableStyledString_title')), + description: $r('app.string.Create_Apply_StyledString_MutableStyledString_desc') + }, + { + name: `${PROPERTY_STRING_ROUTE_PREFIX}/StyledStringStyle`, + title: resource.resourceToString($r('app.string.StyledStringStyle_title')), + description: $r('app.string.StyledStringStyle_description') + }, + { + name: `${PROPERTY_STRING_ROUTE_PREFIX}/StyledStringParagraphStyle`, + title: resource.resourceToString($r('app.string.StyledStringParagraphStyle_title')), + description: $r('app.string.StyledStringParagraphStyle_description') + }, + { + name: `${PROPERTY_STRING_ROUTE_PREFIX}/StyledStringImageAttachment`, + title: resource.resourceToString($r('app.string.StyledStringImageAttachment_title')), + description: $r('app.string.StyledStringImageAttachment_description') + }, + { + name: `${PROPERTY_STRING_ROUTE_PREFIX}/StyledStringGestureStyle`, + title: resource.resourceToString($r('app.string.TStyledStringGestureStyle_title')), + description: $r('app.string.StyledStringGestureStyle_description') + }, + { + name: `${PROPERTY_STRING_ROUTE_PREFIX}/StyledStringHtml`, + title: resource.resourceToString($r('app.string.StyledStringHtml_title')), + description: $r('app.string.StyledStringHtml_description') + }, + { + name: `${PROPERTY_STRING_ROUTE_PREFIX}/StyledStringSceneExample`, + title: resource.resourceToString($r('app.string.StyledStringSceneExample_title')), + description: $r('app.string.StyledStringSceneExample_description') + } +]; + +@Builder +export function PropertyStringDestination(name: string) { + if (name === PROPERTY_STRING_ROUTE_PREFIX) { + PropertyStringExample(); + } +} + +@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'); + }) + } + + build() { + NavDestination() { + 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 }) + } + .backgroundColor('#f1f3f5') + .title('propertyString', { + backgroundBlurStyle: BlurStyle.COMPONENT_THICK, + barStyle: BarStyle.STACK + }) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddBuilderDecoratorContent.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddBuilderDecoratorContent.ets new file mode 100644 index 0000000000000000000000000000000000000000..c14e3958ff5c93fc6c6b0a00aa35bed85c134086 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddBuilderDecoratorContent.ets @@ -0,0 +1,74 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct AddBuilderDecoratorContent { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + private myBuilder: CustomBuilder = undefined + + @Builder + TextBuilder() { + Row() { + Image($r('app.media.startIcon')).width(50).height(50).margin(16) + Column() { + Text($r('app.string.AddBuilderDecoratorContent_Text_1')).fontWeight(FontWeight.Bold).fontSize(16) + Text($r('app.string.AddBuilderDecoratorContent_Text_2')).fontColor('#8a8a8a').fontSize(12) + }.alignItems(HorizontalAlign.Start) + }.backgroundColor('#f4f4f4') + .borderRadius('20') + .width(220) + } + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard() { + Column({ space: 3 }) { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan( + resource.resourceToString($r('app.string.AddBuilderDecoratorContent_Text_3')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + Button($r('app.string.AddBuilderDecoratorContent_Button_1'), { + buttonStyle: ButtonStyleMode.NORMAL + }) + .height(30) + .fontSize(13) + .onClick(() => { + this.myBuilder = () => { + this.TextBuilder() + } + this.controller.addBuilderSpan(this.myBuilder) + }) + } + } + } + .width('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.Add_Builder_DecoratorContent_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddEvent.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddEvent.ets new file mode 100644 index 0000000000000000000000000000000000000000..78d87d697e47681cdfba5ac5e5efa89633d1ac7e --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddEvent.ets @@ -0,0 +1,385 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; +import { pasteboard } from '@kit.BasicServicesKit'; +import resource from '../../common/resource'; + +@Component +struct event1 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + controller1: RichEditorController = new RichEditorController(); + options1: RichEditorOptions = { controller: this.controller1 }; + + build() { + Column() { + ComponentCard({ + title: $r('app.string.Add_Event_title_1'), + description: $r('app.string.Add_Event_title_1_desc') + }) { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.AddEvent_Text_1')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + } + } + } +} + +@Component +struct event2 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + controller1: RichEditorController = new RichEditorController(); + options1: RichEditorOptions = { controller: this.controller1 }; + + build() { + Column() { + ComponentCard({ + title: $r('app.string.Add_Event_title_2'), + description: $r('app.string.Add_Event_title_2_desc'), + }) { + Column({ space: 3 }) { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.AddEvent_Text_2')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + .onSelectionChange((value: RichEditorRange) => { + this.controller1.addTextSpan('\n' + resource.resourceToString($r('app.string.AddEvent_Text_3')) + + value.start + ',' + value.end + ')', { + style: { + fontColor: Color.Gray, + fontSize: 10 + } + }) + }) + .width(300) + .height(50) + Text(resource.resourceToString($r('app.string.AddEvent_Text_4'))).fontSize(10).fontColor(Color.Gray).width(300) + RichEditor(this.options1) + .width(300) + .height(70) + } + } + } + } +} + +@Component +struct event3 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + controller1: RichEditorController = new RichEditorController(); + options1: RichEditorOptions = { controller: this.controller1 }; + + build() { + Column() { + ComponentCard({ + title: $r('app.string.Add_Event_title_3'), + description: $r('app.string.Add_Event_title_3_desc') + }) { + Column({ space: 3 }) { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.AddEvent_Text_5')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + .onWillChange((value: RichEditorChangeValue) => { + this.controller1.addTextSpan(resource.resourceToString($r('app.string.AddEvent_Text_6')) + + JSON.stringify(value), { + style: { + fontColor: Color.Gray, + fontSize: 10 + } + }) + return true; + }) + .onDidChange((rangeBefore: TextRange, rangeAfter: TextRange) => { + this.controller1.addTextSpan(resource.resourceToString($r('app.string.AddEvent_Text_7')) + + JSON.stringify(rangeBefore) + '\nrangeAfter:' + JSON.stringify(rangeBefore), { + style: { + fontColor: Color.Gray, + fontSize: 10 + } + }) + }) + .width(300) + .height(50) + Text(resource.resourceToString($r('app.string.AddEvent_Text_4'))).fontSize(10).fontColor(Color.Gray).width(300) + RichEditor(this.options1) + .width(300) + .height(70) + } + } + } + } +} + +@Component +struct event4 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + controller1: RichEditorController = new RichEditorController(); + options1: RichEditorOptions = { controller: this.controller1 }; + + build() { + Column() { + ComponentCard({ + title: $r('app.string.Add_Event_title_4'), + description: $r('app.string.Add_Event_title_4_desc'), + }) { + Column({ space: 3 }) { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.AddEvent_Text_8')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + .aboutToIMEInput((value: RichEditorInsertValue) => { + this.controller1.addTextSpan(resource.resourceToString($r('app.string.AddEvent_Text_9')) + + JSON.stringify(value), { + style: { + fontColor: Color.Gray, + fontSize: 10 + } + }) + return true; + }) + .onDidIMEInput((value: TextRange) => { + this.controller1.addTextSpan(resource.resourceToString($r('app.string.AddEvent_Text_10')) + + JSON.stringify(value), { + style: { + fontColor: Color.Gray, + fontSize: 10 + } + }) + }) + .width(300) + .height(50) + Text(resource.resourceToString($r('app.string.AddEvent_Text_4'))).fontSize(10).fontColor(Color.Gray).width(300) + RichEditor(this.options1) + .width(300) + .height(70) + } + } + } + } +} + +@Component +struct event5 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + controller1: RichEditorController = new RichEditorController(); + options1: RichEditorOptions = { controller: this.controller1 }; + + PopDataFromPasteboard() { + let selection = this.controller.getSelection(); + let start = selection.selection[0]; + let end = selection.selection[1]; + if (start == end) { + start = this.controller.getCaretOffset(); + end = this.controller.getCaretOffset(); + } + let moveOffset = 0; + let sysBoard = pasteboard.getSystemPasteboard(); + sysBoard.getData((err, data) => { + if (err) { + return; + } + if (start != end) { + this.controller.deleteSpans({ start: start, end: end }) + } + let count = data.getRecordCount(); + for (let i = 0; i < count; i++) { + const element = data.getRecord(i); + if (element && element.plainText && element.mimeType === pasteboard.MIMETYPE_TEXT_PLAIN) { + this.controller.addTextSpan(element.plainText, + { + style: { fontSize: 26, fontColor: Color.Red }, + offset: start + moveOffset + } + ) + moveOffset += element.plainText.length; + } + } + this.controller.setCaretOffset(start + moveOffset) + }) + } + + build() { + Column() { + ComponentCard({ + title: $r('app.string.Add_Event_title_5'), + description: $r('app.string.Add_Event_title_5_desc') + }) { + Column({ space: 3 }) { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.AddEvent_Text_11')), + { style: { fontColor: Color.Black, fontSize: 15 } }) + }) + .onPaste((event) => { + this.controller1.addTextSpan(resource.resourceToString($r('app.string.AddEvent_Text_12')), + { style: { fontColor: Color.Gray, fontSize: 10 } }) + if (event != undefined && event.preventDefault) { + event.preventDefault(); + } + console.info('RichEditor onPaste') + this.PopDataFromPasteboard() + }) + .width(300) + .height(50) + Text(resource.resourceToString($r('app.string.AddEvent_Text_4'))).fontSize(10).fontColor(Color.Gray).width(300) + RichEditor(this.options1) + .width(300) + .height(70) + }.width('100%').alignItems(HorizontalAlign.Start) + } + } + } +} + +@Component +struct event6 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + controller1: RichEditorController = new RichEditorController(); + options1: RichEditorOptions = { controller: this.controller1 }; + + build() { + Column() { + ComponentCard({ + title: $r('app.string.Add_Event_title_6'), + description: $r('app.string.Add_Event_title_6_desc') + }) { + Column({ space: 3 }) { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.AddEvent_Text_13')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + .onCut(() => { + this.controller1.addTextSpan(resource.resourceToString($r('app.string.AddEvent_Text_14')), { + style: { + fontColor: Color.Gray, + fontSize: 10 + } + }) + }) + .width(300) + .height(50) + Text(resource.resourceToString($r('app.string.AddEvent_Text_4'))).fontSize(10).fontColor(Color.Gray).width(300) + RichEditor(this.options1) + .width(300) + .height(70) + } + } + } + } +} + +@Component +struct event7 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + controller1: RichEditorController = new RichEditorController(); + options1: RichEditorOptions = { controller: this.controller1 }; + + build() { + Column() { + ComponentCard({ + title: $r('app.string.Add_Event_title_7'), + description: $r('app.string.Add_Event_title_7') + }) { + Column({ space: 3 }) { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.AddEvent_Text_15')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + .onCopy(() => { + this.controller1.addTextSpan(resource.resourceToString($r('app.string.AddEvent_Text_16')), { + style: { + fontColor: Color.Gray, + fontSize: 10 + } + }) + }) + .width(300) + .height(50) + Text(resource.resourceToString($r('app.string.AddEvent_Text_4'))).fontSize(10).fontColor(Color.Gray).width(300) + RichEditor(this.options1) + .width(300) + .height(70) + } + } + } + } +} + +@Entry +@Component +export struct AddEvent { + scroller: Scroller = new Scroller(); + + build() { + NavDestination() { + Scroll(this.scroller) { + Column({ space: 12 }) { + event1(); + event2(); + event3(); + event4(); + event5(); + event6(); + event7(); + // tmp(); + + } + .width('100%') + .padding({ left: 12, right: 12 }) + }.id('scroll_') + } + .backgroundColor('#f1f2f3') + .title($r('app.string.Add_Event_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddImageContent.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddImageContent.ets new file mode 100644 index 0000000000000000000000000000000000000000..125a03d960a5787237d173100fdc02fda2fc1b8a --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddImageContent.ets @@ -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. + */ + +import { ComponentCard } from '../../common/Card'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct AddImageContent { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard() { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.AddImageContent_Text_1')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + .width(300) + .height(100) + Button($r('app.string.AddImageContent_Button_1'), { + buttonStyle: ButtonStyleMode.NORMAL + }) + .height(30) + .fontSize(13) + .onClick(() => { + this.controller.addImageSpan($r('app.media.startIcon'), { + imageStyle: { + size: ['57px', '57px'] + } + }) + }) + } + } + .width('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.Add_ImageContent_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddSymbolSpanContent.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddSymbolSpanContent.ets new file mode 100644 index 0000000000000000000000000000000000000000..e86404b6443b13e4bbbdf8010f336180cba8dd50 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddSymbolSpanContent.ets @@ -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. + */ + +import { ComponentCard } from '../../common/Card'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct AddSymbolSpanContent { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard() { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.AddSymbolSpanContent_Text_1')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + .width(300) + .height(100) + Button($r('app.string.AddSymbolSpanContent_Button_1'), { + buttonStyle: ButtonStyleMode.NORMAL + }) + .height(30) + .fontSize(13) + .onClick(() => { + this.controller.addSymbolSpan($r('sys.symbol.basketball_fill'), { + style: { + fontSize: 30 + } + }) + }) + } + } + .width('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.Add_SymbolSpanContent_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddTextContent.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddTextContent.ets new file mode 100644 index 0000000000000000000000000000000000000000..9e8c0663c0c75b401a22f69f4323c81ca80f1105 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/AddTextContent.ets @@ -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. + */ + +import { ComponentCard } from '../../common/Card'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct AddTextContent { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard() { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.AddTextContent_Text_1')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + .border({ width: 1, color: Color.Gray }) + .constraintSize({ + maxHeight: 100 + }) + .width(300) + .margin(10) + Button($r('app.string.AddTextContent_Button_1'), { + buttonStyle: ButtonStyleMode.NORMAL + }) + .height(30) + .fontSize(13) + .onClick(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.AddTextContent_Text_2'))) + }) + } + } + .width('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.Add_TextContent_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/BackplaneHighlighting.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/BackplaneHighlighting.ets new file mode 100644 index 0000000000000000000000000000000000000000..56b4e3e79bc71b039d306210a04e35c4346435e3 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/BackplaneHighlighting.ets @@ -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. + */ + +import { ComponentCard } from '../../common/Card'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct BackplaneHighlighting { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard() { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.BackplaneHighlighting_Text_1')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + .width(300) + .height(60) + Button($r('app.string.BackplaneHighlighting_Button_1'), { + buttonStyle: ButtonStyleMode.NORMAL + }) + .height(30) + .fontSize(13) + .onClick(() => { + this.controller.setSelection(0, 2) + }) + } + } + .width('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.Backplane_Highlighting_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/CreateRichEditor.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/CreateRichEditor.ets new file mode 100644 index 0000000000000000000000000000000000000000..ba5d5cace309235a83e8227a7b5c1ab77b80f1eb --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/CreateRichEditor.ets @@ -0,0 +1,76 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct CreateRichEditor { + controllerNoStyledString: RichEditorController = new RichEditorController(); + optionsNoStyledString: RichEditorOptions = { controller: this.controllerNoStyledString }; + fontStyle: TextStyle = new TextStyle({ + fontColor: Color.Pink + }); + // 定义字体样式对象 + + mutableStyledString: MutableStyledString = + new MutableStyledString(resource.resourceToString($r('app.string.CreateRichEditor_Text_1')), + [{ + start: 0, + length: 5, + styledKey: StyledStringKey.FONT, + styledValue: this.fontStyle + }]); + // 创建属性字符串 + + controller: RichEditorStyledStringController = new RichEditorStyledStringController(); + options: RichEditorStyledStringOptions = { controller: this.controller }; + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ + title: $r('app.string.Create_RichEditor_Component_title_1') + }) { + RichEditor(this.options) + .onReady(() => { + this.controller.setStyledString(this.mutableStyledString); + }) + } + + ComponentCard({ + title: $r('app.string.Create_RichEditor_Component_title_2'), + }) { + RichEditor(this.optionsNoStyledString) + .onReady(() => { + this.controllerNoStyledString.addTextSpan( + resource.resourceToString($r('app.string.CreateRichEditor_Text_2')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + } + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.Create_RichEditor_Component_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/GetGraphicInfoInComponent.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/GetGraphicInfoInComponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..e7068bb172891b4e0b6e3fe168bafae978510cbf --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/GetGraphicInfoInComponent.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. + */ + +import { ComponentCard } from '../../common/Card'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct GetGraphicInfoInComponent { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + controller1: RichEditorController = new RichEditorController(); + options1: RichEditorOptions = { controller: this.controller1 } + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard() { + Column({ space: 3 }) { + // 创建两个富文本组件 + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan( + resource.resourceToString($r('app.string.GetGraphicInfoInComponent_Text_1')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + .width(300) + .height(50) + Text($r('app.string.GetGraphicInfoInComponent_Text_1')).fontSize(10).fontColor(Color.Gray).width(300) + RichEditor(this.options1) + .width(300) + .height(50) + Button($r('app.string.GetGraphicInfoInComponent_Button_1'), { + buttonStyle: ButtonStyleMode.NORMAL + }) + .height(30) + .fontSize(13) + .onClick(() => { + this.controller1.addTextSpan(JSON.stringify(this.controller.getSpans()), { + style: { + fontColor: Color.Gray, + fontSize: 10 + } + }) + }) + } + } + } + .width('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.Get_GraphicInfo_In_Component_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/SetAttributes.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/SetAttributes.ets new file mode 100644 index 0000000000000000000000000000000000000000..0a6fd09c61692cca609d132ea8daafd02d7031d5 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/SetAttributes.ets @@ -0,0 +1,288 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; +import resource from '../../common/resource'; + +// 自定义SelectionMenuTheme接口 +export interface SelectionMenuTheme { + imageSize: number; + buttonSize: number; + menuSpacing: number; + editorOptionMargin: number; + expandedOptionPadding: number; + defaultMenuWidth: number; + imageFillColor: Resource; + backGroundColor: Resource; + iconBorderRadius: Resource; + containerBorderRadius: Resource; + cutIcon: Resource; + copyIcon: Resource; + pasteIcon: Resource; + selectAllIcon: Resource; + shareIcon: Resource; + translateIcon: Resource; + searchIcon: Resource; + arrowDownIcon: Resource; + iconPanelShadowStyle: ShadowStyle; + iconFocusBorderColor: Resource; +} + +// 定义defaultTheme变量 +export const defaultTheme: SelectionMenuTheme = { + imageSize: 24, + buttonSize: 48, + menuSpacing: 8, + editorOptionMargin: 1, + expandedOptionPadding: 3, + defaultMenuWidth: 256, + imageFillColor: $r('sys.color.ohos_id_color_primary'), + backGroundColor: $r('sys.color.ohos_id_color_dialog_bg'), + iconBorderRadius: $r('sys.float.ohos_id_corner_radius_default_m'), + containerBorderRadius: $r('sys.float.ohos_id_corner_radius_card'), + cutIcon: $r('sys.media.ohos_ic_public_cut'), + copyIcon: $r('sys.media.ohos_ic_public_copy'), + pasteIcon: $r('sys.media.ohos_ic_public_paste'), + selectAllIcon: $r('sys.media.ohos_ic_public_select_all'), + shareIcon: $r('sys.media.ohos_ic_public_share'), + translateIcon: $r('sys.media.ohos_ic_public_translate_c2e'), + searchIcon: $r('sys.media.ohos_ic_public_search_filled'), + arrowDownIcon: $r('sys.media.ohos_ic_public_arrow_down'), + iconPanelShadowStyle: ShadowStyle.OUTER_DEFAULT_MD, + iconFocusBorderColor: $r('sys.color.ohos_id_color_focused_outline'), +} + +@Component +struct attr1 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + sliderShow: boolean = false; + private theme: SelectionMenuTheme = defaultTheme; + + @Builder + SystemMenu() { + Column() { + Menu() { + if (this.controller) { + MenuItemGroup() { + MenuItem({ + startIcon: this.theme.cutIcon, + content: resource.resourceToString($r('app.string.SetAttributes_Text_1')), + labelInfo: 'Ctrl+X' + }) + MenuItem({ + startIcon: this.theme.copyIcon, + content: resource.resourceToString($r('app.string.SetAttributes_Text_2')), + labelInfo: 'Ctrl+C' + }) + MenuItem({ + startIcon: this.theme.pasteIcon, + content: resource.resourceToString($r('app.string.SetAttributes_Text_3')), + labelInfo: 'Ctrl+V' + }) + } + } + } + .radius(this.theme.containerBorderRadius) + .clip(true) + .backgroundColor(Color.White) + .width(this.theme.defaultMenuWidth) + } + .width(this.theme.defaultMenuWidth) + } + + build() { + Column() { + ComponentCard({ + title: $r('app.string.Set_Attributes_title_1'), + description: $r('app.string.Set_Attributes_title_1_desc'), + }) { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.SetAttributes_Text_4')), { + style: { + fontColor: Color.Black, + fontSize: 18 + } + }) + }) + .bindSelectionMenu(RichEditorSpanType.TEXT, this.SystemMenu, ResponseType.LongPress, { + onDisappear: () => { + this.sliderShow = false + } + }) + // 绑定自定义菜单 + .width(300) + .height(300) + } + } + } +} + +@Component +struct attr2 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + + build() { + Column() { + ComponentCard({ + title: $r('app.string.Set_Attributes_title_2'), + description: $r('app.string.Set_Attributes_title_2_desc') + }) { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.SetAttributes_Text_5')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + .caretColor(Color.Orange) + .width(300) + .height(300) + } + } + } +} + +@Component +struct attr3 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + + build() { + Column() { + ComponentCard({ + title: $r('app.string.Set_Attributes_title_3'), + description: $r('app.string.Set_Attributes_title_3_desc') + }) { + RichEditor(this.options) + .placeholder(resource.resourceToString($r('app.string.SetAttributes_Text_6')), { + fontColor: Color.Gray, + font: { + size: 15, + weight: FontWeight.Normal, + family: 'HarmonyOS Sans', + style: FontStyle.Normal + } + }) + .width(300) + .height(50) + } + } + } +} + +@Component +struct attr4 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + + build() { + Column() { + ComponentCard({ + title: $r('app.string.Set_Attributes_title_4'), + description: $r('app.string.Set_Attributes_title_4_desc') + }) { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.SetAttributes_Text_7')), + { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + .maxLines(2) + } + } + } +} + +@Component +struct attr5 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + + build() { + Column() { + ComponentCard({ + title: $r('app.string.Set_Attributes_title_5'), + description: $r('app.string.Set_Attributes_title_5_desc') + }) { + RichEditor(this.options) + .placeholder(resource.resourceToString($r('app.string.SetAttributes_Text_8'))) + .onReady(() => { + }) + .maxLength(7) + } + } + } +} + +@Component +struct attr6 { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + + build() { + Column() { + ComponentCard({ + title: $r('app.string.Set_Attributes_title_6'), + description: $r('app.string.Set_Attributes_title_6_desc') + }) { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.SetAttributes_Text_9')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + } + } + } +} + +@Entry +@Component +export struct SetAttributes { + scroller: Scroller = new Scroller(); + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + + build() { + NavDestination() { + Scroll(this.scroller) { + Column({ space: 12 }) { + attr1(); + attr2(); + attr3(); + attr4(); + attr5(); + attr6(); + } + .width('100%') + .padding({ left: 12, right: 12 }) + }.id('scroll_') + } + .backgroundColor('#f1f2f3') + .title($r('app.string.Set_Attributes_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/SetUserPresetTextStyles.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/SetUserPresetTextStyles.ets new file mode 100644 index 0000000000000000000000000000000000000000..46fea9e75b6b6f47d09d579284eb647080ad1ad7 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/SetUserPresetTextStyles.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. + */ + +import { ComponentCard } from '../../common/Card'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct SetUserPresetTextStyles { + controller: RichEditorController = new RichEditorController(); + options: RichEditorOptions = { controller: this.controller }; + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard() { + RichEditor(this.options) + .onReady(() => { + this.controller.addTextSpan(resource.resourceToString($r('app.string.SetUserPresetTextStyles_Text_1')), { + style: { + fontColor: Color.Black, + fontSize: 15 + } + }) + }) + .width(300) + .height(60) + Button($r('app.string.SetUserPresetTextStyles_Button_1'), { + buttonStyle: ButtonStyleMode.NORMAL + }) + .height(30) + .fontSize(13) + .onClick(() => { + this.controller.setTypingStyle({ + fontWeight: 'medium', + fontColor: Color.Pink, + fontSize: 15, + fontStyle: FontStyle.Italic, + decoration: { + type: TextDecorationType.Underline, + color: Color.Gray + } + }) + }) + } + } + .width('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.Set_User_PresetText_Styles_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/index.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..9ebb6185c758c145dcb3311b059f80d5661d77d9 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/richEditor/index.ets @@ -0,0 +1,139 @@ +/* + * 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 { Route } from '../../common/Route'; +import resource from '../../common/resource'; +import { CreateRichEditor } from './CreateRichEditor'; +import { SetAttributes } from './SetAttributes'; +import { AddEvent } from './AddEvent'; +import { SetUserPresetTextStyles } from './SetUserPresetTextStyles'; +import { BackplaneHighlighting } from './BackplaneHighlighting'; +import { AddTextContent } from './AddTextContent'; +import { AddImageContent } from './AddImageContent'; +import { AddBuilderDecoratorContent } from './AddBuilderDecoratorContent'; +import { AddSymbolSpanContent } from './AddSymbolSpanContent'; +import { GetGraphicInfoInComponent } from './GetGraphicInfoInComponent'; + +export const RICH_EDITOR_ROUTE_PREFIX: string = 'RichEditor'; + +const routes: Route[] = [ + { + name: `${RICH_EDITOR_ROUTE_PREFIX}/CreateRichEditor`, + title: resource.resourceToString($r('app.string.Create_RichEditor_Component_title')), + description: $r('app.string.Create_RichEditor_Component_description') + }, + { + name: `${RICH_EDITOR_ROUTE_PREFIX}/SetAttributes`, + title: resource.resourceToString($r('app.string.Set_Attributes_title')), + }, + { + name: `${RICH_EDITOR_ROUTE_PREFIX}/AddEvent`, + title: resource.resourceToString($r('app.string.Add_Event_title')), + }, + { + name: `${RICH_EDITOR_ROUTE_PREFIX}/SetUserPresetTextStyles`, + title: resource.resourceToString($r('app.string.Set_User_PresetText_Styles_title')), + description: $r('app.string.Set_User_PresetText_Styles_desc') + }, + { + name: `${RICH_EDITOR_ROUTE_PREFIX}/BackplaneHighlighting`, + title: resource.resourceToString($r('app.string.Backplane_Highlighting_title')), + description: $r('app.string.Backplane_Highlighting_desc') + }, + { + name: `${RICH_EDITOR_ROUTE_PREFIX}/AddTextContent`, + title: resource.resourceToString($r('app.string.Add_TextContent_title')), + description: $r('app.string.Add_TextContent_desc') + }, + { + name: `${RICH_EDITOR_ROUTE_PREFIX}/AddImageContent`, + title: resource.resourceToString($r('app.string.Add_ImageContent_title')), + description: $r('app.string.Add_ImageContent_desc') + }, + { + name: `${RICH_EDITOR_ROUTE_PREFIX}/AddBuilderDecoratorContent`, + title: resource.resourceToString($r('app.string.Add_Builder_DecoratorContent_title')), + description: $r('app.string.Add_Builder_DecoratorContent_desc') + }, + { + name: `${RICH_EDITOR_ROUTE_PREFIX}/AddSymbolSpanContent`, + title: resource.resourceToString($r('app.string.Add_SymbolSpanContent_title')), + description: $r('app.string.Add_SymbolSpanContent_desc') + }, + { + name: `${RICH_EDITOR_ROUTE_PREFIX}/GetGraphicInfoInComponent`, + title: resource.resourceToString($r('app.string.Get_GraphicInfo_In_Component_title')), + description: $r('app.string.Get_GraphicInfo_In_Component_desc') + } +]; + +@Builder +export function RichEditorDestination(name: string) { + if (name === RICH_EDITOR_ROUTE_PREFIX) { + RichEditorExample(); + } else if (name === routes[0].name) { + CreateRichEditor(); + } else if (name === routes[1].name) { + SetAttributes(); + } else if (name === routes[2].name) { + AddEvent(); + } else if (name === routes[3].name) { + SetUserPresetTextStyles(); + } else if (name === routes[4].name) { + BackplaneHighlighting(); + } else if (name === routes[5].name) { + AddTextContent(); + } else if (name === routes[6].name) { + AddImageContent(); + } else if (name === routes[7].name) { + AddBuilderDecoratorContent(); + } else if (name === routes[8].name) { + AddSymbolSpanContent(); + } else if (name === routes[9].name) { + GetGraphicInfoInComponent(); + } +} + +@Entry +@Component +struct RichEditorExample { + @Consume pathStack: NavPathStack; + + build() { + NavDestination() { + Scroll() { + List({ space: 12 }) { + ForEach(routes, (route: Route) => { + ListItem() { + CompletedRoutableCard({ title: route.title, description: route.description }) + } + .width('100%') + .onClick(() => { + this.pathStack.pushPath({ name: route.name }); + }) + }) + } + .contentStartOffset(56) + .padding({ left: 16, right: 16 }) + }.id('scroll_') + } + .backgroundColor('#f1f3f5') + .title('RichEditor', { + backgroundBlurStyle: BlurStyle.COMPONENT_THICK, + barStyle: BarStyle.STACK + }) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/CreatSymbolGlyph.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/CreatSymbolGlyph.ets new file mode 100644 index 0000000000000000000000000000000000000000..f8ebd2ab2859b865f036a8de8885d5e69d27c479 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/CreatSymbolGlyph.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. + */ + +import { ComponentCard } from '../../common/Card'; + +@Entry +@Component +export struct CreatSymbolGlyph { + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ title: $r('app.string.CreatSymbolGlyph_title') }) { + // [Start creat_symbol_glyph] + SymbolGlyph($r('sys.symbol.ohos_folder_badge_plus')) + .fontSize(96) + .renderingStrategy(SymbolRenderingStrategy.SINGLE) + .fontColor([Color.Black, Color.Green, Color.White]) + // [End creat_symbol_glyph] + } + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.CreatSymbolGlyph_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/SymbolAddEvent.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/SymbolAddEvent.ets new file mode 100644 index 0000000000000000000000000000000000000000..87d8cdc917e8a64c284962e1f1d00920b6309430 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/SymbolAddEvent.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. + */ + +import { ComponentCard } from '../../common/Card'; + +@Entry +@Component +export struct SymbolGlyphSpanAddEvent { + @State wifiColor: ResourceColor = Color.Black; + + build() { + NavDestination() { + Column({ space: 12 }) { + 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(() => { + this.wifiColor = Color.Gray; + }) + // [End symbol_glyph_span_add_event] + } + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.SymbolGlyphSpanAddEvent_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/SymbolAddToText.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/SymbolAddToText.ets new file mode 100644 index 0000000000000000000000000000000000000000..8faacdae9e0a4d7863d6239fe7e3e8a3b6bab99d --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/SymbolAddToText.ets @@ -0,0 +1,221 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; + +@Entry +@Component +export struct SymbolGlyphSpanAddToText { + scroller: Scroller = new Scroller(); + + build() { + NavDestination() { + Scroll(this.scroller) { + Column({ space: 12 }) { + ComponentCard({ title: $r('app.string.SymbolGlyphSpanAddToText_title_1') }) { + // [Start creat_symbol_span] + Text() { + SymbolSpan($r('sys.symbol.ohos_trash')) + .fontWeight(FontWeight.Normal) + .fontSize(96) + }.id('1') + + // [End creat_symbol_span] + } + + ComponentCard({ title: $r('app.string.SymbolGlyphSpanAddToText_title_2') }) { + // [Start symbol_span_font_size] + Row() { + Column() { + Text('48') + Text() { + SymbolSpan($r('sys.symbol.ohos_folder_badge_plus')) + .fontSize(48) + .renderingStrategy(SymbolRenderingStrategy.SINGLE) + .fontColor([Color.Black, Color.Green, Color.White]) + }.id('2') + } + + Column() { + Text('72') + Text() { + SymbolSpan($r('sys.symbol.ohos_folder_badge_plus')) + .fontSize(72) + .renderingStrategy(SymbolRenderingStrategy.SINGLE) + .fontColor([Color.Black, Color.Green, Color.White]) + }.id('3') + } + + Column() { + Text('96') + Text() { + SymbolSpan($r('sys.symbol.ohos_folder_badge_plus')) + .fontSize(96) + .renderingStrategy(SymbolRenderingStrategy.SINGLE) + .fontColor([Color.Black, Color.Green, Color.White]) + }.id('4') + } + } + + // [End symbol_span_font_size] + } + + ComponentCard({ title: $r('app.string.SymbolGlyphSpanAddToText_title_3') }) { + // [Start symbol_span_font_weight] + Row() { + Column() { + Text('Light') + Text() { + SymbolSpan($r('sys.symbol.ohos_trash')) + .fontWeight(FontWeight.Lighter) + .fontSize(96) + }.id('5') + } + + Column() { + Text('Normal') + Text() { + SymbolSpan($r('sys.symbol.ohos_trash')) + .fontWeight(FontWeight.Normal) + .fontSize(96) + }.id('6') + } + + Column() { + Text('Bold') + Text() { + SymbolSpan($r('sys.symbol.ohos_trash')) + .fontWeight(FontWeight.Bold) + .fontSize(96) + }.id('7') + } + } + + // [End symbol_span_font_weight] + } + + ComponentCard({ title: $r('app.string.SymbolGlyphSpanAddToText_title_4') }) { + // [Start symbol_span_font_color] + Row() { + Column() { + Text('Black') + Text() { + SymbolSpan($r('sys.symbol.ohos_folder_badge_plus')) + .fontSize(96) + .fontColor([Color.Black]) + }.id('8') + } + + Column() { + Text('Green') + Text() { + SymbolSpan($r('sys.symbol.ohos_folder_badge_plus')) + .fontSize(96) + .fontColor([Color.Green]) + }.id('9') + } + + Column() { + Text('Pink') + Text() { + SymbolSpan($r('sys.symbol.ohos_folder_badge_plus')) + .fontSize(96) + .fontColor([Color.Pink]) + }.id('10') + } + } + + // [End symbol_span_font_color] + } + + ComponentCard({ title: $r('app.string.SymbolGlyphSpanAddToText_title_5') }) { + // [Start symbol_span_rendering_strategy] + Row() { + Column() { + Text($r('app.string.SymbolAddToText_Text_1')) + Text() { + SymbolSpan($r('sys.symbol.ohos_folder_badge_plus')) + .fontSize(96) + .renderingStrategy(SymbolRenderingStrategy.SINGLE) + .fontColor([Color.Black, Color.Green, Color.White]) + }.id('11') + } + + Column() { + Text($r('app.string.SymbolAddToText_Text_2')) + Text() { + SymbolSpan($r('sys.symbol.ohos_folder_badge_plus')) + .fontSize(96) + .renderingStrategy(SymbolRenderingStrategy.MULTIPLE_COLOR) + .fontColor([Color.Black, Color.Green, Color.White]) + }.id('12') + } + + Column() { + Text($r('app.string.SymbolAddToText_Text_3')) + Text() { + SymbolSpan($r('sys.symbol.ohos_folder_badge_plus')) + .fontSize(96) + .renderingStrategy(SymbolRenderingStrategy.MULTIPLE_OPACITY) + .fontColor([Color.Black, Color.Green, Color.White]) + }.id('13') + } + } + + // [End symbol_span_rendering_strategy] + } + + ComponentCard({ title: $r('app.string.SymbolGlyphSpanAddToText_title_6') }) { + // [Start symbol_span_effect_strategy] + Row() { + Column() { + Text($r('app.string.SymbolAddToText_Text_4')) + Text() { + SymbolSpan($r('sys.symbol.ohos_wifi')) + .fontSize(96) + .effectStrategy(SymbolEffectStrategy.NONE) + }.id('14') + } + + Column() { + Text($r('app.string.SymbolAddToText_Text_5')) + Text() { + SymbolSpan($r('sys.symbol.ohos_wifi')) + .fontSize(96) + .effectStrategy(SymbolEffectStrategy.SCALE) + }.id('15') + } + + Column() { + Text($r('app.string.SymbolAddToText_Text_6')) + Text() { + SymbolSpan($r('sys.symbol.ohos_wifi')) + .fontSize(96) + .effectStrategy(SymbolEffectStrategy.HIERARCHICAL) + }.id('16') + } + } + + // [End symbol_span_effect_strategy] + } + } + .width('100%') + .padding({ left: 12, right: 12 }) + }.id('scroll_') + } + .backgroundColor('#f1f2f3') + .title($r('app.string.SymbolGlyphSpanAddToText_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/SymbolCustomIconAnimation.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/SymbolCustomIconAnimation.ets new file mode 100644 index 0000000000000000000000000000000000000000..e74e5bda67a5a1290bf1d764c54be49e61f4d8f7 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/SymbolCustomIconAnimation.ets @@ -0,0 +1,64 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; + +@Entry +@Component +export struct SymbolGlyphSpanCustomIconAnimation { + @State isActive: boolean = true; + @State triggerValueReplace: number = 0; + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ title: $r('app.string.SymbolGlyphSpanCustomIconAnimation_title_1') }) { + // [Start symbol_effect_1] + Column() { + Text($r('app.string.SymbolCustomIconAnimation_Text_1')) + SymbolGlyph($r('sys.symbol.ohos_wifi')) + .id('1') + .fontSize(96) + .symbolEffect(new HierarchicalSymbolEffect(EffectFillStyle.ITERATIVE), this.isActive) + Button(this.isActive ? $r('app.string.SymbolGlyphSpanCustomIconAnimation_Button_1') : $r('app.string.SymbolGlyphSpanCustomIconAnimation_Button_2')).onClick(() => { + this.isActive = !this.isActive; + }) + } + // [End symbol_effect_1] + } + ComponentCard({ title: $r('app.string.SymbolGlyphSpanCustomIconAnimation_title_2') }) { + // [Start symbol_effect_2] + Column() { + Text($r('app.string.SymbolCustomIconAnimation_Text_2')) + SymbolGlyph($r('sys.symbol.ellipsis_message_1')) + .id('2') + .fontSize(96) + .fontColor([Color.Gray]) + .symbolEffect(new BounceSymbolEffect(EffectScope.WHOLE, EffectDirection.UP), this.triggerValueReplace) + Button($r('app.string.SymbolGlyphSpanCustomIconAnimation_Button_3')).onClick(() => { + this.triggerValueReplace = this.triggerValueReplace + 1; + }) + } + // [End symbol_effect_2] + } + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.SymbolGlyphSpanCustomIconAnimation_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/SymbolSceneExample.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/SymbolSceneExample.ets new file mode 100644 index 0000000000000000000000000000000000000000..618a85afc47e213f8711a3103db39181dc9b3b18 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/SymbolSceneExample.ets @@ -0,0 +1,244 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct SymbolGlyphSpanSceneExample { + @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 symbolTextIndex: number = 0; + @State fontColorValue: ResourceColor = Color.Grey; + @State fontColorValue1: ResourceColor = '#E8E8E8'; + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ title: $r('app.string.SymbolGlyphSpanSceneExample_title') }) { + // [Start 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)') + }.id('text1') + } + + Row() { + Row({ space: 5 }) { + SymbolGlyph(this.symbolSources[this.symbolSourcesIndex]) + .id('symbolGlyph1') + .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) + }.id('text2') + + Text() { + SymbolSpan($r('sys.symbol.heart_badge_plus')) + .fontColor([this.fontColorValue]) + .fontSize(20) + }.id('text3') + + Text() { + SymbolSpan($r('sys.symbol.ohos_trash')) + .fontColor([this.fontColorValue]) + .fontSize(20) + }.id('text4') + } + .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')) + .id('symbolGlyph2') + .fontColor([this.fontColorValue]) + .fontSize(20) + SymbolGlyph($r('sys.symbol.trash')) + .id('symbolGlyph3') + .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')) + .id('symbolGlyph4') + .fontColor([this.fontColorValue]) + .fontSize(20) + SymbolGlyph($r('sys.symbol.trash')) + .id('symbolGlyph5') + .fontColor([this.fontColorValue]) + .fontSize(20) + } + } + + Divider().width(5).color(this.fontColorValue1).width('98%') + Row() { + Row() { + Text($r('app.string.SymbolSceneExample_Text_7')) + }.width('82%') + + Row({ space: 5 }) { + SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) + .id('symbolGlyph6') + .fontColor([this.fontColorValue]) + .fontSize(20) + SymbolGlyph($r('sys.symbol.trash')) + .id('symbolGlyph7') + .fontColor([this.fontColorValue]) + .fontSize(20) + } + } + + Divider().width(5).color(this.fontColorValue1).width('98%') + Row() { + Row() { + Text($r('app.string.SymbolSceneExample_Text_8')) + }.width('82%') + + Row({ space: 5 }) { + SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) + .id('symbolGlyph8') + .fontColor([this.fontColorValue]) + .fontSize(20) + SymbolGlyph($r('sys.symbol.trash')) + .id('symbolGlyph9') + .fontColor([this.fontColorValue]) + .fontSize(20) + } + } + + Divider().width(5).color(this.fontColorValue1).width('98%') + Row() { + Row() { + Text($r('app.string.SymbolSceneExample_Text_9')) + }.width('82%') + + Row({ space: 5 }) { + SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) + .id('symbolGlyph10') + .fontColor([this.fontColorValue]) + .fontSize(20) + SymbolGlyph($r('sys.symbol.trash')) + .id('symbolGlyph11') + .fontColor([this.fontColorValue]) + .fontSize(20) + } + } + + Divider().width(5).color(this.fontColorValue1).width('98%') + Row() { + Row() { + Text($r('app.string.SymbolSceneExample_Text_10')) + }.width('82%') + + Row({ space: 5 }) { + SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) + .id('symbolGlyph12') + .fontColor([this.fontColorValue]) + .fontSize(20) + SymbolGlyph($r('sys.symbol.trash')) + .id('symbolGlyph13') + .fontColor([this.fontColorValue]) + .fontSize(20) + } + } + + Divider().width(5).color(this.fontColorValue1).width('98%') + Row() { + Row() { + Text($r('app.string.SymbolSceneExample_Text_11')) + }.width('82%') + + Row({ space: 5 }) { + SymbolGlyph($r('sys.symbol.play_arrow_triangle_2_circlepath')) + .id('symbolGlyph14') + .fontColor([this.fontColorValue]) + .fontSize(20) + SymbolGlyph($r('sys.symbol.trash')) + .id('symbolGlyph15') + .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 + }) + // [End symbol_glyph_span_scene_example] + } + } + .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/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/index.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..245b218ccdb45068cd51411a692a92a119e3585f --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/symbol/index.ets @@ -0,0 +1,100 @@ +/* + * 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 { CreatSymbolGlyph } from './CreatSymbolGlyph'; +import { SymbolGlyphSpanAddToText } from './SymbolAddToText'; +import { SymbolGlyphSpanCustomIconAnimation } from './SymbolCustomIconAnimation'; +import { SymbolGlyphSpanAddEvent } from './SymbolAddEvent'; +import { SymbolGlyphSpanSceneExample } from './SymbolSceneExample'; + +import { Route } from '../../common/Route'; +import resource from '../../common/resource'; + +export const SYMBOL_GLYPH_SPAN: string = 'symbol'; + +const routes: Route[] = [ + { + name: `${SYMBOL_GLYPH_SPAN}/CreatSymbolGlyph`, + title: resource.resourceToString($r('app.string.CreatSymbolGlyph_title')), + description: $r('app.string.CreatSymbolGlyph_description') + }, + { + name: `${SYMBOL_GLYPH_SPAN}/SymbolGlyphSpanAddToText`, + title: resource.resourceToString($r('app.string.SymbolGlyphSpanAddToText_title')), + description: $r('app.string.SymbolGlyphSpanAddToText_description') + }, + { + name: `${SYMBOL_GLYPH_SPAN}/SymbolGlyphSpanCustomIconAnimation`, + title: resource.resourceToString($r('app.string.SymbolGlyphSpanCustomIconAnimation_title')), + description: $r('app.string.SymbolGlyphSpanCustomIconAnimation_description') + }, + { + name: `${SYMBOL_GLYPH_SPAN}/SymbolGlyphSpanAddEvent`, + title: resource.resourceToString($r('app.string.SymbolGlyphSpanAddEvent_title')), + description: $r('app.string.SymbolGlyphSpanAddEvent_description') + }, + { + name: `${SYMBOL_GLYPH_SPAN}/SymbolGlyphSpanSceneExample`, + title: resource.resourceToString($r('app.string.SymbolGlyphSpanSceneExample_title')), + description: $r('app.string.SymbolGlyphSpanSceneExample_description') + } +]; + +@Builder +export function SymbolGlyphSpanDestination(name: string) { + if (name === SYMBOL_GLYPH_SPAN) { + SymbolGlyphSpanExample(); + } else if (name === routes[0].name) { + CreatSymbolGlyph(); + } else if (name === routes[1].name) { + SymbolGlyphSpanAddToText(); + } else if (name === routes[2].name) { + SymbolGlyphSpanCustomIconAnimation(); + } else if (name === routes[3].name) { + SymbolGlyphSpanAddEvent(); + } else if (name === routes[4].name) { + SymbolGlyphSpanSceneExample(); + } +} + +@Entry +@Component +struct SymbolGlyphSpanExample { + @Consume pathStack: NavPathStack; + + build() { + NavDestination() { + List({ space: 12 }) { + ForEach(routes, (route: Route) => { + ListItem() { + CompletedRoutableCard({ title: route.title, description: route.description }) + } + .width('100%') + .onClick(() => { + this.pathStack.pushPath({ name: route.name }); + }) + }) + } + .contentStartOffset(56) + .padding({ left: 16, right: 16 }) + } + .backgroundColor('#f1f3f5') + .title('symbol', { + backgroundBlurStyle: BlurStyle.COMPONENT_THICK, + barStyle: BarStyle.STACK + }) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/AIMenu.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/AIMenu.ets new file mode 100644 index 0000000000000000000000000000000000000000..23ea68380767ecb440240df190b4a86b553d72dc --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/AIMenu.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 { ComponentCard } from '../../common/Card'; + +@Entry +@Component +export struct AIMenu { + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ title: $r('app.string.SetUpAIMenu_title') }) { + // [Start set_ai_menu] + Text($r('app.string.AIMenu_Text_1')) + .fontSize(16) + .copyOption(CopyOptions.LocalDevice) + .enableDataDetector(true)// 使能实体识别 + .dataDetectorConfig({ + // 配置识别样式 + // types可支持PHONE_NUMBER电话号码、URL链接、EMAIL邮箱、ADDRESS地址、DATE_TIME时间 + // types设置为null或者[]时,识别所有类型的实体 + types: [], onDetectResultUpdate: (result: string) => { + } + }) + // [End set_ai_menu] + } + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.SetUpAIMenu_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/CreateText.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/CreateText.ets index 274e166c979a93db16c8e7ab664313390c8587b7..db423574802acf63e39054a4d1849c478f9bcb6b 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/CreateText.ets +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/CreateText.ets @@ -23,7 +23,7 @@ export struct CreateText { Column({ space: 12 }) { ComponentCard({ title: $r('app.string.CreatText_title_1') }) { // [Start create_a_text_in_one_way] - Text('This is a text string') + Text($r('app.string.CreateText_Text_1')) // [End create_a_text_in_one_way] } diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/CustomTextStyle.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/CustomTextStyle.ets index a6544964ae0d16e971e0823a22362ce4bae6dea9..d451b7f6ed97a97e923b3994d777475194ce5f7d 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/CustomTextStyle.ets +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/CustomTextStyle.ets @@ -61,22 +61,36 @@ export struct CustomTextStyle { .fontSize(12) .border({ width: 1 }) .padding(10) - Text($r('app.string.CustomTextStyle_textContent_1') + - 'I am an extra long text, with ellipses displayed for any excess。') + Text($r('app.string.CustomTextStyle_textContent_1')) .width(250) .textOverflow({ overflow: TextOverflow.Ellipsis }) .maxLines(1) .fontSize(12) .border({ width: 1 }) .padding(10) - Text($r('app.string.CustomTextStyle_textContent_2') + - 'When the text overflows its dimensions,the text will scroll for displaying.') + Text($r('app.string.CustomTextStyle_textContent_2')) .width(250) .textOverflow({ overflow: TextOverflow.MARQUEE }) .maxLines(1) .fontSize(12) .border({ width: 1 }) .padding(10) + Text($r('app.string.CustomTextStyle_textContent_8')) + .width(250) + .textOverflow({ overflow: TextOverflow.MARQUEE }) + .maxLines(1) + .fontSize(12) + .border({ width: 1 }) + .padding(10) + .marqueeOptions({ + start: true, + fromStart: true, + step: 6, + loop: -1, + delay: 0, + fadeout: false, + marqueeStartPolicy: MarqueeStartPolicy.DEFAULT + }) // [End custom_text_overflow] } } @@ -243,7 +257,7 @@ export struct CustomTextStyle { } .width('100%') .padding({ left: 12, right: 12 }) - } + }.id('scroll_') } .backgroundColor('#f1f2f3') .title($r('app.string.CustomTextStyle_title')) diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/SelectMenu.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/SelectMenu.ets new file mode 100644 index 0000000000000000000000000000000000000000..252cdf3e947a8c4ed0a54ae863ee21dab05e4f8c --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/SelectMenu.ets @@ -0,0 +1,123 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; +import resource from '../../common/resource'; + +@Entry +@Component +export struct SelectMenu { + controller: TextController = new TextController(); + options: TextOptions = { controller: this.controller }; + + // 定义菜单项 + @Builder + RightClickTextCustomMenu() { + Column() { + Menu() { + MenuItemGroup() { + MenuItem({ startIcon: $r('app.media.app_icon'), content: 'CustomMenu One', labelInfo: '' }) + .onClick(() => { + // 使用closeSelectionMenu接口关闭菜单 + this.controller.closeSelectionMenu(); + }) + MenuItem({ startIcon: $r('app.media.app_icon'), content: 'CustomMenu Two', labelInfo: '' }) + MenuItem({ startIcon: $r('app.media.app_icon'), content: 'CustomMenu Three', labelInfo: '' }) + } + }.backgroundColor('#F0F0F0') + } + } + + // 定义onCreateMenu,onMenuItemClick + onCreateMenu = (menuItems: Array) => { + let item1: TextMenuItem = { + content: 'customMenu1', + icon: $r('app.media.app_icon'), + id: TextMenuItemId.of('customMenu1'), + }; + let item2: TextMenuItem = { + content: 'customMenu2', + id: TextMenuItemId.of('customMenu2'), + icon: $r('app.media.app_icon'), + }; + menuItems.push(item1); + menuItems.unshift(item2); + return menuItems; + } + onMenuItemClick = (menuItem: TextMenuItem, textRange: TextRange) => { + if (menuItem.id.equals(TextMenuItemId.of('customMenu2'))) { + console.log(resource.resourceToString($r('app.string.SelectMenu_Text_1')) + + textRange.start + '; end:' + textRange.end); + return true; + } + if (menuItem.id.equals(TextMenuItemId.COPY)) { + console.log(resource.resourceToString($r('app.string.SelectMenu_Text_2')) + + textRange.start + '; end:' + textRange.end); + return true; + } + if (menuItem.id.equals(TextMenuItemId.SELECT_ALL)) { + console.log(resource.resourceToString($r('app.string.SelectMenu_Text_3')) + + textRange.start + '; end:' + textRange.end); + return false; + } + return false; + }; + + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ title: $r('app.string.SetSelectionMenu_textContent_1') }) { + // [Start set_selection_menu_with_copyoption] + Text($r('app.string.SelectMenu_textContent_1')) + .fontSize(30) + .copyOption(CopyOptions.InApp) + // [End set_selection_menu_with_copyoption] + } + + ComponentCard({ title: $r('app.string.SetSelectionMenu_textContent_2') }) { + // [Start set_selection_menu_with_bindselectionmenu] + Text($r('app.string.SelectMenu_textContent_1'), this.options) + .fontSize(30) + .copyOption(CopyOptions.InApp) + .bindSelectionMenu(TextSpanType.TEXT, this.RightClickTextCustomMenu, TextResponseType.RIGHT_CLICK, { + onAppear: () => { + console.info(resource.resourceToString($r('app.string.SelectMenu_Text_4'))); + }, + onDisappear: () => { + console.info(resource.resourceToString($r('app.string.SelectMenu_Text_5'))); + } + }) + // [Start set_selection_menu_with_bindselectionmenu] + } + + ComponentCard({ title: $r('app.string.SetSelectionMenu_textContent_3') }) { + // [Start set_selection_menu_with_editmenuoptions] + Text($r('app.string.SelectMenu_textContent_1')) + .fontSize(20) + .copyOption(CopyOptions.LocalDevice) + .editMenuOptions({ + onCreateMenu: this.onCreateMenu, onMenuItemClick: this.onMenuItemClick + }) + // [End set_selection_menu_with_editmenuoptions] + } + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.SetSelectionMenu_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/TextSpan.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/TextSpan.ets index ead16c2241340b555f28b6b76bbc92c522cedd14..4d0abc81355a73605b4965f770e9387754481b52 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/TextSpan.ets +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/TextSpan.ets @@ -18,7 +18,7 @@ import { ComponentCard } from '../../common/Card'; @Entry @Component export struct TextSpan { - @State onClickText: ResourceStr = 'I am Upper-span'; + @State onClickText: ResourceStr = 'I am Upper-span2'; build() { NavDestination() { diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/index.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/index.ets index f266ed800d0d9ceaf5dc2439f00b35d525d0f3ad..266e20052a5fc87042689a5815bc8060727474fe 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/index.ets +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/text/index.ets @@ -21,6 +21,8 @@ import { TextAddEvent } from './TextAddEvent'; import { TextHotSearch } from './TextHotSearch'; import { TextSpan } from './TextSpan'; import resource from '../../common/resource'; +import { SelectMenu } from './SelectMenu'; +import { AIMenu } from './AIMenu'; export const TEXT_ROUTE_PREFIX: string = 'text'; @@ -45,6 +47,16 @@ const routes: Route[] = [ title: resource.resourceToString($r('app.string.TextAddEvent_title')), description: $r('app.string.TextAddEvent_description') }, + { + name: `${TEXT_ROUTE_PREFIX}/SelectMenu`, + title: resource.resourceToString($r('app.string.SetSelectionMenu_title')), + description: $r('app.string.SetSelectionMenu_description') + }, + { + name: `${TEXT_ROUTE_PREFIX}/AIMenu`, + title: resource.resourceToString($r('app.string.SetUpAIMenu_title')), + description: $r('app.string.SetUpAIMenu_description') + }, { name: `${TEXT_ROUTE_PREFIX}/TextHotSearch`, title: resource.resourceToString($r('app.string.TextHotSearch_title')), @@ -65,6 +77,10 @@ export function TextDestination(name: string) { } else if (name === routes[3].name) { TextAddEvent(); } else if (name === routes[4].name) { + SelectMenu(); + } else if (name === routes[5].name) { + AIMenu(); + } else if (name === routes[6].name) { TextHotSearch(); } } @@ -91,7 +107,7 @@ struct TextExample { .padding({ left: 16, right: 16 }) } .backgroundColor('#f1f3f5') - .title('Text', { + .title('Text/Span', { backgroundBlurStyle: BlurStyle.COMPONENT_THICK, barStyle: BarStyle.STACK }) diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/AutoFill.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/AutoFill.ets new file mode 100644 index 0000000000000000000000000000000000000000..5cdcceb7cdf74e2a0d92dc12d8a2bf3d92b4d5e7 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/AutoFill.ets @@ -0,0 +1,41 @@ +/* + * 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 { ComponentCard } from '../../common/Card'; + +@Entry +@Component +export struct AutoFill { + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ description: $r('app.string.Auto_Fill_description') }) { + // [Start auto_fill] + TextInput({ placeholder: $r('app.string.Auto_Fill_PlaceHolder') }) + .width('95%') + .height(40) + .margin(20) + .contentType(ContentType.EMAIL_ADDRESS) + // [End auto_fill] + } + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.Auto_Fill')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/CursorAvoidance.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/CursorAvoidance.ets new file mode 100644 index 0000000000000000000000000000000000000000..57201b815e2837a4699f74711b9cc500c03b1d31 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/CursorAvoidance.ets @@ -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. + */ + +import { ComponentCard } from '../../common/Card'; + +// [Start cursor_avoid] +@Entry +@Component +export struct CursorAvoidance { + @State caretPosition: number = 600; + areaController: TextAreaController = new TextAreaController(); + text = 'Most of us compare ourselves with anyone we think is happier — a relative, someone we know a lot,' + + ' or someone we hardly know. As a result, what we do remember is anything that makes others happy, ' + + 'anything that makes ourselves unhappy,' + + ' totally forgetting that there is something happy in our own life.\ + So the best way to destroy happiness is to look at something and focus on even the smallest flaw. ' + + 'It is the smallest flaw that would make us complain. And it is the complaint that leads to us becoming unhappy.\ + If one chooses to be happy, he will be blessed; if he chooses to be unhappy, he will be cursed. ' + + 'Happiness is just what you think will make you happy.' + + 'Most of us compare ourselves with anyone we think is happier — a relative, someone we know a lot, ' + + 'or someone we hardly know. As a result, what we do remember is anything that makes others happy, ' + + 'anything that makes ourselves unhappy, totally forgetting that there is something happy in our own life.\ + '; + // : string = getResourceString($r('app.string.CursorAvoidance_Button_1')); + @State str1 : string = getContext(this).resourceManager.getStringSync($r('app.string.CursorAvoidance_Button_1')); + @State str2 : string = getContext(this).resourceManager.getStringSync($r('app.string.CursorAvoidance_Button_2')); + + build() { + NavDestination() { + ComponentCard({ title: $r('app.string.CursorAvoidance_title') }) { + Scroll() { + Column() { + Row() { + + Button(this.str1 + this.caretPosition).onClick(() => { + this.caretPosition += 1; + }).fontSize(10) + Button(this.str2 + this.caretPosition).onClick(() => { + this.caretPosition -= 1; + }).fontSize(10) + Button($r('app.string.CursorAvoidance_Button_3')).onClick(() => { + this.areaController.caretPosition(this.caretPosition); + }).fontSize(10) + } + + TextArea({ text: this.text, controller: this.areaController }) + .width('100%') + .fontSize('20fp') + } + }.width('100%').height('100%') + } + } + .backgroundColor('#f1f2f3') + .title($r('app.string.CursorAvoidance_title')) + } +} +// [End cursor_avoid] \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/LoginRegisterPage.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/LoginRegisterPage.ets index 16b8826b8a11ae94cb66d395ceac9826aaa45bdd..3998f3dcea363e128b1ac349478d1b75c0ce33df 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/LoginRegisterPage.ets +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/LoginRegisterPage.ets @@ -38,7 +38,7 @@ export struct LoginRegisterPage { .onSubmit((enterKeyType) => { console.info(enterKeyType + resource.resourceToString($r('app.string.LoginRegisterPage_textContent'))); }) - Button('Sign in') + Button($r('app.string.LoginRegisterPage_Button_3')) .width('100%') } } diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/SelectMenu.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/SelectMenu.ets new file mode 100644 index 0000000000000000000000000000000000000000..1f782392a69b9e376cf1bcef290059607ad3671d --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/SelectMenu.ets @@ -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. + */ + +import { ComponentCard } from '../../common/Card'; + +@Entry +@Component +export struct SelectMenu { + build() { + NavDestination() { + Column({ space: 12 }) { + ComponentCard({ description: $r('app.string.SelectionMenu_description') }) { + Column({ space: 8 }) { + // [Start select_textinput] + TextInput({ text: $r('app.string.SelectMenu_textContent_1') }) + // [End select_textinput] + // [Start select_textarea] + TextArea({ text: $r('app.string.SelectMenu_textContent_1') }) + // [End select_textarea] + } + } + } + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.SelectionMenu_title')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/SetOmissionProperty.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/SetOmissionProperty.ets new file mode 100644 index 0000000000000000000000000000000000000000..cdf8397bfc230bee0cc98f07f7642aace1a87560 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/SetOmissionProperty.ets @@ -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. + */ + +import { ComponentCard } from '../../common/Card'; + +@Entry +@Component +export struct SetOmissionProperty { + 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 }) + } + .backgroundColor('#f1f2f3') + .title($r('app.string.Set_Omission_Property')) + } +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/SetTextInputType.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/SetTextInputType.ets index c96b89a703af46e27385e700ee7c1b589317bf63..566fd00c217e6c4afbe2ca08435d7fbd2b20a1ed 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/SetTextInputType.ets +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/SetTextInputType.ets @@ -20,26 +20,74 @@ import { ComponentCard } from '../../common/Card'; export struct SetTextInputType { build() { NavDestination() { - Column({ space: 12 }) { - ComponentCard({ title: $r('app.string.SetTextInputType_title_1') }) { - // [Start set_normal_input_type] - TextInput() - .id('Normal') - .type(InputType.Normal) - // [End set_normal_input_type] + Scroll() { + Grid() { + GridItem() { + ComponentCard({ title: $r('app.string.SetTextInputType_title_1') }) { + TextInput() + .id('Normal') + .type(InputType.Normal) + } + }.width('33%') + GridItem() { + ComponentCard({ title: $r('app.string.SetTextInputType_title_2') }) { + // [Start set_password_input_type] + TextInput() + .id('Password') + .type(InputType.Password) + // [End set_password_input_type] + } + }.width('33%') + GridItem() { + ComponentCard({ title: $r('app.string.SetTextInputType_title_3') }) { + // [Start set_email_input_type] + TextInput() + .id('Email') + .type(InputType.Email) + // [End set_email_input_type] + } + }.width('33%') + GridItem() { + ComponentCard({ title: $r('app.string.SetTextInputType_title_4') }) { + // [Start set_number_input_type] + TextInput() + .id('Number') + .type(InputType.Number) + // [End set_number_input_type] + } + }.width('33%') + GridItem() { + ComponentCard({ title: $r('app.string.SetTextInputType_title_5') }) { + // [Start set_phonenumber_input_type] + TextInput() + .id('PhoneNumber') + .type(InputType.PhoneNumber) + // [End set_phonenumber_input_type] + } + }.width('33%') + GridItem() { + ComponentCard({ title: $r('app.string.SetTextInputType_title_6') }) { + // [Start set_number_decimal_input_type] + TextInput() + .id('NUMBER_DECIMAL') + .type(InputType.NUMBER_DECIMAL) + // [End set_number_decimal_input_type] + } + }.width('33%') + GridItem() { + ComponentCard({ title: $r('app.string.SetTextInputType_title_7') }) { + // [Start set_url_input_type] + TextInput() + .id('URL') + .type(InputType.URL) + // [End set_url_input_type] + } + }.width('33%') } - - ComponentCard({ title: $r('app.string.SetTextInputType_title_2') }) { - // [Start set_password_input_type] - TextInput() - .id('Password') - .type(InputType.Password) - // [End set_password_input_type] - } - } - .width('100%') - .height('100%') - .padding({ left: 12, right: 12 }) + .width('100%') + .height('100%') + .padding({ left: 12, right: 12 }) + }.id('scroll_') } .backgroundColor('#f1f2f3') .title($r('app.string.SetTextInputType_title')) diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/TextInputAddEvent.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/TextInputAddEvent.ets index 74ed0cfe424883fef88747902cda490e93eec5d1..18a68f293890536c3465e288827b3be359014c71 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/TextInputAddEvent.ets +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/TextInputAddEvent.ets @@ -20,6 +20,8 @@ import { ComponentCard } from '../../common/Card'; export struct TextInputAddEvent { @State eventText: ResourceStr = $r('app.string.TextInputAddEvent_textContent_1'); @State inputValue: ResourceStr = $r('app.string.TextInputAddEvent_textContent_2'); + controller: TextInputController = new TextInputController(); + passwordState: boolean = false; build() { NavDestination() { @@ -29,9 +31,47 @@ export struct TextInputAddEvent { Text(this.eventText) Text(this.inputValue) // [Start add_text_input_event] - TextInput() + TextInput({ + text: $r('app.string.TextInputAddEvent_textContent_2'), + placeholder: 'input your word...', + controller: this.controller + }) + .type(InputType.Password) + .showPassword(this.passwordState) .onChange((value: string) => { - this.inputValue = value; + // 文本内容发生变化时触发该回调 + this.inputValue = 'onChange is triggering: ' + value; + }) + .onSubmit((enterKey: EnterKeyType, event: SubmitEvent) => { + // 按下输入法回车键时触发该回调 + this.eventText = 'onSubmit is triggering: ' + enterKey + ' ' + event.text; + }) + .onTextSelectionChange((selectionStart: number, selectionEnd: number) => { + // 文本选择的位置发生变化或编辑状态下光标位置发生变化时,触发该回调 + this.eventText = 'onTextSelectionChange is triggering: ' + selectionStart + ' ' + selectionEnd; + }) + .onSecurityStateChange((isShowPassword: boolean) => { + // 密码显隐状态切换时,触发该回调 + this.eventText = 'onSecurityStateChange is triggering: ' + isShowPassword + this.passwordState = isShowPassword; + }) + .onWillInsert((info: InsertValue) => { + // 在将要输入时,触发该回调 + this.eventText = 'onWillInsert is triggering: ' + info.insertValue + ' ' + info.insertOffset; + return true; + }) + .onDidInsert((info: InsertValue) => { + // 在输入完成时,触发该回调 + this.eventText = 'onDidInsert is triggering: ' + info.insertValue + ' ' + info.insertOffset + }) + .onWillDelete((info: DeleteValue) => { + // 在将要删除时,触发该回调 + this.eventText = 'onWillDelete is triggering: ' + info.deleteValue + ' ' + info.deleteOffset + return true; + }) + .onDidDelete((info: DeleteValue) => { + // 在删除完成时,触发该回调 + this.eventText = 'onDidDelete is triggering: ' + info.deleteValue + ' ' + info.deleteOffset }) .onFocus(() => { this.eventText = $r('app.string.TextInputAddEvent_textContent_3'); diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/index.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/index.ets index 6c295e9a328f35a1ad0f441df0ba94ed6866b0e1..91475ab18832a47e42303551cacb889d9784a27c 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/index.ets +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/ets/pages/textInput/index.ets @@ -23,6 +23,10 @@ import { LoginRegisterPage } from './LoginRegisterPage'; import { SetTextInputType } from './SetTextInputType'; import { TextInputAddEvent } from './TextInputAddEvent'; import resource from '../../common/resource'; +import { SelectMenu } from './SelectMenu'; +import { AutoFill } from './AutoFill'; +import { SetOmissionProperty } from './SetOmissionProperty'; +import { CursorAvoidance } from './CursorAvoidance'; export const INPUT_ROUTE_PREFIX: string = 'TextInput'; @@ -48,14 +52,34 @@ const routes: Route[] = [ description: $r('app.string.TextInputAddEvent_description') }, { - name: `${INPUT_ROUTE_PREFIX}/LoginRegisterPage`, - title: resource.resourceToString($r('app.string.LoginRegisterPage_title')), - description: $r('app.string.LoginRegisterPage_description') + name: `${INPUT_ROUTE_PREFIX}/SelectMenu`, + title: resource.resourceToString($r('app.string.SelectionMenu_title')), + description: $r('app.string.SelectionMenu_description') + }, + { + name: `${INPUT_ROUTE_PREFIX}/AutoFill`, + title: resource.resourceToString($r('app.string.Auto_Fill')), + description: $r('app.string.Auto_Fill_description') + }, + { + name: `${INPUT_ROUTE_PREFIX}/SetOmissionProperty`, + title: resource.resourceToString($r('app.string.Set_Omission_Property')), + description: $r('app.string.Set_Omission_Property_description') }, { name: `${INPUT_ROUTE_PREFIX}/KeyboardAvoidance`, title: resource.resourceToString($r('app.string.KeyboardAvoidance_title')), description: $r('app.string.KeyboardAvoidance_description') + }, + { + name: `${INPUT_ROUTE_PREFIX}/CursorAvoidance`, + title: resource.resourceToString($r('app.string.CursorAvoidance_title')), + description: $r('app.string.CursorAvoidance_description') + }, + { + name: `${INPUT_ROUTE_PREFIX}/LoginRegisterPage`, + title: resource.resourceToString($r('app.string.LoginRegisterPage_title')), + description: $r('app.string.LoginRegisterPage_description') } ]; @@ -72,9 +96,17 @@ export function TextInputDestination(name: string) { } else if (name === routes[3].name) { TextInputAddEvent(); } else if (name === routes[4].name) { - LoginRegisterPage(); + SelectMenu(); } else if (name === routes[5].name) { + AutoFill(); + } else if (name === routes[6].name) { + SetOmissionProperty(); + } else if (name === routes[7].name) { KeyboardAvoidance(); + } else if (name === routes[8].name) { + CursorAvoidance(); + } else if (name === routes[9].name) { + LoginRegisterPage(); } } @@ -85,22 +117,24 @@ struct TextInputExample { build() { NavDestination() { - List({ space: 12 }) { - ForEach(routes, (route: Route) => { - ListItem() { - CompletedRoutableCard({ title: route.title, description: route.description }) - } - .width('100%') - .onClick(() => { - this.pathStack.pushPath({ name: route.name }); + Scroll() { + List({ space: 12 }) { + ForEach(routes, (route: Route) => { + ListItem() { + CompletedRoutableCard({ title: route.title, description: route.description }) + } + .width('100%') + .onClick(() => { + this.pathStack.pushPath({ name: route.name }); + }) }) - }) - } - .contentStartOffset(56) - .padding({ left: 16, right: 16 }) + } + .contentStartOffset(56) + .padding({ left: 16, right: 16 }) + }.id('scroll_') } .backgroundColor('#f1f3f5') - .title('TextInput', { + .title('TextInput/TextArea', { backgroundBlurStyle: BlurStyle.COMPONENT_THICK, barStyle: BarStyle.STACK }) diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/resources/base/element/float.json b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..a0a93dd91fd48f08f3a9532c76e9b26e68d4c034 --- /dev/null +++ b/code/DocsSample/ArkUISample/TextComponent/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/code/DocsSample/ArkUISample/TextComponent/entry/src/main/resources/base/element/string.json b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/resources/base/element/string.json index 40eb1db3937f96f96539bbf71011e759fd76d6d7..84c70d29815ac6ffa86d003032dd2f65ddb75285 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/resources/base/element/string.json +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/resources/base/element/string.json @@ -2,7 +2,7 @@ "string": [ { "name": "module_desc", - "value": "module description" + "value": "模块描述" }, { "name": "EntryAbility_desc", @@ -14,11 +14,23 @@ }, { "name": "pageIndex_Text", - "value": "文本显示/Text" + "value": "文本显示(Text/Span)" }, { "name": "pageIndex_TextInput", - "value": "文本输入/TextInput" + "value": "文本输入(TextInput/TextArea)" + }, + { + "name": "pageIndex_RichEditor", + "value": "富文本(RichEditor)" + }, + { + "name": "pageIndex_PropertyString", + "value": "属性字符串(StyledString/MutableStyledString)" + }, + { + "name": "pageIndex_TextNDKUI", + "value": "使用文本(NDK)" }, { "name": "CreatText_title", @@ -54,7 +66,7 @@ }, { "name": "TextSpan_description", - "value": "Span只能作为Text和RichEditor组件的子组件显示文本内容,可以在一个Text内添加多个Span来显示一段信息。" + "value": "Span只能作为Text和RichEditor组件的子组件显示文本内容,可以在一个Text内添加多个Span来显示一段信息" }, { "name": "TextSpan_textContent_1", @@ -82,11 +94,11 @@ }, { "name": "CreatText_description", - "value": "示例使用string字符串和引用Resource资源两种方式来创建文本。" + "value": "示例使用string字符串和引用Resource资源两种方式来创建文本" }, { "name": "CreatText_description_1", - "value": "资源引用类型可以通过$r创建Resource类型对象,文件位置为/resources/base/element/string.json。" + "value": "资源引用类型可以通过$r创建Resource类型对象,文件位置为/resources/base/element/string.json" }, { "name": "CustomTextStyle_title", @@ -130,19 +142,19 @@ }, { "name": "CustomTextStyle_description", - "value": "示例中展示对文本的对齐、文本超长处理、文本行高、装饰线等属性进行设置的自定义文本样式。" + "value": "示例中展示对文本的对齐、文本超长处理、文本行高、装饰线等属性进行设置的自定义文本样式" }, { "name": "CustomTextStyle_description_1", - "value": "textOverflow需配合maxLines一起使用(默认情况下文本自动折行)。" + "value": "textOverflow需配合maxLines一起使用(默认情况下文本自动折行)。从API version 18开始,文本超长时设置跑马灯的方式展示时,支持设置跑马灯的配置项,比如开关、步长、循环次数、方向等" }, { "name": "CustomTextStyle_textContent_1", - "value": "我是超长文本,超出的部分显示省略号。" + "value": "我是超长文本,超出的部分显示省略号 I am an extra long text, with ellipses displayed for any excess。" }, { "name": "CustomTextStyle_textContent_2", - "value": "当文本溢出其尺寸时,文本将滚动显示。" + "value": "当文本溢出其尺寸时,文本将滚动显示 When the text overflows its dimensions,the text will scroll for displaying." }, { "name": "CustomTextStyle_textContent_3", @@ -164,6 +176,10 @@ "name": "CustomTextStyle_textContent_7", "value": "这是一段可复制文本。" }, + { + "name": "CustomTextStyle_textContent_8", + "value": "当文本溢出其尺寸时,文本将滚动显示,支持设置跑马灯配置项 When the text overflows its dimensions, the text will scroll for displaying." + }, { "name": "TextAlign_Start", "value": "左对齐" @@ -180,9 +196,37 @@ "name": "TextAddEvent_title", "value": "添加事件" }, + { + "name": "SetSelectionMenu_title", + "value": "设置选中菜单" + }, + { + "name": "SelectionMenu_title", + "value": "选中菜单" + }, + { + "name": "SelectionMenu_description", + "value": "输入框中的文字被选中时会弹出包含剪切、复制、翻译、搜索的菜单" + }, + { + "name": "SetSelectionMenu_description", + "value": "设置Text被选中时,会弹出包含复制、翻译、搜索以及自定义的菜单" + }, + { + "name": "SetSelectionMenu_textContent_1", + "value": "Text组件需要设置copyOption属性才可以被选中" + }, + { + "name": "SetSelectionMenu_textContent_2", + "value": "Text组件通过设置bindSelectionMenu属性绑定自定义选择菜单" + }, + { + "name": "SetSelectionMenu_textContent_3", + "value": "Text组件通过设置editMenuOptions属性扩展自定义选择菜单,可以设置扩展项的文本内容、图标以及回调方法" + }, { "name": "TextAddEvent_description", - "value": "Text组件可以添加通用事件,可以绑定onClick、onTouch等事件来响应操作。" + "value": "Text组件可以添加通用事件,可以绑定onClick、onTouch等事件来响应操作" }, { "name": "TextAddEvent_textContent_1", @@ -202,7 +246,7 @@ }, { "name": "TextHotSearch_description", - "value": "示例通过maxLines、textOverflow、textAlign、constraintSize属性展示了热搜榜的效果。" + "value": "示例通过maxLines、textOverflow、textAlign、constraintSize属性展示了热搜榜的效果" }, { "name": "TextHotSearch_textContent_1", @@ -242,7 +286,7 @@ }, { "name": "CreatTextInput_description", - "value": "示例通过接口创建文本输入框,其中TextInput为单行输入框、TextArea为多行输入框。" + "value": "示例通过接口创建文本输入框,其中TextInput为单行输入框、TextArea为多行输入框" }, { "name": "CreatTextInput_description_1", @@ -264,6 +308,26 @@ "name": "SetTextInputType_title_2", "value": "密码输入模式" }, + { + "name": "SetTextInputType_title_3", + "value": "邮箱地址输入模式" + }, + { + "name": "SetTextInputType_title_4", + "value": "纯数字输入模式" + }, + { + "name": "SetTextInputType_title_5", + "value": "电话号码输入模式" + }, + { + "name": "SetTextInputType_title_6", + "value": "带小数点的数字输入模式" + }, + { + "name": "SetTextInputType_title_7", + "value": "带URL的输入模式" + }, { "name": "SetTextInputType_description", "value": "TextInput有9种可选类型,示例中展示Normal基本输入模式和Password密码输入模式两种类型" @@ -286,7 +350,7 @@ }, { "name": "CustomTextInputStyle_description", - "value": "示例对输入框的提示文本、文本内容和背景颜色进行展示,更丰富的样式可以结合通用属性实现。" + "value": "示例对输入框的提示文本、文本内容和背景颜色进行展示,更丰富的样式可以结合通用属性实现" }, { "name": "CustomTextInputStyle_textContent_1", @@ -306,7 +370,7 @@ }, { "name": "TextInputAddEvent_description", - "value": "文本框主要用于获取用户输入的信息,把信息处理成数据进行上传,绑定onChange事件可以获取输入框内改变的内容。用户也可以使用通用事件来进行相应的交互操作。" + "value": "文本框主要用于获取用户输入的信息,把信息处理成数据进行上传,绑定onChange事件可以获取输入框内改变的内容。用户也可以使用通用事件来进行相应的交互操作" }, { "name": "TextInputAddEvent_textContent_1", @@ -326,7 +390,7 @@ }, { "name": "LoginRegisterPage_description", - "value": "示例模仿用户在登录/注册页面,进行登录或注册。" + "value": "示例模仿用户在登录/注册页面,进行登录或注册" }, { "name": "LoginRegisterPage_textContent", @@ -334,11 +398,831 @@ }, { "name": "KeyboardAvoidance_title", - "value": "键盘避让示例" + "value": "键盘避让" + }, + { + "name": "CursorAvoidance_title", + "value": "光标避让" + }, + { + "name": "CursorAvoidance_description", + "value": "keyBoardAvoidMode枚举中的OFFSET和RESIZE在键盘抬起后,不支持二次避让。如果想要支持光标位置在点击或者通过接口设置变化后发生二次避让,可以考虑使用OFFSET_WITH_CARET和RESIZE_CARET替换原有的OFFSET和RESIZE模式。\n对于滚动容器更推荐使用RESIZE_WITH_CARET,非滚动容器应该使用OFFSET_WITH_CARET。" }, { "name": "KeyboardAvoidance_description", - "value": "示例中键盘抬起后,具有滚动能力的容器组件在横竖屏切换时,才会生效键盘避让。" + "value": "示例中键盘抬起后,具有滚动能力的容器组件在横竖屏切换时,才会生效键盘避让" + }, + { + "name": "SelectMenu_textContent_1", + "value": "这是一段文本,用来展示选中菜单" + }, + { + "name": "SelectMenu_textContent_2", + "value": "自定义选择菜单弹出时触发该回调" + }, + { + "name": "SelectMenu_textContent_3", + "value": "自定义选择菜单关闭时触发该回调" + }, + { + "name": "SetUpAIMenu_title", + "value": "设置AI菜单" + }, + { + "name": "SetUpAIMenu_description", + "value": "Text组件通过enableDataDetector和dataDetectorConfig属性实现AI菜单的显示" + }, + { + "name": "Auto_Fill", + "value": "自动填充" + }, + { + "name": "Auto_Fill_description", + "value": "输入框可以通过contentType属性设置自动填充类型" + }, + { + "name": "Auto_Fill_PlaceHolder", + "value": "输入你的邮箱..." + }, + { + "name": "Set_Omission_Property", + "value": "设置省略属性" + }, + { + "name": "Set_Omission_Property_description", + "value": "输入框可以通过ellipsisMode属性设置省略位置" + }, + { + "name": "Set_Omission_Property_textContent", + "value": "这是一段文本,用来展示省略模式" + }, + { + "name": "Create_RichEditor_Component_title", + "value": "创建RichEditor组件" + }, + { + "name": "Create_RichEditor_Component_title_1", + "value": "创建使用属性字符串构建的RichEditor组件" + }, + { + "name": "Create_RichEditor_Component_title_2", + "value": "创建不使用属性字符串构建的RichEditor组件" + }, + { + "name": "Create_RichEditor_Component_description", + "value": "开发者可以创建使用属性字符串和不使用属性字符串构建的RichEditor组件" + }, + { + "name": "Set_Attributes_title", + "value": "设置属性" + }, + { + "name": "Set_Attributes_title_1", + "value": "设置自定义选择菜单" + }, + { + "name": "Set_Attributes_title_1_desc", + "value": "通过bindSelectionMenu设置自定义选择菜单" + }, + { + "name": "Set_Attributes_title_2", + "value": "设置输入框光标、手柄颜色" + }, + { + "name": "Set_Attributes_title_2_desc", + "value": "通过caretColor设置输入框光标、手柄颜色" + }, + { + "name": "Set_Attributes_title_3", + "value": "设置无输入时的提示文本" + }, + { + "name": "Set_Attributes_title_3_desc", + "value": "通过placeholder设置无输入时的提示文本" + }, + { + "name": "Set_Attributes_title_4", + "value": "设置最大行数" + }, + { + "name": "Set_Attributes_title_4_desc", + "value": "通过maxLines设置富文本可显示的最大行数" + }, + { + "name": "Set_Attributes_title_5", + "value": "设置最大长度" + }, + { + "name": "Set_Attributes_title_5_desc", + "value": "通过maxLength设置富文本的最大输入字符数" + }, + { + "name": "Set_Attributes_title_6", + "value": "默认选中菜单" + }, + { + "name": "Set_Attributes_title_6_desc", + "value": "富文本中的文字被选中时会弹出包含剪切、复制、翻译、分享的菜单" + }, + { + "name": "Add_Event_title", + "value": "添加事件" + }, + { + "name": "Add_Event_title_1", + "value": "添加组件初始化完成后可触发的回调" + }, + { + "name": "Add_Event_title_1_desc", + "value": "通过onReady来添加组件初始化完成后可触发的回调" + }, + { + "name": "Add_Event_title_2", + "value": "添加组件内容选择区域或编辑状态下光标位置改变时可触发的回调" + }, + { + "name": "Add_Event_title_2_desc", + "value": "通过onSelectionChange来添加组件内容选择区域或编辑状态下光标位置改变时可触发的回调" + }, + { + "name": "Add_Event_title_3", + "value": "添加组件内容选择区域或编辑状态下光标位置改变时可触发的回调" + }, + { + "name": "Add_Event_title_3_desc", + "value": "通过onWillChange添加图文变化前可触发的回调,通过onDidChange添加图文变化后可触发的回调" + }, + { + "name": "Add_Event_title_4", + "value": "添加输入法输入内容前和完成输入后可触发的回调" + }, + { + "name": "Add_Event_title_4_desc", + "value": "在添加输入法输入内容前,可以通过aboutToIMEInput触发回调。在输入法完成输入后,可以通过onDidIMEInput触发回调" + }, + { + "name": "Add_Event_title_5", + "value": "添加完成粘贴前可触发的回调" + }, + { + "name": "Add_Event_title_5_desc", + "value": "通过onPaste回调,来添加粘贴前要处理的流程" + }, + { + "name": "Add_Event_title_6", + "value": "添加完成剪切前可触发的回调" + }, + { + "name": "Add_Event_title_6_desc", + "value": "通过onCut回调,来添加剪切前要处理的流程" + }, + { + "name": "Add_Event_title_7", + "value": "添加完成复制前可触发的回调" + }, + { + "name": "Add_Event_title_7_desc", + "value": "通过onCopy回调,来添加复制前要处理的流程" + }, + { + "name": "Set_User_PresetText_Styles_title", + "value": "设置用户预设的文本样式" + }, + { + "name": "Set_User_PresetText_Styles_desc", + "value": "通过setTypingStyle设置用户预设的文本样式" + }, + { + "name": "Backplane_Highlighting_title", + "value": "设置组件内的内容选中时部分背板高亮" + }, + { + "name": "Backplane_Highlighting_desc", + "value": "通过setSelection设置组件内的内容选中时部分背板高亮" + }, + { + "name": "Add_TextContent_title", + "value": "添加文本内容" + }, + { + "name": "Add_TextContent_desc", + "value": "除了直接在组件内输入内容,也可以通过addTextSpan添加文本内容" + }, + { + "name": "Add_ImageContent_title", + "value": "添加图片内容" + }, + { + "name": "Add_ImageContent_desc", + "value": "通过addImageSpan添加图片内容" + }, + { + "name": "Add_Builder_DecoratorContent_title", + "value": "添加@Builder装饰器修饰的内容" + }, + { + "name": "Add_Builder_DecoratorContent_desc", + "value": "通过addBuilderSpan添加@Builder装饰器修饰的内容" + }, + { + "name": "Add_SymbolSpanContent_title", + "value": "添加SymbolSpan内容" + }, + { + "name": "Add_SymbolSpanContent_desc", + "value": "可通过addSymbolSpan添加Symbol内容。此接口可用于特殊符号添加与展示,例如在编辑学术论文时,此接口可用于添加各种数学符号" + }, + { + "name": "Get_GraphicInfo_In_Component_title", + "value": "获取组件内图文信息" + }, + { + "name": "Get_GraphicInfo_In_Component_desc", + "value": "可通过getSpans获取组件内所有图文内容的信息,包括图文的内容、id、样式、位置等信息。获取内容位置信息后,可对指定范围内容进行样式的更新" + }, + { + "name": "Create_Apply_StyledString_MutableStyledString_title", + "value": "创建并应用StyledString和MutableStyledString" + }, + { + "name": "Create_Apply_StyledString_MutableStyledString_desc", + "value": "可以通过TextController提供的setStyledString方法,将属性字符串附加到文本组件,并推荐在onPageShow或者文本组件的onAppear回调中触发绑定" + }, + { + "name": "pageIndex_StyledString", + "value": "属性字符串 StyledString/MutableStyledString" + }, + { + "name": "CreatStyledString_title", + "value": "创建并应用StyledString和MutableStyledString" + }, + { + "name": "CreatStyledString_description", + "value": "可以通过TextController提供的setStyledString方法,将属性字符串附加到文本组件,并推荐在onPageShow或者文本组件的onAppear回调中触发绑定。" + }, + { + "name": "StyledStringStyle_title", + "value": "设置文本样式" + }, + { + "name": "StyledStringStyle_description", + "value": "属性字符串目前提供了多种Style对象,包括TextStyle、TextShadowStyle、DecorationStyle、BaselineOffsetStyle、LineHeightStyle、LetterSpacingStyle,用于设置文本的各类样式。" + }, + { + "name": "StyledStringStyle_title_1", + "value": "创建及应用文本字体样式对象(TextStyle)" + }, + { + "name": "StyledStringStyle_title_2", + "value": "创建及应用文本阴影对象(TextShadowStyle)" + }, + { + "name": "StyledStringStyle_title_3", + "value": "创建及应用文本装饰线对象(DecorationStyle)" + }, + { + "name": "StyledStringStyle_title_4", + "value": "创建及应用文本基线偏移量对象(BaselineOffsetStyle)" + }, + { + "name": "StyledStringStyle_title_5", + "value": "创建及应用文本行高对象(LineHeightStyle)" + }, + { + "name": "StyledStringStyle_title_6", + "value": "创建及应用文本字符间距对象(LetterSpacingStyle)" + }, + { + "name": "StyledStringParagraphStyle_title", + "value": "设置段落样式" + }, + { + "name": "StyledStringParagraphStyle_description", + "value": "可通过ParagraphStyle设置段落样式布局。" + }, + { + "name": "StyledStringImageAttachment_title", + "value": "通过ImageAttachment来添加图片" + }, + { + "name": "StyledStringImageAttachment_description", + "value": "将图片和文本附加到同一个MutableStyledString对象上,并实现图文混排。" + }, + { + "name": "TStyledStringGestureStyle_title", + "value": "设置事件" + }, + { + "name": "StyledStringGestureStyle_description", + "value": "除了初始化属性字符串对象即初始样式对象,亦可通过setStyle接口再叠加新样式或更新已有样式,同时需要在附加的文本组件controller上主动触发更新绑定的属性字符串。" + }, + { + "name": "StyledStringHtml_title", + "value": "格式转换" + }, + { + "name": "StyledStringHtml_description", + "value": "可以通过toHtml、fromHtml接口实现属性字符串与HTML格式字符串的相关转换,当前支持转换的HTML标签范围:

。" + }, + { + "name": "StyledStringSceneExample_title", + "value": "场景示例" + }, + { + "name": "StyledStringSceneExample_description", + "value": "通过ParagraphStyle、LineHeightStyle、TextStyle对象展示了会员过期提示的效果。" + }, + { + "name": "pageIndex_symbolGlyphSpan", + "value": "图标小符号(SymbolGlyph/SymbolSpan)" + }, + { + "name": "CreatSymbolGlyph_title", + "value": "创建图标" + }, + { + "name": "CreatSymbolGlyph_description", + "value": "SymbolGlyph通过$r引用Resource资源来创建,目前仅支持系统预置的Symbol资源名。" + }, + { + "name": "SymbolGlyphSpanAddToText_title", + "value": "添加到文本中" + }, + { + "name": "SymbolGlyphSpanAddToText_description", + "value": "SymbolSpan可作为Text的子组件用于显示图标小符号。可以在一个Text组件内添加多个SymbolSpan,从而展示一串连续的图标。" + }, + { + "name": "SymbolGlyphSpanCustomIconAnimation_title", + "value": "自定义图标动效" + }, + { + "name": "SymbolGlyphSpanCustomIconAnimation_description", + "value": "相较于effectStrategy属性在启动时即触发动效,可以通过以下两种方式来控制动效的播放状态,以及选择更多样化的动效策略。" + }, + { + "name": "SymbolGlyphSpanAddEvent_title", + "value": "添加事件" + }, + { + "name": "SymbolGlyphSpanAddEvent_description", + "value": "SymbolGlyph组件可以添加通用事件,例如绑定onClick、onTouch等事件来响应操作。" + }, + { + "name": "SymbolGlyphSpanSceneExample_title", + "value": "场景示例" + }, + { + "name": "SymbolGlyphSpanSceneExample_description", + "value": "该示例通过symbolEffect、fontSize、fontColor属性展示了播放列表的效果。" + }, + { + "name": "SymbolGlyphSpanAddToText_title_1", + "value": "创建SymbolSpan" + }, + { + "name": "SymbolGlyphSpanAddToText_title_2", + "value": "通过fontSize属性设置SymbolSpan的大小" + }, + { + "name": "SymbolGlyphSpanAddToText_title_3", + "value": "通过fontWeight属性设置SymbolSpan组件的粗细" + }, + { + "name": "SymbolGlyphSpanAddToText_title_4", + "value": "通过fontColor属性设置SymbolSpan的颜色" + }, + { + "name": "SymbolGlyphSpanAddToText_title_5", + "value": "通过renderingStrategy属性设置SymbolSpan的渲染策略" + }, + { + "name": "SymbolGlyphSpanAddToText_title_6", + "value": "通过effectStrategy属性设置SymbolSpan的动效策略" + }, + { + "name": "SymbolGlyphSpanCustomIconAnimation_title_1", + "value": "通过设置SymbolEffect属性,可以同时配置SymbolGlyph的动效策略和播放状态" + }, + { + "name": "SymbolGlyphSpanCustomIconAnimation_title_2", + "value": "通过设置SymbolEffect属性,可以同时指定SymbolGlyph的动画效果策略及其播放触发条件" + }, + { + "name": "ListenTextBoxEvents_NDK_title", + "value": "输入框文本事件监听" + }, + { + "name": "ListenTextBoxEvents_NDK_desc", + "value": "输入框包含多种交互行为,开发者可注册事件监听并获取状态" + }, + { + "name": "TextDrawingDisplay_NDK_title", + "value": "Text组件的文本绘制与显示" + }, + { + "name": "TextDrawingDisplay_NDK_desc", + "value": "Text组件提供了接口NODE_TEXT_CONTENT_WITH_STYLED_STRING,可以直接渲染方舟文本引擎生成的文本" + }, + { + "name": "StyledStringHtml_Button_1", + "value": "添加属性字符串" + }, + { + "name": "StyledStringHtml_Button_2", + "value": "toHtml" + }, + { + "name": "StyledStringHtml_Button_3", + "value": "fromHtml" + }, + { + "name": "StyledStringImageAttachment_Button_1", + "value": "点击查看商品卡片" + }, + { + "name": "StyledStringParagraphStyle_Button_1", + "value": "change" + }, + { + "name": "StyledStringSceneExample_Button_1", + "value": "限时4.88元 立即续费" + }, + { + "name": "AddBuilderDecoratorContent_Button_1", + "value": "addBuilderSpan" + }, + { + "name": "AddImageContent_Button_1", + "value": "addImageSpan" + }, + { + "name": "AddSymbolSpanContent_Button_1", + "value": "addSymbolSpan" + }, + { + "name": "AddTextContent_Button_1", + "value": "addTextSpan" + }, + { + "name": "BackplaneHighlighting_Button_1", + "value": "setSelection(0,2)" + }, + { + "name": "GetGraphicInfoInComponent_Button_1", + "value": "getSpans" + }, + { + "name": "SetUserPresetTextStyles_Button_1", + "value": "setTypingStyle" + }, + { + "name": "SymbolGlyphSpanCustomIconAnimation_Button_1", + "value": "关闭" + }, + { + "name": "SymbolGlyphSpanCustomIconAnimation_Button_2", + "value": "播放" + }, + { + "name": "SymbolGlyphSpanCustomIconAnimation_Button_3", + "value": "trigger" + }, + { + "name": "CursorAvoidance_Button_1", + "value": "CaretPosition++: " + }, + { + "name": "CursorAvoidance_Button_2", + "value": "CaretPosition--: " + }, + { + "name": "CursorAvoidance_Button_3", + "value": "SetCaretPosition: " + }, + { + "name": "LoginRegisterPage_Button_3", + "value": "Sign in" + }, + { + "name": "CreateApply_Text_1", + "value": "运动45分钟" + }, + { + "name": "CreateApply_Text_2", + "value": "运动35分钟" + }, + { + "name": "StyledStringHtml_Text_1", + "value": "属性字符串" + }, + { + "name": "StyledStringImageAttachment_Text_1", + "value": "\n品牌相纸 高清冲印30张\n限时直降5.15元 限量增送" + }, + { + "name": "StyledStringImageAttachment_Text_2", + "value": "\n¥16.21 3000+人好评" + }, + { + "name": "StyledStringParagraphStyle_Text_1", + "value": "段落标题\n正文第一段落开始0123456789正文第一段落结束。" + }, + { + "name": "StyledStringSceneExample_Text_1", + "value": "您的豪华钻石已过期1天\n续费可继续享受会员专属权益" + }, + { + "name": "StyledStringSceneExample_Text_2", + "value": "\n¥4.88¥15" + }, + { + "name": "StyledStringSceneExample_Text_3", + "value": "\n02时06分后将失去该优惠" + }, + { + "name": "StyledStringStyle_Text_1", + "value": "运动35分钟 目标达成" + }, + { + "name": "StyledStringStyle_Text_2", + "value": "运动35分钟" + }, + { + "name": "StyledStringStyle_Text_3", + "value": "运动35分钟" + }, + { + "name": "StyledStringStyle_Text_4", + "value": "运动35分钟" + }, + { + "name": "StyledStringStyle_Text_5", + "value": "运动35分钟\n顶顶顶\n得到" + }, + { + "name": "StyledStringStyle_Text_6", + "value": "运动35分钟" + }, + { + "name": "AddBuilderDecoratorContent_Text_1", + "value": "文本文档.txt" + }, + { + "name": "AddBuilderDecoratorContent_Text_2", + "value": "123.45KB" + }, + { + "name": "AddBuilderDecoratorContent_Text_3", + "value": "点击按钮在此处添加builderspan。" + }, + { + "name": "AddEvent_Text_1", + "value": "onReady回调内容是组件内预置文本。" + }, + { + "name": "AddEvent_Text_2", + "value": "改变内容选择区域或编辑状态下的光标位置,触发onSelectionChange回调。" + }, + { + "name": "AddEvent_Text_3", + "value": "触发了onSelectionChange回调,起始范围信息为:(" + }, + { + "name": "AddEvent_Text_4", + "value": "查看回调内容:" + }, + { + "name": "AddEvent_Text_5", + "value": "组件内图文变化前,触发回调。\n图文变化后,触发回调。" + }, + { + "name": "AddEvent_Text_6", + "value": "组件内图文变化前,触发回调:\n" + }, + { + "name": "AddEvent_Text_7", + "value": "\n图文变化后,触发回调:\nrangeBefore:" + }, + { + "name": "AddEvent_Text_8", + "value": "输入法输入内容前,触发回调。\n输入法完成输入后,触发回调。" + }, + { + "name": "AddEvent_Text_9", + "value": "输入法输入内容前,触发aboutToIMEInput回调:\n" + }, + { + "name": "AddEvent_Text_10", + "value": "输入法完成输入后,触发onDidIMEInput回调:\n" + }, + { + "name": "AddEvent_Text_11", + "value": "对此处文本进行复制粘贴操作可触发对应回调。" + }, + { + "name": "AddEvent_Text_12", + "value": "触发onPaste回调\n" + }, + { + "name": "AddEvent_Text_13", + "value": "对此处文本进行复制粘贴操作可触发对应回调。" + }, + { + "name": "AddEvent_Text_14", + "value": "触发onCut回调\n" + }, + { + "name": "AddEvent_Text_15", + "value": "对此处文本进行复制粘贴操作可触发对应回调。" + }, + { + "name": "AddEvent_Text_16", + "value": "触发onCopy回调\n" + }, + { + "name": "AddImageContent_Text_1", + "value": "点击按钮在此处添加image。" + }, + { + "name": "AddSymbolSpanContent_Text_1", + "value": "点击按钮在此处添加symbol。" + }, + { + "name": "AddTextContent_Text_1", + "value": "点击按钮在此处添加text。" + }, + { + "name": "AddTextContent_Text_2", + "value": "新添加一段文字。" + }, + { + "name": "BackplaneHighlighting_Text_1", + "value": "点击按钮在此处选中0-2位置的文本。" + }, + { + "name": "CreateRichEditor_Text_1", + "value": "创建使用属性字符串构建的RichEditor组件。" + }, + { + "name": "CreateRichEditor_Text_2", + "value": "创建不使用属性字符串构建的RichEditor组件。" + }, + { + "name": "GetGraphicInfoInComponent_Text_1", + "value": "点击按钮获取此处span信息。" + }, + { + "name": "GetGraphicInfoInComponent_Text_2", + "value": "查看getSpans返回值:" + }, + { + "name": "SetAttributes_Text_1", + "value": "剪切" + }, + { + "name": "SetAttributes_Text_2", + "value": "复制" + }, + { + "name": "SetAttributes_Text_3", + "value": "粘贴" + }, + { + "name": "SetAttributes_Text_4", + "value": "组件设置了自定义菜单,长按可触发。" + }, + { + "name": "SetAttributes_Text_5", + "value": "组件设置了光标手柄颜色。" + }, + { + "name": "SetAttributes_Text_6", + "value": "此处为提示文本..." + }, + { + "name": "SetAttributes_Text_7", + "value": "组件设置了最大行数\n超出内容将会以滚动显示\n超出1行\n超出2行\n超出3行\n超出4行" + }, + { + "name": "SetAttributes_Text_8", + "value": "组件设置了最大字符数:7" + }, + { + "name": "SetAttributes_Text_9", + "value": "这是一段文本,用来展示选中菜单" + }, + { + "name": "SetUserPresetTextStyles_Text_1", + "value": "点击按钮,改变预设文本样式。" + }, + { + "name": "SymbolAddToText_Text_1", + "value": "单色" + }, + { + "name": "SymbolAddToText_Text_2", + "value": "多色" + }, + { + "name": "SymbolAddToText_Text_3", + "value": "分层" + }, + { + "name": "SymbolAddToText_Text_4", + "value": "无动效" + }, + { + "name": "SymbolAddToText_Text_5", + "value": "整体缩放动效" + }, + { + "name": "SymbolAddToText_Text_6", + "value": "层级动效" + }, + { + "name": "SymbolCustomIconAnimation_Text_1", + "value": "可变颜色动效" + }, + { + "name": "SymbolCustomIconAnimation_Text_2", + "value": "弹跳动效" + }, + { + "name": "SymbolSceneExample_Text_1", + "value": "顺序播放" + }, + { + "name": "SymbolSceneExample_Text_2", + "value": "单曲循环" + }, + { + "name": "SymbolSceneExample_Text_3", + "value": "随机播放" + }, + { + "name": "SymbolSceneExample_Text_4", + "value": "当前播放列表" + }, + { + "name": "SymbolSceneExample_Text_5", + "value": "歌曲一" + }, + { + "name": "SymbolSceneExample_Text_6", + "value": "歌曲二" + }, + { + "name": "SymbolSceneExample_Text_7", + "value": "歌曲三" + }, + { + "name": "SymbolSceneExample_Text_8", + "value": "歌曲四" + }, + { + "name": "SymbolSceneExample_Text_9", + "value": "歌曲五" + }, + { + "name": "SymbolSceneExample_Text_10", + "value": "歌曲六" + }, + { + "name": "SymbolSceneExample_Text_11", + "value": "歌曲七" + }, + { + "name": "SymbolSceneExample_Text_12", + "value": "关闭" + }, + { + "name": "AIMenu_Text_1", + "value": "电话号码:(86) (755) ******** \n \n 链接:www.********.com \n \n 邮箱:***@example.com\n \n 地址:XX省XX市XX区XXXX \n \n 时间:XX年XX月XX日XXXX" + }, + { + "name": "CreateText_Text_1", + "value": "我是一段文本" + }, + { + "name": "SelectMenu_Text_1", + "value": "拦截 id: customMenu2 start:" + }, + { + "name": "SelectMenu_Text_2", + "value": "拦截 COPY start:" + }, + { + "name": "SelectMenu_Text_3", + "value": "不拦截 SELECT_ALL start:" + }, + { + "name": "SelectMenu_Text_4", + "value": "自定义选择菜单弹出时触发该回调" + }, + { + "name": "SelectMenu_Text_5", + "value": "自定义选择菜单关闭时触发该回调" } ] } \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/resources/base/profile/main_pages.json b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/resources/base/profile/main_pages.json index 1898d94f58d6128ab712be2c68acc7c98e9ab9ce..2e5e78d67e7c32c013955029202db9008ddb3f08 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/src/main/resources/base/profile/main_pages.json +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/main/resources/base/profile/main_pages.json @@ -1,5 +1,12 @@ { "src": [ - "pages/Index" + "pages/Index", + "pages/propertyString/CreateApply", + "pages/propertyString/StyledStringStyle", + "pages/propertyString/StyledStringParagraphStyle", + "pages/propertyString/StyledStringImageAttachment", + "pages/propertyString/StyledStringGestureStyle", + "pages/propertyString/StyledStringHtml", + "pages/propertyString/StyledStringSceneExample" ] -} +} \ No newline at end of file diff --git a/code/DocsSample/ArkUISample/TextComponent/entry/src/ohosTest/ets/test/index.test.ets b/code/DocsSample/ArkUISample/TextComponent/entry/src/ohosTest/ets/test/index.test.ets index 74242ee433ae1ba21235b51ea43d9415268bd944..0587758e31376a3f13229678d2e59b8cb8b84af9 100644 --- a/code/DocsSample/ArkUISample/TextComponent/entry/src/ohosTest/ets/test/index.test.ets +++ b/code/DocsSample/ArkUISample/TextComponent/entry/src/ohosTest/ets/test/index.test.ets @@ -13,12 +13,11 @@ * limitations under the License. */ -import { describe, it, expect, beforeAll } from '@ohos/hypium'; +import { describe, it, expect, beforeAll, Level } from '@ohos/hypium'; // 导入测试依赖kit -import { abilityDelegatorRegistry, Driver, ON, MatchPattern } from '@kit.TestKit'; +import { abilityDelegatorRegistry, Driver, ON, MatchPattern, On, Component } from '@kit.TestKit'; import { UIAbility, Want } from '@kit.AbilityKit'; - const delegator: abilityDelegatorRegistry.AbilityDelegator = abilityDelegatorRegistry.getAbilityDelegator(); const bundleName = abilityDelegatorRegistry.getArguments().bundleName; let abilityDelegator: abilityDelegatorRegistry.AbilityDelegator = abilityDelegatorRegistry.getAbilityDelegator(); @@ -50,8 +49,9 @@ export default function IndexTest() { * @tc.number UiTest_001 * @tc.name testCreateText * @tc.desc 测试文本创建场景示例 + * @tc.level: Level 1 */ - it('testCreateText', 0, async (done: Function) => { + it('testCreateText', Level.LEVEL1, async (done: Function) => { console.info('uitest: testCreateText begin'); let driver = Driver.create(); let buttonComponent = await driver.findComponent(ON.text('Text', MatchPattern.CONTAINS)); @@ -62,8 +62,10 @@ export default function IndexTest() { expect(sampleButton === null).assertFalse(); await sampleButton.click(); - let textString = await driver.findComponent(ON.text('This is a text string', MatchPattern.CONTAINS)); - let textResource = await driver.findComponent(ON.text('module description', MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.CreateText_Text_1')); + let textString = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.module_desc')); + let textResource = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); expect(textString === null).assertFalse(); expect(textResource === null).assertFalse(); await driver.pressBack(); @@ -74,10 +76,11 @@ export default function IndexTest() { /** * @tc.number UiTest_002 - * @tc.name testCreateText + * @tc.name testTextSpan * @tc.desc 测试文本段创建场景示例 + * @tc.level: Level 1 */ - it('testTextSpan', 0, async (done: Function) => { + it('testTextSpan', Level.LEVEL1, async (done: Function) => { console.info('uitest: testTextSpan begin'); let driver = Driver.create(); let componentButton = await driver.findComponent(ON.text('Text', MatchPattern.CONTAINS)); @@ -90,13 +93,28 @@ export default function IndexTest() { str = await getResourceString($r('app.string.TextSpan_textContent_2')); let textSpan = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.TextSpan_textContent_3')); + let textColorSpan1 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); str = await getResourceString($r('app.string.TextSpan_textContent_4')); - let textColorSpan = await driver.findComponent(ON.text('我是Span2', MatchPattern.CONTAINS)); + let textColorSpan2 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.TextSpan_textContent_5')); + let textColorSpan3 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + + let uppercase = await driver.findComponent(ON.text('I am Upper-span', MatchPattern.CONTAINS)); + expect(uppercase === null).assertFalse(); + + let textBeforeClick = await driver.findComponent(ON.text('I am Upper-span2', MatchPattern.CONTAINS)); + expect(textBeforeClick === null).assertFalse(); + await textBeforeClick.click(); str = await getResourceString($r('app.string.TextSpan_textContent_6')); - let textCase = await driver.findComponent(ON.text('I am Upper-span', MatchPattern.CONTAINS)); + let textAfterClick = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(textSpan === null).assertFalse(); - expect(textColorSpan === null).assertFalse(); - expect(textCase === null).assertFalse(); + expect(textColorSpan1 === null).assertFalse(); + expect(textColorSpan2 === null).assertFalse(); + expect(textColorSpan3 === null).assertFalse(); + expect(textColorSpan3 === null).assertFalse(); + expect(textAfterClick === null).assertFalse(); await driver.pressBack(); await driver.pressBack(); console.info('uitest: testTextSpan end'); @@ -107,8 +125,9 @@ export default function IndexTest() { * @tc.number UiTest_003 * @tc.name testCustomTextStyle * @tc.desc 测试自定义文本样式场景示例 + * @tc.level: Level 1 */ - it('testCustomTextStyle', 0, async (done: Function) => { + it('testCustomTextStyle', Level.LEVEL1, async (done: Function) => { console.info('uitest: testCustomTextStyle begin'); let driver = Driver.create(); let buttonComponent = await driver.findComponent(ON.text('Text', MatchPattern.CONTAINS)); @@ -125,9 +144,85 @@ export default function IndexTest() { let textCenter = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); str = await getResourceString($r('app.string.TextAlign_End')); let textRight = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + + let longText1 = await driver.findComponent(ON.text( + 'This is the setting of textOverflow to Clip text content This is the setting of textOverflow ' + + 'to None text content. This is the setting of textOverflow to Clip text content This is the setting ' + + 'of textOverflow to None text content.', MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.CustomTextStyle_textContent_1')); + let longText2 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.CustomTextStyle_textContent_2')); + let longText3 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.CustomTextStyle_textContent_8')); + let longText4 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + + let customLineHeight = await driver.findComponent(ON.text( + 'This is the text with the line height set. This is the text with the line height set.', + MatchPattern.CONTAINS)); + let customTextLineAndColor = await driver.findComponent(ON.text('This is the text', MatchPattern.CONTAINS)); + + let scrollComponent: Component = await driver.waitForComponent(ON.id('scroll_'), 1000); + let scrollCenter = await scrollComponent.getBoundsCenter(); + await driver.swipe(scrollCenter.x, scrollCenter.y + 400, scrollCenter.x, scrollCenter.y - 400, 3000); + await driver.waitForIdle(500, 500); + + let customTextBaselineOffset1 = + await driver.findComponent(ON.text('This is the text content with baselineOffset 0.', MatchPattern.CONTAINS)); + let customTextBaselineOffset2 = + await driver.findComponent(ON.text('This is the text content with baselineOffset 30.', MatchPattern.CONTAINS)); + let customTextBaselineOffset3 = + await driver.findComponent(ON.text('This is the text content with baselineOffset -20.', MatchPattern.CONTAINS)); + let customTextLetterSpace1 = + await driver.findComponent(ON.text('This is the text content with letterSpacing 0.', MatchPattern.CONTAINS)); + let customTextLetterSpace2 = + await driver.findComponent(ON.text('This is the text content with letterSpacing 3.', MatchPattern.CONTAINS)); + let customTextLetterSpace3 = + await driver.findComponent(ON.text('This is the text content with letterSpacing -1.', MatchPattern.CONTAINS)); + + await driver.swipe(scrollCenter.x, scrollCenter.y + 400, scrollCenter.x, scrollCenter.y - 400, 3000); + await driver.waitForIdle(500, 500); + + str = await getResourceString($r('app.string.CustomTextStyle_textContent_3')); + let customTheSizeOfText1 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.CustomTextStyle_textContent_4')); + let customTheSizeOfText2 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.CustomTextStyle_textContent_5')); + let customTheSizeOfText3 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.CustomTextStyle_textContent_6')); + let customTheSizeOfText4 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + let textCase1 = await driver.findComponent(ON.text('This is the text content with textCase set to Normal.', + MatchPattern.CONTAINS)); + let textCase2 = await driver.findComponent(ON.text('This is the text content with textCase set to LowerCase.', + MatchPattern.CONTAINS)); + let textCase3 = await driver.findComponent(ON.text('This is the text content with textCase set to UpperCase.', + MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.CustomTextStyle_textContent_7')); + let copyOption = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(textLeft === null).assertFalse(); expect(textCenter === null).assertFalse(); expect(textRight === null).assertFalse(); + expect(longText1 === null).assertFalse(); + expect(longText2 === null).assertFalse(); + expect(longText3 === null).assertFalse(); + expect(longText4 === null).assertFalse(); + expect(customLineHeight === null).assertFalse(); + expect(customTextLineAndColor === null).assertFalse(); + expect(customTextBaselineOffset1 === null).assertFalse(); + expect(customTextBaselineOffset2 === null).assertFalse(); + expect(customTextBaselineOffset3 === null).assertFalse(); + expect(customTextLetterSpace1 === null).assertFalse(); + expect(customTextLetterSpace2 === null).assertFalse(); + expect(customTextLetterSpace3 === null).assertFalse(); + expect(customTheSizeOfText1 === null).assertFalse(); + expect(customTheSizeOfText2 === null).assertFalse(); + expect(customTheSizeOfText3 === null).assertFalse(); + expect(customTheSizeOfText4 === null).assertFalse(); + expect(textCase1 === null).assertFalse(); + expect(textCase2 === null).assertFalse(); + expect(textCase3 === null).assertFalse(); + expect(copyOption === null).assertFalse(); + await driver.pressBack(); await driver.pressBack(); console.info('uitest: testCustomTextStyle end'); @@ -138,8 +233,9 @@ export default function IndexTest() { * @tc.number UiTest_004 * @tc.name testTextAddEvent * @tc.desc 测试文本增加事件场景示例 + * @tc.level: Level 1 */ - it('testTextAddEvent', 0, async (done: Function) => { + it('testTextAddEvent', Level.LEVEL1, async (done: Function) => { console.info('uitest: testTextAddEvent begin'); let driver = Driver.create(); let buttonComponent = await driver.findComponent(ON.text('Text', MatchPattern.CONTAINS)); @@ -155,6 +251,7 @@ export default function IndexTest() { await textClick.click(); str = await getResourceString($r('app.string.TextAddEvent_textContent_2')); expect(await textClick.getText() === str).assertTrue(); + await driver.pressBack(); await driver.pressBack(); console.info('uitest: testTextAddEvent end'); @@ -163,10 +260,65 @@ export default function IndexTest() { /** * @tc.number UiTest_005 + * @tc.name testSelectMenu + * @tc.desc 测试设置选中菜单场景示例 + * @tc.level: Level 1 + */ + it('testSelectMenu', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testSelectMenu begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('Text', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.SetSelectionMenu_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + str = await getResourceString($r('app.string.SelectMenu_textContent_1')); + let selectMenuText = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(selectMenuText === null).assertFalse(); + + await driver.pressBack(); + await driver.pressBack(); + console.info('uitest: testSelectMenu end'); + done(); + }) + + /** + * @tc.number UiTest_006 + * @tc.name testAIMenu + * @tc.desc 测试设置AI菜单场景示例 + * @tc.level: Level 1 + */ + it('testAIMenu', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testAIMenu begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('Text', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.SetUpAIMenu_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + str = await getResourceString($r('app.string.AIMenu_Text_1')); + let aiMenuText = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(aiMenuText === null).assertFalse(); + + await driver.pressBack(); + await driver.pressBack(); + console.info('uitest: testAIMenu end'); + done(); + }) + + /** + * @tc.number UiTest_007 * @tc.name testHotSearch * @tc.desc 测试热搜榜场景示例 + * @tc.level: Level 1 */ - it('testHotSearch', 0, async (done: Function) => { + it('testHotSearch', Level.LEVEL1, async (done: Function) => { console.info('uitest: testHotSearch begin'); let driver = Driver.create(); let buttonComponent = await driver.findComponent(ON.text('Text', MatchPattern.CONTAINS)); @@ -185,6 +337,27 @@ export default function IndexTest() { expect(textHotSearch2 === null).assertFalse(); expect(textHotSearch3 === null).assertFalse(); expect(textHotSearch4 === null).assertFalse(); + + str = await getResourceString($r('app.string.TextHotSearch_textContent_1')); + let hotText1 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.TextHotSearch_textContent_2')); + let hotText2 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.TextHotSearch_textContent_3')); + let hotText3 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.TextHotSearch_textContent_4')); + let hotText4 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.TextHotSearch_textContent_5')); + let hotText5 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.TextHotSearch_textContent_6')); + let hotText6 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + + expect(hotText1 === null).assertFalse(); + expect(hotText2 === null).assertFalse(); + expect(hotText3 === null).assertFalse(); + expect(hotText4 === null).assertFalse(); + expect(hotText5 === null).assertFalse(); + expect(hotText6 === null).assertFalse(); + await driver.pressBack(); await driver.pressBack(); console.info('uitest: testHotSearch end'); @@ -192,11 +365,12 @@ export default function IndexTest() { }) /** - * @tc.number UiTest_006 + * @tc.number UiTest_008 * @tc.name testCreateTextInput * @tc.desc 测试创建文本输入框场景示例 + * @tc.level: Level 1 */ - it('testCreateTextInput', 0, async (done: Function) => { + it('testCreateTextInput', Level.LEVEL1, async (done: Function) => { console.info('uitest: testCreateTextInput begin'); let driver = Driver.create(); let buttonComponent = await driver.findComponent(ON.text('TextInput', MatchPattern.CONTAINS)); @@ -214,8 +388,10 @@ export default function IndexTest() { expect(textInput === null).assertFalse(); expect(textArea === null).assertFalse(); expect(textArea2 === null).assertFalse(); + await textInput.inputText('textInput'); await textArea.inputText('textArea'); + await driver.pressBack(); await driver.pressBack(); console.info('uitest: testCreateTextInput end'); @@ -223,12 +399,13 @@ export default function IndexTest() { }) /** - * @tc.number UiTest_007 + * @tc.number UiTest_009-1 * @tc.name testSetTextInputType * @tc.desc 测试设置文本输入框类型场景示例 + * @tc.level: Level 1 */ - it('testSetTextInputType', 0, async (done: Function) => { - console.info('uitest: testSetTextInputType begin'); + it('testSetTextInputType1', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testSetTextInputType1 begin'); let driver = Driver.create(); let buttonComponent = await driver.findComponent(ON.text('TextInput', MatchPattern.CONTAINS)); expect(buttonComponent === null).assertFalse(); @@ -240,22 +417,69 @@ export default function IndexTest() { let textInput1 = await driver.findComponent(ON.id('Normal')); let textInput2 = await driver.findComponent(ON.id('Password')); + let textInput3 = await driver.findComponent(ON.id('Email')); + let textInput4 = await driver.findComponent(ON.id('Number')); + expect(textInput1 === null).assertFalse(); expect(textInput2 === null).assertFalse(); - await textInput1.inputText('Normal'); - await textInput2.inputText('Password'); + expect(textInput3 === null).assertFalse(); + expect(textInput4 === null).assertFalse(); + + await textInput1.inputText('aaa'); + await textInput2.inputText('aaa'); + await textInput3.inputText('123456@example.com'); + await textInput4.inputText('123456789'); + await driver.pressBack(); await driver.pressBack(); - console.info('uitest: testSetTextInputType end'); + + console.info('uitest: testSetTextInputType1 end'); done(); }) /** - * @tc.number UiTest_008 + * @tc.number UiTest_009-2 + * @tc.name testSetTextInputType + * @tc.desc 测试设置文本输入框类型场景示例 + * @tc.level: Level 1 + */ + it('testSetTextInputType2', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testSetTextInputType2 begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('TextInput', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.SetTextInputType_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + let textInput5 = await driver.findComponent(ON.id('PhoneNumber')); + let textInput6 = await driver.findComponent(ON.id('NUMBER_DECIMAL')); + let textInput7 = await driver.findComponent(ON.id('URL')); + + expect(textInput5 === null).assertFalse(); + expect(textInput6 === null).assertFalse(); + expect(textInput7 === null).assertFalse(); + + await textInput5.inputText('+86 123-0123-0456'); + await textInput6.inputText('9.15'); + await textInput7.inputText('http://www.example.com'); + + await driver.pressBack(); + await driver.pressBack(); + + console.info('uitest: testSetTextInputType2 end'); + done(); + }) + + /** + * @tc.number UiTest_010 * @tc.name testCustomTextInputStyle * @tc.desc 测试自定义文本输入框样式场景示例 + * @tc.level: Level 1 */ - it('testCustomTextInputStyle', 0, async (done: Function) => { + it('testCustomTextInputStyle', Level.LEVEL1, async (done: Function) => { console.info('uitest: testCustomTextInputStyle begin'); let driver = Driver.create(); let buttonComponent = await driver.findComponent(ON.text('TextInput', MatchPattern.CONTAINS)); @@ -277,11 +501,12 @@ export default function IndexTest() { }) /** - * @tc.number UiTest_009 + * @tc.number UiTest_011 * @tc.name testTextInputAddEvent * @tc.desc 测试文本输入框增加事件场景示例 + * @tc.level: Level 1 */ - it('testTextInputAddEvent', 0, async (done: Function) => { + it('testTextInputAddEvent', Level.LEVEL1, async (done: Function) => { console.info('uitest: testTextInputAddEvent begin'); let driver = Driver.create(); let buttonComponent = await driver.findComponent(ON.text('TextInput', MatchPattern.CONTAINS)); @@ -303,16 +528,154 @@ export default function IndexTest() { }) /** - * @tc.number UiTest_010 + * @tc.number UiTest_012 + * @tc.name testTextInputSelectMenu + * @tc.desc 测试设置选中菜单场景示例 + * @tc.level: Level 1 + */ + it('testTextInputSelectMenu', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testTextInputSelectMenu begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('TextInput', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.SelectionMenu_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + str = await getResourceString($r('app.string.SelectMenu_textContent_1')); + let selectMenuText = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(selectMenuText === null).assertFalse(); + + await driver.pressBack(); + await driver.pressBack(); + console.info('uitest: testTextInputSelectMenu end'); + done(); + }) + + /** + * @tc.number UiTest_013 + * @tc.name testTextInputAutoFill + * @tc.desc 自动填充 + * @tc.level: Level 1 + */ + it('testTextInputAutoFill', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testTextInputAutoFill begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('TextInput', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.Auto_Fill')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + await driver.pressBack(); + await driver.pressBack(); + console.info('uitest: testTextInputAutoFill end'); + done(); + }) + + /** + * @tc.number UiTest_014 + * @tc.name testSetOmissionProperty + * @tc.desc 设置省略属性 + * @tc.level: Level 1 + */ + it('testSetOmissionProperty', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testSetOmissionProperty begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('TextInput', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.Set_Omission_Property')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + str = await getResourceString($r('app.string.Set_Omission_Property_textContent')); + let textInput = await driver.findComponent(ON.type('TextInput', MatchPattern.CONTAINS)); + expect(textInput === null).assertFalse(); + await textInput.click(); + let selectMenuText = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(selectMenuText === null).assertFalse(); + + await driver.pressBack(); + await driver.pressBack(); + console.info('uitest: testSetOmissionProperty end'); + done(); + }) + + /** + * @tc.number UiTest_015 + * @tc.name testKeyboardAvoidance + * @tc.desc 测试键盘避让场景示例 + * @tc.level: Level 1 + */ + it('testKeyboardAvoidance', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testKeyboardAvoidance begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('TextInput', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.KeyboardAvoidance_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + let textInput = await driver.findComponent(ON.type('TextInput')); + await textInput.inputText('textInput'); + await driver.pressBack(); + await driver.pressBack(); + console.info('uitest: testKeyboardAvoidance end'); + done(); + }) + + /** + * @tc.number UiTest_016 + * @tc.name testCursorAvoidance + * @tc.desc 光标避让 + * @tc.level: Level 1 + */ + it('testCursorAvoidance', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testCursorAvoidance begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('TextInput', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let scrollComponent: Component = await driver.waitForComponent(ON.id('scroll_'), 1000); + let scrollCenter = await scrollComponent.getBoundsCenter(); + await driver.swipe(scrollCenter.x, scrollCenter.y + 400, scrollCenter.x, scrollCenter.y - 400, 3000); + await driver.waitForIdle(500, 500); + let str = await getResourceString($r('app.string.CursorAvoidance_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + let TextArea = await driver.findComponent(ON.type('TextArea')); + await TextArea.click(); + await driver.pressBack(); + await driver.pressBack(); + console.info('uitest: testCursorAvoidance end'); + done(); + }) + + /** + * @tc.number UiTest_017 * @tc.name testLoginRegisterPage * @tc.desc 测试登录/注册场景示例 + * @tc.level: Level 1 */ - it('testLoginRegisterPage', 0, async (done: Function) => { + it('testLoginRegisterPage', Level.LEVEL1, async (done: Function) => { console.info('uitest: testLoginRegisterPage begin'); let driver = Driver.create(); let buttonComponent = await driver.findComponent(ON.text('TextInput', MatchPattern.CONTAINS)); expect(buttonComponent === null).assertFalse(); await buttonComponent.click(); + let scrollComponent: Component = await driver.waitForComponent(ON.id('scroll_'), 1000); + let scrollCenter = await scrollComponent.getBoundsCenter(); + await driver.swipe(scrollCenter.x, scrollCenter.y + 400, scrollCenter.x, scrollCenter.y - 400, 3000); + await driver.waitForIdle(500, 500); let str = await getResourceString($r('app.string.LoginRegisterPage_title')); let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); expect(sampleButton === null).assertFalse(); @@ -326,31 +689,925 @@ export default function IndexTest() { await password.inputText('password'); await driver.pressBack(); await driver.pressBack(); + await driver.pressBack(); console.info('uitest: testLoginRegisterPage end'); done(); }) /** - * @tc.number UiTest_011 - * @tc.name testKeyboardAvoidance - * @tc.desc 测试键盘避让场景示例 + * @tc.number UiTest_018 + * @tc.name testCreateRichEditor + * @tc.desc 创建RichEditor组件 + * @tc.level: Level 1 */ - it('testKeyboardAvoidance', 0, async (done: Function) => { - console.info('uitest: testKeyboardAvoidance begin'); + it('testCreateRichEditor', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testCreateRichEditor begin'); let driver = Driver.create(); - let buttonComponent = await driver.findComponent(ON.text('TextInput', MatchPattern.CONTAINS)); + let buttonComponent = await driver.findComponent(ON.text('RichEditor', MatchPattern.CONTAINS)); expect(buttonComponent === null).assertFalse(); await buttonComponent.click(); - let str = await getResourceString($r('app.string.KeyboardAvoidance_title')); + let str = await getResourceString($r('app.string.Create_RichEditor_Component_title')); let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); expect(sampleButton === null).assertFalse(); await sampleButton.click(); + str = await getResourceString($r('app.string.Create_RichEditor_Component_title_1')); + let richEditor1 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.Create_RichEditor_Component_title_2')); + let richEditor2 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(richEditor1 === null).assertFalse(); + expect(richEditor2 === null).assertFalse(); - let textInput = await driver.findComponent(ON.type('TextInput')); - await textInput.inputText('textInput'); await driver.pressBack(); + await driver.waitForIdle(2000, 2000); await driver.pressBack(); - console.info('uitest: testKeyboardAvoidance end'); + console.info('uitest: testCreateRichEditor end'); + done(); + }) + + /** + * @tc.number UiTest_019 + * @tc.name testSetAttributes + * @tc.desc 设置属性 + * @tc.level: Level 1 + */ + it('testSetAttributes', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testSetAttributes begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('RichEditor', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.Set_Attributes_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + let scrollComponent: Component = await driver.waitForComponent(ON.id('scroll_'), 1000); + let scrollCenter = await scrollComponent.getBoundsCenter(); + str = await getResourceString($r('app.string.Set_Attributes_title_1')); + let richEditor1 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.Set_Attributes_title_2')); + let richEditor2 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(richEditor1 === null).assertFalse(); + expect(richEditor2 === null).assertFalse(); + await driver.swipe(scrollCenter.x, scrollCenter.y + 400, scrollCenter.x, scrollCenter.y - 400, 3000); + await driver.waitForIdle(500, 500); + str = await getResourceString($r('app.string.Set_Attributes_title_3')); + let richEditor3 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.Set_Attributes_title_4')); + let richEditor4 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.Set_Attributes_title_5')); + let richEditor5 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.Set_Attributes_title_6')); + let richEditor6 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(richEditor3 === null).assertFalse(); + expect(richEditor4 === null).assertFalse(); + expect(richEditor5 === null).assertFalse(); + expect(richEditor6 === null).assertFalse(); + await driver.waitForIdle(500, 500); + await driver.pressBack(); + await driver.delayMs(1000); + await driver.pressBack(); + await driver.delayMs(1000); + console.info('uitest: testSetAttributes end'); + done(); + }) + + /** + * @tc.number UiTest_020 + * @tc.name testAddEvent + * @tc.desc 添加事件 + * @tc.level: Level 1 + */ + it('testAddEvent', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testAddEvent begin'); + let driver = Driver.create(); + await driver.waitForIdle(500, 500); + let buttonComponent = await driver.findComponent(ON.text('RichEditor', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.Add_Event_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + let scrollComponent: Component = await driver.waitForComponent(ON.id('scroll_'), 1000); + let scrollCenter = await scrollComponent.getBoundsCenter(); + str = await getResourceString($r('app.string.Add_Event_title_1')); + let richEditor1 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.Add_Event_title_2')); + let richEditor2 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.Add_Event_title_3')); + let richEditor3 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.Add_Event_title_4')); + let richEditor4 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(richEditor1 === null).assertFalse(); + expect(richEditor2 === null).assertFalse(); + expect(richEditor3 === null).assertFalse(); + expect(richEditor4 === null).assertFalse(); + + await driver.swipe(scrollCenter.x, scrollCenter.y + 400, scrollCenter.x, scrollCenter.y - 500, 3000); + await driver.waitForIdle(500, 500); + str = await getResourceString($r('app.string.Add_Event_title_5')); + let richEditor5 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.Add_Event_title_6')); + let richEditor6 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + str = await getResourceString($r('app.string.Add_Event_title_7')); + let richEditor7 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(richEditor5 === null).assertFalse(); + expect(richEditor6 === null).assertFalse(); + expect(richEditor7 === null).assertFalse(); + await driver.waitForIdle(500, 500); + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testAddEvent end'); + done(); + }) + + /** + * @tc.number UiTest_021 + * @tc.name testSetUserPresetTextStyles + * @tc.desc 通过setTypingStyle设置用户预设的文本样式 + * @tc.level: Level 1 + */ + it('testSetUserPresetTextStyles', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testSetUserPresetTextStyles begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('RichEditor', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.Set_User_PresetText_Styles_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testSetUserPresetTextStyles end'); + done(); + }) + + /** + * @tc.number UiTest_022 + * @tc.name testBackplaneHighlighting + * @tc.desc 通过setSelection设置组件内的内容选中时部分背板高亮 + * @tc.level: Level 1 + */ + it('testBackplaneHighlighting', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testBackplaneHighlighting begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('RichEditor', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.Backplane_Highlighting_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testBackplaneHighlighting end'); + done(); + }) + + /** + * @tc.number UiTest_023 + * @tc.name testAddTextContent + * @tc.desc 添加文本内容 + * @tc.level: Level 1 + */ + it('testAddTextContent', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testAddTextContent begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('RichEditor', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.Add_TextContent_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + let button = await driver.findComponent(ON.text('addTextSpan')); + expect(button === null).assertFalse(); + await button.click(); + str = await getResourceString($r('app.string.AddTextContent_Text_2')); + let richEditor1 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(richEditor1 === null).assertFalse(); + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testAddTextContent end'); + done(); + }) + + /** + * @tc.number UiTest_024 + * @tc.name testAddImageContent + * @tc.desc 添加图片内容 + * @tc.level: Level 1 + */ + it('testAddImageContent', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testAddImageContent begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('RichEditor', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.Add_ImageContent_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + let button = await driver.findComponent(ON.text('addImageSpan')); + expect(button === null).assertFalse(); + await button.click(); + str = await getResourceString($r('app.string.AddImageContent_Text_1')); + let richEditor1 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(richEditor1 === null).assertFalse(); + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testAddImageContent end'); + done(); + }) + + /** + * @tc.number UiTest_025 + * @tc.name testAddBuilderDecoratorContent + * @tc.desc 添加@Builder装饰器修饰的内容 + * @tc.level: Level 1 + */ + it('testAddBuilderDecoratorContent', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testAddBuilderDecoratorContent begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('RichEditor', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.Add_Builder_DecoratorContent_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + let button = await driver.findComponent(ON.text('addBuilderSpan')); + expect(button === null).assertFalse(); + await button.click(); + str = await getResourceString($r('app.string.AddBuilderDecoratorContent_Text_3')); + let richEditor1 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(richEditor1 === null).assertFalse(); + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testAddBuilderDecoratorContent end'); + done(); + }) + + /** + * @tc.number UiTest_026 + * @tc.name testAddSymbolSpanContent + * @tc.desc 添加SymbolSpan内容 + * @tc.level: Level 1 + */ + it('testAddSymbolSpanContent', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testAddSymbolSpanContent begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('RichEditor', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let scrollComponent: Component = await driver.waitForComponent(ON.id('scroll_'), 1000); + let scrollCenter = await scrollComponent.getBoundsCenter(); + await driver.swipe(scrollCenter.x, scrollCenter.y + 400, scrollCenter.x, scrollCenter.y - 400, 3000); + await driver.waitForIdle(500, 500); + let str = await getResourceString($r('app.string.Add_SymbolSpanContent_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + let button = await driver.findComponent(ON.text('addSymbolSpan')); + expect(button === null).assertFalse(); + await button.click(); + str = await getResourceString($r('app.string.AddSymbolSpanContent_Text_1')); + let richEditor1 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(richEditor1 === null).assertFalse(); + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testAddSymbolSpanContent end'); + done(); + }) + + /** + * @tc.number UiTest_027 + * @tc.name testGetGraphicInfoInComponent + * @tc.desc 获取组件内图文信息 + * @tc.level: Level 1 + */ + it('testGetGraphicInfoInComponent', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testGetGraphicInfoInComponent begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('RichEditor', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let scrollComponent: Component = await driver.waitForComponent(ON.id('scroll_'), 1000); + let scrollCenter = await scrollComponent.getBoundsCenter(); + await driver.swipe(scrollCenter.x, scrollCenter.y + 400, scrollCenter.x, scrollCenter.y - 400, 3000); + await driver.waitForIdle(500, 500); + let str = await getResourceString($r('app.string.Get_GraphicInfo_In_Component_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + let button = await driver.findComponent(ON.text('getSpans')); + expect(button === null).assertFalse(); + await button.click(); + str = await getResourceString($r('app.string.GetGraphicInfoInComponent_Text_1')); + let richEditor1 = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(richEditor1 === null).assertFalse(); + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testGetGraphicInfoInComponent end'); + done(); + }) + + /** + * @tc.number UiTest_028 + * @tc.name testCreatSymbolGlyph + * @tc.desc 测试创建图标场景示例 + * @tc.level: Level 1 + */ + it('testCreatSymbolGlyph', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testCreatSymbolGlyph begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('SymbolGlyph', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.CreatSymbolGlyph_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + let symbolGlyph = await driver.findComponent(ON.type('SymbolGlyph')); + expect(symbolGlyph === null).assertFalse(); + + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testCreatSymbolGlyph end'); + done(); + }) + + /** + * @tc.number UiTest_029 + * @tc.name testSymbolGlyphSpanAddToText + * @tc.desc 测试添加到文本场景示例 + * @tc.level: Level 1 + */ + it('testSymbolGlyphSpanAddToText', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testSymbolGlyphSpanAddToText begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('SymbolGlyph', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.SymbolGlyphSpanAddToText_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + let symbolSpan1 = await driver.findComponent(ON.id('1')); + expect(symbolSpan1 === null).assertFalse(); + + let text2 = await driver.findComponent(ON.text('48')); + expect(text2 === null).assertFalse(); + let text3 = await driver.findComponent(ON.text('72')); + expect(text3 === null).assertFalse(); + let text4 = await driver.findComponent(ON.text('96')); + expect(text4 === null).assertFalse(); + + let symbolSpan2 = await driver.findComponent(ON.id('2')); + expect(symbolSpan2 === null).assertFalse(); + let symbolSpan3 = await driver.findComponent(ON.id('3')); + expect(symbolSpan3 === null).assertFalse(); + let symbolSpan4 = await driver.findComponent(ON.id('4')); + expect(symbolSpan4 === null).assertFalse(); + + let scrollComponent: Component = await driver.waitForComponent(ON.id('scroll_'), 1000); + let scrollCenter = await scrollComponent.getBoundsCenter(); + await driver.swipe(scrollCenter.x, scrollCenter.y + 400, scrollCenter.x, scrollCenter.y - 400, 3000); + await driver.waitForIdle(500, 500); + + let text5 = await driver.findComponent(ON.text('Light')); + expect(text5 === null).assertFalse(); + let text6 = await driver.findComponent(ON.text('Normal')); + expect(text6 === null).assertFalse(); + let text7 = await driver.findComponent(ON.text('Bold')); + expect(text7 === null).assertFalse(); + let text8 = await driver.findComponent(ON.text('Black')); + expect(text8 === null).assertFalse(); + let text9 = await driver.findComponent(ON.text('Green')); + expect(text9 === null).assertFalse(); + let text10 = await driver.findComponent(ON.text('Pink')); + expect(text10 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolAddToText_Text_1')); + let text11 = await driver.findComponent(ON.text(str)); + expect(text11 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolAddToText_Text_2')); + let text12 = await driver.findComponent(ON.text(str)); + expect(text12 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolAddToText_Text_3')); + let text13 = await driver.findComponent(ON.text(str)); + expect(text13 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolAddToText_Text_4')); + let text14 = await driver.findComponent(ON.text(str)); + expect(text14 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolAddToText_Text_5')); + let text15 = await driver.findComponent(ON.text(str)); + expect(text15 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolAddToText_Text_6')); + let text16 = await driver.findComponent(ON.text(str)); + expect(text16 === null).assertFalse(); + + let symbolSpan5 = await driver.findComponent(ON.id('5')); + expect(symbolSpan5 === null).assertFalse(); + let symbolSpan6 = await driver.findComponent(ON.id('6')); + expect(symbolSpan6 === null).assertFalse(); + let symbolSpan7 = await driver.findComponent(ON.id('7')); + expect(symbolSpan7 === null).assertFalse(); + let symbolSpan8 = await driver.findComponent(ON.id('8')); + expect(symbolSpan8 === null).assertFalse(); + let symbolSpan9 = await driver.findComponent(ON.id('9')); + expect(symbolSpan9 === null).assertFalse(); + let symbolSpan10 = await driver.findComponent(ON.id('10')); + expect(symbolSpan10 === null).assertFalse(); + let symbolSpan11 = await driver.findComponent(ON.id('11')); + expect(symbolSpan11 === null).assertFalse(); + let symbolSpan12 = await driver.findComponent(ON.id('12')); + expect(symbolSpan12 === null).assertFalse(); + let symbolSpan13 = await driver.findComponent(ON.id('13')); + expect(symbolSpan13 === null).assertFalse(); + let symbolSpan14 = await driver.findComponent(ON.id('14')); + expect(symbolSpan14 === null).assertFalse(); + let symbolSpan15 = await driver.findComponent(ON.id('15')); + expect(symbolSpan15 === null).assertFalse(); + let symbolSpan16 = await driver.findComponent(ON.id('16')); + expect(symbolSpan16 === null).assertFalse(); + + await driver.pressBack(); + await driver.pressBack(); + console.info('uitest: testSymbolGlyphSpanAddToText end'); + done(); + }) + + /** + * @tc.number UiTest_030 + * @tc.name testSymbolGlyphSpanCustomIconAnimation + * @tc.desc 测试自定义图标动效场景示例 + * @tc.level: Level 1 + */ + it('testSymbolGlyphSpanCustomIconAnimation', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testSymbolGlyphSpanCustomIconAnimation begin'); + let driver = Driver.create(); + await driver.waitForIdle(500, 500); + let buttonComponent = await driver.findComponent(ON.text('SymbolGlyph', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.SymbolGlyphSpanCustomIconAnimation_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + str = await getResourceString($r('app.string.SymbolCustomIconAnimation_Text_1')); + let text1 = await driver.findComponent(ON.text(str)); + expect(text1 === null).assertFalse(); + let symbolGlyph1 = await driver.findComponent(ON.id('1')); + expect(symbolGlyph1 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolGlyphSpanCustomIconAnimation_Button_1')); + let button1 = await driver.findComponent(ON.text(str)); + expect(button1 === null).assertFalse(); + await button1.click(); + str = await getResourceString($r('app.string.SymbolGlyphSpanCustomIconAnimation_Button_2')); + expect(await button1.getText() === str).assertTrue(); + + str = await getResourceString($r('app.string.SymbolCustomIconAnimation_Text_2')); + let text2 = await driver.findComponent(ON.text(str)); + expect(text2 === null).assertFalse(); + let symbolGlyph2 = await driver.findComponent(ON.id('2')); + expect(symbolGlyph2 === null).assertFalse(); + let button2 = await driver.findComponent(ON.text('trigger')); + expect(button2 === null).assertFalse(); + await button1.click(); + await driver.waitForIdle(500, 500); + await driver.pressBack(); + await driver.delayMs(1000); + await driver.pressBack(); + console.info('uitest: testSymbolGlyphSpanCustomIconAnimation end'); + done(); + }) + + /** + * @tc.number UiTest_031 + * @tc.name testSymbolGlyphSpanAddEvent + * @tc.desc 测试添加事件场景示例 + * @tc.level: Level 1 + */ + it('testSymbolGlyphSpanAddEvent', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testSymbolGlyphSpanAddEvent begin'); + let driver = Driver.create(); + await driver.waitForIdle(500, 500); + let buttonComponent = await driver.findComponent(ON.text('SymbolGlyph', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.SymbolGlyphSpanAddEvent_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + let symbolGlyph = await driver.findComponent(ON.id('symbolGlyph1')); + expect(symbolGlyph === null).assertFalse(); + await symbolGlyph.click(); + await driver.waitForIdle(500, 500); + await driver.delayMs(1000); + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testSymbolGlyphSpanAddEvent end'); + done(); + }) + + /** + * @tc.number UiTest_032 + * @tc.name testSymbolGlyphSpanSceneExample + * @tc.desc 测试播放列表场景示例 + * @tc.level: Level 1 + */ + it('testSymbolGlyphSpanSceneExample', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testSymbolGlyphSpanSceneExample begin'); + let driver = Driver.create(); + await driver.waitForIdle(500, 500); + let buttonComponent = await driver.findComponent(ON.text('SymbolGlyph', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.SymbolGlyphSpanSceneExample_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + let text1 = await driver.findComponent(ON.id('text1')); + expect(text1 === null).assertFalse(); + let symbolGlyph1 = await driver.findComponent(ON.id('symbolGlyph1')); + expect(symbolGlyph1 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolSceneExample_Text_1')); + let text = await driver.findComponent(ON.text(str)); + expect(text === null).assertFalse(); + await text.click(); + str = await getResourceString($r('app.string.SymbolSceneExample_Text_2')); + expect(await text.getText() === str).assertTrue(); + await text.click(); + str = await getResourceString($r('app.string.SymbolSceneExample_Text_3')); + expect(await text.getText() === str).assertTrue(); + let text2 = await driver.findComponent(ON.id('text2')); + expect(text2 === null).assertFalse(); + let text3 = await driver.findComponent(ON.id('text3')); + expect(text3 === null).assertFalse(); + let text4 = await driver.findComponent(ON.id('text4')); + expect(text4 === null).assertFalse(); + + str = await getResourceString($r('app.string.SymbolSceneExample_Text_5')); + let text5 = await driver.findComponent(ON.text(str)); + expect(text5 === null).assertFalse(); + let symbolGlyph2 = await driver.findComponent(ON.id('symbolGlyph2')); + expect(symbolGlyph2 === null).assertFalse(); + let symbolGlyph3 = await driver.findComponent(ON.id('symbolGlyph3')); + expect(symbolGlyph3 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolSceneExample_Text_6')); + let text6 = await driver.findComponent(ON.text(str)); + expect(text6 === null).assertFalse(); + let symbolGlyph4 = await driver.findComponent(ON.id('symbolGlyph4')); + expect(symbolGlyph4 === null).assertFalse(); + let symbolGlyph5 = await driver.findComponent(ON.id('symbolGlyph5')); + expect(symbolGlyph5 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolSceneExample_Text_7')); + let text7 = await driver.findComponent(ON.text(str)); + expect(text7 === null).assertFalse(); + let symbolGlyph6 = await driver.findComponent(ON.id('symbolGlyph6')); + expect(symbolGlyph6 === null).assertFalse(); + let symbolGlyph7 = await driver.findComponent(ON.id('symbolGlyph7')); + expect(symbolGlyph7 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolSceneExample_Text_8')); + let text8 = await driver.findComponent(ON.text(str)); + expect(text8 === null).assertFalse(); + let symbolGlyph8 = await driver.findComponent(ON.id('symbolGlyph8')); + expect(symbolGlyph8 === null).assertFalse(); + let symbolGlyph9 = await driver.findComponent(ON.id('symbolGlyph9')); + expect(symbolGlyph9 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolSceneExample_Text_9')); + let text9 = await driver.findComponent(ON.text(str)); + expect(text9 === null).assertFalse(); + let symbolGlyph10 = await driver.findComponent(ON.id('symbolGlyph10')); + expect(symbolGlyph10 === null).assertFalse(); + let symbolGlyph11 = await driver.findComponent(ON.id('symbolGlyph11')); + expect(symbolGlyph11 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolSceneExample_Text_10')); + let text10 = await driver.findComponent(ON.text(str)); + expect(text10 === null).assertFalse(); + let symbolGlyph12 = await driver.findComponent(ON.id('symbolGlyph12')); + expect(symbolGlyph12 === null).assertFalse(); + let symbolGlyph13 = await driver.findComponent(ON.id('symbolGlyph13')); + expect(symbolGlyph13 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolSceneExample_Text_11')); + let text11 = await driver.findComponent(ON.text(str)); + expect(text11 === null).assertFalse(); + let symbolGlyph14 = await driver.findComponent(ON.id('symbolGlyph14')); + expect(symbolGlyph14 === null).assertFalse(); + let symbolGlyph15 = await driver.findComponent(ON.id('symbolGlyph15')); + expect(symbolGlyph15 === null).assertFalse(); + str = await getResourceString($r('app.string.SymbolSceneExample_Text_12')); + let text12 = await driver.findComponent(ON.text(str)); + expect(text12 === null).assertFalse(); + + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testSymbolGlyphSpanSceneExample end'); + done(); + }) + + /** + * @tc.number UiTest_033 + * @tc.name testCreateApply + * @tc.desc 测试创建并应用属性字符串场景示例 + * @tc.level: Level 1 + */ + it('testCreateApply', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testCreateApply begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('StyledString', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.Create_Apply_StyledString_MutableStyledString_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + str = await getResourceString($r('app.string.CreateApply_Text_1')); + let styledString = await driver.findComponent(ON.text(str)); + expect(styledString === null).assertFalse(); + str = await getResourceString($r('app.string.CreateApply_Text_2')); + let mutableStyledString = await driver.findComponent(ON.text(str)); + expect(mutableStyledString === null).assertFalse(); + + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testCreateApply end'); + done(); + }) + + /** + * @tc.number UiTest_034 + * @tc.name testStyledStringStyle + * @tc.desc 测试设置文本样式场景示例 + * @tc.level: Level 1 + */ + it('testStyledStringStyle', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testStyledStringStyle begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('StyledString', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.StyledStringStyle_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + let mutableStyledString1 = await driver.findComponent(ON.id('1')); + expect(mutableStyledString1 === null).assertFalse(); + let mutableStyledString2 = await driver.findComponent(ON.id('2')); + expect(mutableStyledString2 === null).assertFalse(); + let mutableStyledString3 = await driver.findComponent(ON.id('3')); + expect(mutableStyledString3 === null).assertFalse(); + let mutableStyledString4 = await driver.findComponent(ON.id('4')); + expect(mutableStyledString4 === null).assertFalse(); + let mutableStyledString5 = await driver.findComponent(ON.id('5')); + expect(mutableStyledString5 === null).assertFalse(); + let mutableStyledString6 = await driver.findComponent(ON.id('6')); + expect(mutableStyledString6 === null).assertFalse(); + + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testStyledStringStyle end'); + done(); + }) + + /** + * @tc.number UiTest_035 + * @tc.name testStyledStringParagraphStyle + * @tc.desc 测试设置段落样式场景示例 + * @tc.level: Level 1 + */ + it('testStyledStringParagraphStyle', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testStyledStringParagraphStyle begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('StyledString', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.StyledStringParagraphStyle_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + str = await getResourceString($r('app.string.StyledStringParagraphStyle_Text_1')); + let mutableStyledString1 = + await driver.findComponent(ON.text(str)); + expect(mutableStyledString1 === null).assertFalse(); + let button = await driver.findComponent(ON.text('change')); + expect(button === null).assertFalse(); + await button.click(); + await driver.waitForIdle(500, 500); + + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testStyledStringParagraphStyle end'); + done(); + }) + + /** + * @tc.number UiTest_036 + * @tc.name testStyledStringImageAttachment + * @tc.desc 测试使用图片场景示例 + * @tc.level: Level 1 + */ + it('testStyledStringImageAttachment', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testStyledStringImageAttachment begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('StyledString', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.StyledStringImageAttachment_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + str = await getResourceString($r('app.string.StyledStringImageAttachment_Button_1')); + let button = await driver.findComponent(ON.text(str)); + expect(button === null).assertFalse(); + await button.click(); + await driver.waitForIdle(500, 500); + let text1 = await driver.findComponent(ON.id('text1')); + expect(text1 === null).assertFalse(); + + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testStyledStringImageAttachment end'); + done(); + }) + + /** + * @tc.number UiTest_037 + * @tc.name testStyledStringGestureStyle + * @tc.desc 测试设置事件场景示例 + * @tc.level: Level 1 + */ + it('testStyledStringGestureStyle', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testStyledStringGestureStyle begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('StyledString', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.TStyledStringGestureStyle_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + let text1 = await driver.findComponent(ON.id('text1')); + expect(text1 === null).assertFalse(); + + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testStyledStringGestureStyle end'); + done(); + }) + + /** + * @tc.number UiTest_038 + * @tc.name testStyledStringHtml + * @tc.desc 测试格式转换场景示例 + * @tc.level: Level 1 + */ + it('testStyledStringHtml', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testStyledStringHtml begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('StyledString', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.StyledStringHtml_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + str = await getResourceString($r('app.string.StyledStringHtml_Button_1')); + let addButton = await driver.findComponent(ON.text(str)); + expect(addButton === null).assertFalse(); + await addButton.click(); + await driver.waitForIdle(500, 500); + let text1 = await driver.findComponent(ON.id('text1')); + expect(text1 === null).assertFalse(); + + let toHtmlButton = await driver.findComponent(ON.text('toHtml')); + expect(toHtmlButton === null).assertFalse(); + await toHtmlButton.click(); + await driver.waitForIdle(500, 500); + let text3 = await driver.findComponent(ON.id('text3')); + expect(text3 === null).assertFalse(); + + let fromHtmlButton = await driver.findComponent(ON.text('fromHtml')); + expect(fromHtmlButton === null).assertFalse(); + await fromHtmlButton.click(); + await driver.waitForIdle(500, 500); + let text2 = await driver.findComponent(ON.id('text2')); + expect(text2 === null).assertFalse(); + + await driver.pressBack(); + await driver.waitForIdle(3000, 3000); + await driver.pressBack(); + console.info('uitest: testStyledStringHtml end'); + done(); + }) + + /** + * @tc.number UiTest_039 + * @tc.name testStyledStringSceneExample + * @tc.desc 测试会员过期提示场景示例 + * @tc.level: Level 1 + */ + it('testStyledStringSceneExample', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testStyledStringSceneExample begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('StyledString', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.StyledStringSceneExample_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + let text1 = await driver.findComponent(ON.id('text1')); + expect(text1 === null).assertFalse(); + str = await getResourceString($r('app.string.StyledStringSceneExample_Button_1')); + let button = await driver.findComponent(ON.text(str)); + expect(button === null).assertFalse(); + + await driver.pressBack(); + await driver.waitForIdle(2000, 2000); + await driver.pressBack(); + console.info('uitest: testStyledStringSceneExample end'); + done(); + }) + + /** + * @tc.number UiTest_040 + * @tc.name testTextDrawingDisplay + * @tc.desc 测试Text组件的文本绘制与显示场景示例 + * @tc.level: Level 1 + */ + it('testTextDrawingDisplay', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testTextDrawingDisplay begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('NDK', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.TextDrawingDisplay_NDK_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + let text = await driver.findComponent(ON.type('Text')); + expect(text === null).assertFalse(); + + await driver.pressBack(); + await driver.pressBack(); + console.info('uitest: testTextDrawingDisplay end'); + done(); + }) + + /** + * @tc.number UiTest_041 + * @tc.name testListenTextBoxEvents + * @tc.desc 测试输入框文本事件监听场景示例 + * @tc.level: Level 1 + */ + it('testListenTextBoxEvents', Level.LEVEL1, async (done: Function) => { + console.info('uitest: testListenTextBoxEvents begin'); + let driver = Driver.create(); + let buttonComponent = await driver.findComponent(ON.text('NDK', MatchPattern.CONTAINS)); + expect(buttonComponent === null).assertFalse(); + await buttonComponent.click(); + let str = await getResourceString($r('app.string.ListenTextBoxEvents_NDK_title')); + let sampleButton = await driver.findComponent(ON.text(str, MatchPattern.CONTAINS)); + expect(sampleButton === null).assertFalse(); + await sampleButton.click(); + + let textArea = await driver.findComponent(ON.type('TextArea')); + expect(textArea === null).assertFalse(); + + await driver.pressBack(); + await driver.pressBack(); + console.info('uitest: testListenTextBoxEvents end'); done(); }) }) diff --git a/code/DocsSample/ArkUISample/TextComponent/screenshots/device/image1.png b/code/DocsSample/ArkUISample/TextComponent/screenshots/device/image1.png index 6c0e5b4f315ad520a9c6a67da376587056af6c2b..bf96a4175ed623325acd0dfe3cbc57e23a6f9c66 100644 Binary files a/code/DocsSample/ArkUISample/TextComponent/screenshots/device/image1.png and b/code/DocsSample/ArkUISample/TextComponent/screenshots/device/image1.png differ diff --git a/code/DocsSample/ArkUISample/TextComponent/screenshots/device/image2.jpeg b/code/DocsSample/ArkUISample/TextComponent/screenshots/device/image2.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..8516710ce8b4ac1f3790841aa45d0302809e7c25 Binary files /dev/null and b/code/DocsSample/ArkUISample/TextComponent/screenshots/device/image2.jpeg differ diff --git a/code/DocsSample/ArkUISample/TextComponent/screenshots/device/image3.jpeg b/code/DocsSample/ArkUISample/TextComponent/screenshots/device/image3.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..ad6f0ba651630c7a10d878035860f8bd406676f2 Binary files /dev/null and b/code/DocsSample/ArkUISample/TextComponent/screenshots/device/image3.jpeg differ