diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityBackRunning.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityBackRunning.ets new file mode 100644 index 0000000000000000000000000000000000000000..133beca2e76cb7fc3dbd1eb113c66c94d662e7af --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityBackRunning.ets @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在代码中触发应用后台运行 +*/ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + // [Start entry_ability_back_running] + AppStorage.setOrCreate('context',windowStage); + // [End entry_ability_back_running] + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + const context = windowStage.getMainWindowSync().getUIContext(); + AppStorage.setOrCreate("context", context); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityDisplayAdaptationRotation.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityDisplayAdaptationRotation.ets new file mode 100644 index 0000000000000000000000000000000000000000..1d2e264725264033c4c0252ac5d9c5f39162bbb1 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityDisplayAdaptationRotation.ets @@ -0,0 +1,96 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现折叠屏折叠态不适配旋转,展示态适配旋转 +*/ + +// [Start entry_ability_display_adaptation_rotation] +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { display, window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + + onDestroy(): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + + windowStage.loadContent('pages/Index', (err) => { + 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.'); + }); + + + windowStage.getMainWindow().then((windowObj) => { + let orientation = display.getFoldStatus() === display.FoldStatus.FOLD_STATUS_EXPANDED ? + window.Orientation.AUTO_ROTATION : window.Orientation.PORTRAIT; + windowObj?.setPreferredOrientation(orientation); + + + // Monitor the unfolded or folded state of the foldable screen + display.on('foldStatusChange', (foldStatus: display.FoldStatus) => { + orientation = foldStatus === display.FoldStatus.FOLD_STATUS_EXPANDED ? window.Orientation.AUTO_ROTATION : + window.Orientation.PORTRAIT; + try { + windowObj?.setPreferredOrientation(orientation, (err: BusinessError) => { + const errCode: number = err.code; + if (errCode) { + console.error(`Failed to set window orientation. Cause code: ${err.code}, message: ${err.message}`); + return; + } + console.info('Succeeded in setting window orientation.'); + }); + } catch (exception) { + console.error(`Failed to set window orientation. Cause code: ${exception.code}, message: ${exception.message}`); + } + }) + }); + } + + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + + onForeground(): void { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + + onBackground(): void { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +} +// [End entry_ability_display_adaptation_rotation] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityFloatingFrame.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityFloatingFrame.ets new file mode 100644 index 0000000000000000000000000000000000000000..a39b21bb4e048044abceafab956d822338ce9cf5 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityFloatingFrame.ets @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现通过侧滑手势关闭打开的悬浮框 +*/ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + // [Start entry_ability_floating_frame] + onWindowStageCreate(windowStage: window.WindowStage): void { + // 创建应用子窗口 + let windowClass: window.Window | undefined = undefined; + windowStage.createSubWindow('mySubWindow', (err: BusinessError, data) => { + if (err.code) { + console.error(`Failed to create the subwindow. Cause code: ${err.code}, message: ${err.message}`); + return; + } + windowClass = data; + console.info('Succeeded in creating the subwindow. Data: ' + JSON.stringify(data)); + // 子窗口创建成功后,设置子窗口的位置、大小及相关属性等 + windowClass.moveWindowTo(300, 300); + windowClass.resize(200, 200); + windowClass.setWindowTouchable(true); + // 为子窗口加载对应的目标页面 + windowClass.setUIContent('pages/Index',(err: BusinessError) => { + if (err.code) { + console.error(`Failed to load the content. Cause code: ${err.code}, message: ${err.message}`); + return; + } + if (windowClass) { + windowClass.setWindowBackgroundColor('#64b38c'); + } + }); + (windowClass as window.Window).showWindow(); + }) + // ... + } + // [End entry_ability_floating_frame] +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityFocusUnresponsive.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityFocusUnresponsive.ets new file mode 100644 index 0000000000000000000000000000000000000000..a02544def7c3c870f994788c5b5976db68d6e22a --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityFocusUnresponsive.ets @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何解决window创建的模态窗口默认焦点不在界面上,导致不响应返回事件的问题 +*/ + +// [Start entry_ability_focus_unresponsive] +// EntryAbility.ets +import { UIAbility } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { window } from '@kit.ArkUI'; + + +export default class EntryAbility extends UIAbility { + onWindowStageCreate(windowStage: window.WindowStage): void { + console.info('onWindowStageCreate'); + let windowClass: window.Window | undefined = undefined; + let config: window.Configuration = { + name: "test", + windowType: window.WindowType.TYPE_DIALOG, + ctx: this.context + }; + try { + window.createWindow(config, (err: BusinessError, data) => { + const errCode: number = err.code; + if (errCode) { + console.error(`Failed to create the window. Cause code: ${err.code}, message: ${err.message}`); + return; + } + windowClass = data; + windowClass.setUIContent('pages/Index'); + let enabled = true; + let promise = windowClass.setDialogBackGestureEnabled(enabled); + promise.then(() => { + console.info('Succeeded in setting dialog window to respond back gesture.'); + }).catch((err: BusinessError) => { + console.error(`Failed to set dialog window to respond back gesture. Cause code: ${err.code}, message: ${err.message}`); + }); + }); + } catch (exception) { + console.error(`Failed to create the window. Cause code: ${exception.code}, message: ${exception.message}`); + } + } +} +// [End entry_ability_focus_unresponsive] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityForWindow.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityForWindow.ets new file mode 100644 index 0000000000000000000000000000000000000000..d5c952e4df15e39ef52bb1cee072d263ac859214 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityForWindow.ets @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取窗口的宽高信息 +*/ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // [Start entry_ability_for_window] + //If you need to get the window width and height information in the page, it is recommended to put the following code in the onPageShow stage of the page life cycle, rather than calling it in the aboutToAppear stage of the page life cycle + let windowClass: window.Window | undefined = undefined; + try { + let promise = window.getLastWindow(this.context); + promise.then((data)=> { + //Get window object + windowClass = data; + try { + //Get window properties + let properties = windowClass.getWindowProperties(); + let rect = properties.windowRect; + //rect.width: Window Width;rect.height: Window height + } catch (exception) { + console.error('Failed to obtain the window properties. Cause: ' + JSON.stringify(exception)); + } + console.info('Succeeded in obtaining the top window. Data: ' + JSON.stringify(data)); + }).catch((err: BusinessError)=>{ + console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(err)); + });} catch (exception) { + console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(exception)); + } + // [End entry_ability_for_window] + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityFullScreenStatus.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityFullScreenStatus.ets new file mode 100644 index 0000000000000000000000000000000000000000..7ce58b5d497e5671dab8b9d5363eef8d37efc098 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityFullScreenStatus.ets @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:进入全屏模式后隐藏状态栏,退出全屏模式如何显示状态栏? +*/ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + // [Start entry_ability_full_screen_status] + // EntryAbility.ets + + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + + windowStage.loadContent('pages/GridImage', (err) => { + 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.'); + + + let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口 + // 1. 设置窗口全屏 + let isLayoutFullScreen = true; + windowClass.setWindowLayoutFullScreen(isLayoutFullScreen); + // 2. 缓存window窗口对象 + AppStorage.setOrCreate('windowClass', windowClass); + }); + } + // [End entry_ability_full_screen_status] +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityGetHeightAndStatus.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityGetHeightAndStatus.ets new file mode 100644 index 0000000000000000000000000000000000000000..86808d7dd55501e7a8bc4b26e73dd23f7e903187 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityGetHeightAndStatus.ets @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取状态栏和导航栏高度 +*/ + +// [Start entry_ability_height_and_status] +// MainAbility.ets +import { common, UIAbility } from '@kit.AbilityKit'; +import { window } from '@kit.ArkUI'; + +/** + * Get the height of the system status bar and navigation bar + * @param context + * @returns + */ +async function getWindowAvoidArea(context: common.UIAbilityContext): Promise { + try { + const mainWindow = await window.getLastWindow(context); + const avoidAreaType = window.AvoidAreaType.TYPE_SYSTEM; // The default area of the system includes the status bar and navigation bar + const avoidArea = mainWindow.getWindowAvoidArea(avoidAreaType); + const height = avoidArea.topRect.height; + return avoidArea + } catch (e) { + console.log('getWindowAvoidArea fail'); + return null + } +} + +export default class MainAbility extends UIAbility { + // do something + async onWindowStageCreate(windowStage: window.WindowStage) { + getWindowAvoidArea(this.context); + windowStage.loadContent('pages/index'); + } + // do something +} +// [End entry_ability_height_and_status] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityHorizontalAndVertical.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityHorizontalAndVertical.ets new file mode 100644 index 0000000000000000000000000000000000000000..5c6a59e70d3c39ecbdd291879b153aae4ae275e6 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityHorizontalAndVertical.ets @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何进行页面横竖屏切换 +*/ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + let windowClass: window.Window = window.findWindow("test"); + // [Start entry_ability_horizontal_and_vertical] + let orientation = window.Orientation.AUTO_ROTATION; + try{ + windowClass.setPreferredOrientation(orientation, (err) => { + if(err.code){ + console.error('Failed to set window orientation. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting window orientation.'); + }); + }catch (exception) { + console.error('Failed to set window orientation. Cause: ' + JSON.stringify(exception)); + } + // [End entry_ability_horizontal_and_vertical] + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersingBackgroundColor_One.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersingBackgroundColor_One.ets new file mode 100644 index 0000000000000000000000000000000000000000..0377be3ec78f4a3f20a5d0a3e84fa6b238edb06a --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersingBackgroundColor_One.ets @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现状态栏背景颜色沉浸? +*/ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + // [Start entry_ability_immersing_background_color_one] + // EntryAbility.ets + + + onWindowStageCreate(windowStage: window.WindowStage): void { + windowStage.loadContent('pages/Example', (err, data) => { + if (err.code) { + return; + } + // Set the full window color to match the color of the application elements + windowStage.getMainWindowSync().setWindowBackgroundColor('#008000'); + }); + } + // [End entry_ability_immersing_background_color_one] +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersingBackgroundColor_Two.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersingBackgroundColor_Two.ets new file mode 100644 index 0000000000000000000000000000000000000000..dc54d71bf60c0fdfbd9355048b52e57fe9d6c4ec --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersingBackgroundColor_Two.ets @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现状态栏背景颜色沉浸? +*/ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + // [Start entry_ability_immersing_background_color_two] + // EntryAbility.ets + + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + + windowStage.loadContent('pages/Index', (err) => { + 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.'); + let windowClass: window.Window = windowStage.getMainWindowSync(); // Get the main window of the application + // 1. Set the window to full screen + let isLayoutFullScreen = true; + windowClass.setWindowLayoutFullScreen(isLayoutFullScreen); + // 2. Cache window object + AppStorage.setOrCreate('windowClass', windowClass); + }); + } + // [End entry_ability_immersing_background_color_two] +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersivePages.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersivePages.ets new file mode 100644 index 0000000000000000000000000000000000000000..95beab0b96fa3e3b6efe157324aefe7705b6fa7b --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersivePages.ets @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现沉浸式页面(包括沉浸式状态栏、沉浸式导航条) +*/ + +// [Start entry_ability_immersive_pages] +import { UIAbility } from '@kit.AbilityKit'; +import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + + +export default class EntryAbility extends UIAbility { + onWindowStageCreate(windowStage: window.WindowStage) { + // 1.Get the main window of the application. + let windowClass: window.Window | undefined = undefined; + windowStage.getMainWindow().then(windowClass => { + console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(windowClass)); + // 2.Set the window to full screen to achieve immersive effects. + windowClass.setWindowLayoutFullScreen(true).then(() => { + console.info('Succeeded in setting the window layout to full-screen mode.'); + }).catch((e: BusinessError) => { + console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(e)); + }) + }).catch((err: BusinessError) => { + console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err)); + }) + // 3.Load the corresponding target page for the immersive window. + windowStage.loadContent("pages/Index", (err) => { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content.'); + }); + } +}; +// [End entry_ability_immersive_pages] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersiveStatusBar.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersiveStatusBar.ets new file mode 100644 index 0000000000000000000000000000000000000000..ebfed506c636b6c3f64dfd0152b3c14cb1a8fcc0 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersiveStatusBar.ets @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何设置沉浸式状态栏 +*/ + +// [Start entry_ability_immersive_status_bar] +import { UIAbility } from '@kit.AbilityKit'; +import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + + +export default class EntryAbility extends UIAbility { + onWindowStageCreate(windowStage: window.WindowStage) { + // 1.Get the main window of the application. + let windowClass: window.Window | undefined = undefined; + windowStage.getMainWindow((err: BusinessError, data) => { + if (err.code) { + console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err)); + return; + } + windowClass = data; + console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(data)); + + + // 2.Realize immersive effects. Method 1: Set the navigation bar and status bar to not display. + let names = []; + windowClass.setWindowSystemBarEnable(names, (err) => { + if (err.code) { + console.error('Failed to set the system bar to be visible. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the system bar to be visible.'); + }); + // 2.Realize immersive effects. Method 2: Set the window to a full screen layout, and coordinate with the transparency, background/text color, and highlighted icons of the navigation bar and status bar to maintain consistency with the main window display. + let isLayoutFullScreen = true; + windowClass.setWindowLayoutFullScreen(isLayoutFullScreen, (err) => { + if (err.code) { + console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the window layout to full-screen mode.'); + }); + let sysBarProps: window.SystemBarProperties = { + statusBarColor: '#ff00ff', + navigationBarColor: '#00ff00', + // The following two attributes are supported starting from API Version 8 + statusBarContentColor: '#ffffff', + navigationBarContentColor: '#ffffff' + }; + windowClass.setWindowSystemBarProperties(sysBarProps, (err) => { + if (err.code) { + console.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the system bar properties.'); + }); + }) + // 3.Load the corresponding target page for the immersive window. + windowStage.loadContent("pages/page2", (err) => { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content.'); + }); + } +}; +// [End entry_ability_immersive_status_bar] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersiveWindow.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersiveWindow.ets new file mode 100644 index 0000000000000000000000000000000000000000..4636d2e7666b99f4ab1d358a954554e79e59827f --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityImmersiveWindow.ets @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何设置沉浸式窗口 +*/ + +// [Start entry_ability_immersive_window] +import { UIAbility } from '@kit.AbilityKit'; +import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + +export default class EntryAbility extends UIAbility { + onWindowStageCreate(windowStage: window.WindowStage) { + // 1.Get the main window of the application. + let windowClass: window.Window | null = null; + windowStage.getMainWindow((err: BusinessError, data) => { + let errCode: number = err.code; + if (errCode) { + console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err)); + return; + } + windowClass = data; + console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(data)); + + // 2.Realize immersive effects. Method 1: Set the navigation bar and status bar to not display. + let names: Array<'status' | 'navigation'> = []; + windowClass.setWindowSystemBarEnable(names, (err: BusinessError) => { + let errCode: number = err.code; + if (errCode) { + console.error('Failed to set the system bar to be visible. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the system bar to be visible.'); + }); + // 2.Realize immersive effects. Method 2: Set the window to a full screen layout, and coordinate with the transparency, background/text color, and highlighted icons of the navigation bar and status bar to maintain consistency with the main window display. + let isLayoutFullScreen = true; + windowClass.setWindowLayoutFullScreen(isLayoutFullScreen, (err: BusinessError) => { + let errCode: number = err.code; + if (errCode) { + console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the window layout to full-screen mode.'); + }); + let sysBarProps: window.SystemBarProperties = { + statusBarColor: '#ff00ff', + navigationBarColor: '#00ff00', + statusBarContentColor: '#ffffff', + navigationBarContentColor: '#ffffff' + }; + windowClass.setWindowSystemBarProperties(sysBarProps, (err: BusinessError) => { + let errCode: number = err.code; + if (errCode) { + console.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting the system bar properties.'); + }); + }) + // 3.Load the corresponding target page for the immersive window. + windowStage.loadContent("pages/page2", (err: BusinessError) => { + let errCode: number = err.code; + if (errCode) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content.'); + }); + } +}; +// [End entry_ability_immersive_window] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityKeepScreenOn.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityKeepScreenOn.ets new file mode 100644 index 0000000000000000000000000000000000000000..efc53ce5c0a6e59f64f600c5bfc052637c7fefec --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityKeepScreenOn.ets @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何保持屏幕常亮 +*/ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // [Start entry_ability_keep_screen_on] + let isKeepScreenOn: boolean = true; + let windowClass: window.Window = window.findWindow("test"); + try { + windowClass.setWindowKeepScreenOn(isKeepScreenOn, (err: BusinessError) => { + const errCode: number = err.code; + if (errCode) { + console.error('Failed to set the screen to be always on. Cause: ' + JSON.stringify(err)); + return; + + } + console.info('Succeeded in setting the screen to be always on.'); + }); + } catch (exception) { + console.error('Failed to set the screen to be always on. Cause: ' + JSON.stringify(exception)); + } + // [End entry_ability_keep_screen_on] + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityKeyboardAvoidMode.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityKeyboardAvoidMode.ets new file mode 100644 index 0000000000000000000000000000000000000000..ae054b20437acf2fd78cb66fb529023c6ef51655 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityKeyboardAvoidMode.ets @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在键盘弹出时,让内容上移,而不是整个页面上移 +*/ + +// [Start entry_ability_keyboard_avoid_mode] +// EntryAbility.ets +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window, KeyboardAvoidMode, UIContext } from '@kit.ArkUI'; + + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + + onDestroy(): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + onWindowStageCreate(windowStage: window.WindowStage) { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + + windowStage.loadContent('pages/Index', (err, data) => { + let uiContext :UIContext = windowStage.getMainWindowSync().getUIContext(); + uiContext.setKeyboardAvoidMode(KeyboardAvoidMode.RESIZE); + 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. Data: %{public}s', JSON.stringify(data) ?? ''); + }); + } + + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + + onForeground(): void { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + + onBackground(): void { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +} +// [End entry_ability_keyboard_avoid_mode] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityLockDevice.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityLockDevice.ets new file mode 100644 index 0000000000000000000000000000000000000000..0f901d4a6a354a12435a8caf36fcb56c1bd29115 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityLockDevice.ets @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何锁定设备竖屏,使得窗口不随屏幕旋转 +*/ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // [Start entry_ability_lock_device] + //1.Get the window instance object, use the creatWindow method to create a new window, and use the findWindow method to obtain an existing window + let windowClass: window.Window | undefined = undefined; + let config: window.Configuration = { + name: "alertWindow", + windowType: window.WindowType.TYPE_SYSTEM_ALERT, + ctx: this.context + }; + try { + let promise = window.createWindow(config); + promise.then((data)=> { + windowClass = data; + console.info('Succeeded in creating the window. Data:' + JSON.stringify(data)); + }).catch((err: BusinessError)=>{ + console.error('Failed to create the Window. Cause:' + JSON.stringify(err)); + });} catch (exception) { + console.error('Failed to create the window. Cause: ' + JSON.stringify(exception)); + } + //2.The window instance uses the setPreferred Orientation method to set the display orientation of the window. PORTRAIT is a fixed vertical screen, and other orientations can refer to the reference link + let orientation = window.Orientation.PORTRAIT; + try { + let windowClass: window.Window = window.findWindow("test"); + windowClass.setPreferredOrientation(orientation, (err: BusinessError) => { + const errCode: number = err.code; + if (errCode) { + console.error('Failed to set window orientation. Cause: ' + JSON.stringify(err)); + return; + } + console.info('Succeeded in setting window orientation.'); + }); + } catch (exception) { + console.error('Failed to set window orientation. Cause: ' + JSON.stringify(exception)); + } + // [End entry_ability_lock_device] + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityMonitorChangesWindowSize.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityMonitorChangesWindowSize.ets new file mode 100644 index 0000000000000000000000000000000000000000..46959939d66aab1d6295e07974a49093f77eb440 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityMonitorChangesWindowSize.ets @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何监听窗口大小的变化 +*/ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + let windowClass: window.Window = window.findWindow("test"); + // [Start entry_ability_monitor_changes_in_window_size] + try { + windowClass.on('windowSizeChange', (data) => { + console.info('Succeeded in enabling the listener for window size changes. Data: ' + JSON.stringify(data)); + }); + } catch (exception) { + console.error('Failed to enable the listener for window size changes. Cause: ' + JSON.stringify(exception)); + } + // [End entry_ability_monitor_changes_in_window_size] + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityMonitorTheFrontAndBack.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityMonitorTheFrontAndBack.ets new file mode 100644 index 0000000000000000000000000000000000000000..97ba92d254d392ef4d523cf938bc74c1c35986ff --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityMonitorTheFrontAndBack.ets @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Component如何监听应用前后台切换 +*/ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +// [Start entry_ability_monitor_the_front_and_back] +// EntryAbility中 +export default class EntryAbility extends UIAbility { + onWindowStageCreate(windowStage: window.WindowStage): void { + AppStorage.setOrCreate('isOnForeground', true); + } + + onForeground(): void { + AppStorage.set('isOnForeground', true); + } + + onBackground(): void { + AppStorage.set('isOnForeground', false); + } +} +// [End entry_ability_monitor_the_front_and_back] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityOrientationAndAvoidAreaChange.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityOrientationAndAvoidAreaChange.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e5aa193584226ecd869ad24d9716d152e78e615 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityOrientationAndAvoidAreaChange.ets @@ -0,0 +1,92 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何同时获取屏幕方向orientation和系统规避区avoidAreaChange信息 +*/ + +// [Start entry_ability_orientation_and_areaChange] +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { display, window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + + onDestroy(): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + + windowStage.loadContent('pages/Index', (err) => { + 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.'); + }); + + + let windowClass: window.Window | undefined = undefined; + try { + window.getLastWindow(this.context, (err: BusinessError, data) => { + const errCode: number = err.code; + if (errCode) { + console.error(`Failed to obtain the top window. Cause code: ${err.code}, message: ${err.message}`); + return; + } + windowClass = data; + console.info('Succeeded in obtaining the top window. Data: ' + JSON.stringify(data)); + // Please ensure that the relevant Window instance, namely windowClass, has been obtained + windowClass.on('avoidAreaChange', async (data) => { + console.info('Succeeded in enabling the listener for avoid area changes. Type: ' + JSON.stringify(data.type) + ', area ' + JSON.stringify(data.area)); + let newDisplay: display.Display = display.getDefaultDisplaySync(); + console.info('---Orientation: ' + newDisplay.orientation); + }); + }); + } catch (exception) { + console.error(`Failed to obtain the top window. Cause code: ${exception.code}, message: ${exception.message}`); + } + } + + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + + onForeground(): void { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + + onBackground(): void { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +} +// [End entry_ability_orientation_and_areaChange] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityOverlap_One.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityOverlap_One.ets new file mode 100644 index 0000000000000000000000000000000000000000..dd492b62e8d1d024e2acddc02aeea0888e6f7524 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityOverlap_One.ets @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:状态栏与页面内容发生重叠,如何解决? +*/ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + + // [Start entry_ability_overlap_one] + // EntryAbility.ets + + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + + windowStage.loadContent('pages/ImagePreview', (err) => { + 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.'); + + + let windowClass: window.Window = windowStage.getMainWindowSync(); // Get the main window of the application + // 1. Set the window to full screen + let isLayoutFullScreen = true; + windowClass.setWindowLayoutFullScreen(isLayoutFullScreen); + // 2. Cache window object + AppStorage.setOrCreate('windowClass', windowClass); + }); + } + // [End entry_ability_overlap_one] +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityOverlap_Two.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityOverlap_Two.ets new file mode 100644 index 0000000000000000000000000000000000000000..eb8988944f36d017e0c8ff9e18226734c013dc76 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityOverlap_Two.ets @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:状态栏与页面内容发生重叠,如何解决? +*/ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + + // [Start entry_ability_overlap_two] + // EntryAbility.ets + + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + + windowStage.loadContent('pages/AvoidStatusBar', (err) => { + 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.'); + + + let windowClass: window.Window = windowStage.getMainWindowSync(); // Get the main window of the application + // 1. Set the window to full screen + let isLayoutFullScreen = true; + windowClass.setWindowLayoutFullScreen(isLayoutFullScreen); + // 2. Cache window object + AppStorage.setOrCreate('windowClass', windowClass); + + + // 3. Obtain layout to avoid obstructed areas + let type = window.AvoidAreaType.TYPE_SYSTEM; + let avoidArea = windowClass.getWindowAvoidArea(type); + let statusBar =px2vp( avoidArea.topRect.height); // 获取状态栏的高度 + AppStorage.setOrCreate('statusBar', statusBar); + }); + } + // [End entry_ability_overlap_two] +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilityStatusBar.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilityStatusBar.ets new file mode 100644 index 0000000000000000000000000000000000000000..bef8ed558c0fc3625881a63fef20a4c3cad685e9 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilityStatusBar.ets @@ -0,0 +1,69 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何修改状态栏字体颜色 +*/ + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + // [Start change_the_font_color_of_the_status_bar_one] + AppStorage.setOrCreate('windowStage',windowStage); + // [End change_the_font_color_of_the_status_bar_one] + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + const context = windowStage.getMainWindowSync().getUIContext(); + AppStorage.setOrCreate("context", context); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/entryability/EntryAbilitySystemBarProperties.ets b/ArkUI/entry/src/main/ets/entryability/EntryAbilitySystemBarProperties.ets new file mode 100644 index 0000000000000000000000000000000000000000..413c667e9a5efd951db415813a978091b6f1ecb5 --- /dev/null +++ b/ArkUI/entry/src/main/ets/entryability/EntryAbilitySystemBarProperties.ets @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:在深色模式切换下如何适配状态栏颜色? +*/ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + // [Start entry_ability_system_bar_properties] + // EntryAbility.ets + + + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + // 缓存当前设备的颜色模式 + AppStorage.setOrCreate('currentColorMode', this.context.config.colorMode); + } + + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + + windowStage.loadContent('pages/Index', (err) => { + 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.'); + let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口 + // 1. 设置窗口全屏 + let isLayoutFullScreen = true; + windowClass.setWindowLayoutFullScreen(isLayoutFullScreen); + // 2. 缓存窗口对象 + AppStorage.setOrCreate('windowClass', windowClass); + }); + } + // [End entry_ability_system_bar_properties] +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/AdaptiveForDifferentmMachines.ets b/ArkUI/entry/src/main/ets/pages/AdaptiveForDifferentmMachines.ets new file mode 100644 index 0000000000000000000000000000000000000000..2ae55d06465fbb588c2df8a6c0b5397b78cc870a --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/AdaptiveForDifferentmMachines.ets @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:UI布局默认是多少vp为基准,以达到不同机器自适应 +*/ + + +// [Start adaptive_for_different_machines] +import { display } from '@kit.ArkUI'; + +let displayClass: display.Display | null = null; +try { + displayClass = display.getDefaultDisplaySync(); +} catch (exception) { + console.error('Failed to obtain the default display object. Code: ' + JSON.stringify(exception)); +} +// [End adaptive_for_different_machines] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/AvoidanceOfPopUpsAndSoftKeyboards.ets b/ArkUI/entry/src/main/ets/pages/AvoidanceOfPopUpsAndSoftKeyboards.ets new file mode 100644 index 0000000000000000000000000000000000000000..e4a29c4fc828a487327781e814bf2e13e5ca5076 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/AvoidanceOfPopUpsAndSoftKeyboards.ets @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现弹窗和软键盘的避让 +*/ + +// [Start avoidance_of_pop_ups_and_soft_keyboards] +@Entry +@Component +struct AvoidDialogPage { + @State message: string = 'Open pop up window'; + dialogController: CustomDialogController = new CustomDialogController({ + builder: CustomDialogExample() + }) + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + this.dialogController.open(); + }) + } + .width('100%') + } + .height('100%') + } +} + +@CustomDialog +struct CustomDialogExample { + controller: CustomDialogController = new CustomDialogController({ + builder: CustomDialogExample({}) + }) + + build() { + Column() { + TextInput({}) + .fontSize(20) + .margin({ top: 10, bottom: 10 }) + .expandSafeArea([SafeAreaType.KEYBOARD, SafeAreaType.SYSTEM]) + .borderWidth(0.5) + .borderRadius(4) + .height(40) + .defaultFocus(true) + .margin({ top: 30, left: 16, right: 16 }) + } + } +} +// [End avoidance_of_pop_ups_and_soft_keyboards] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/BackgroundChangesWithTextSize.ets b/ArkUI/entry/src/main/ets/pages/BackgroundChangesWithTextSize.ets new file mode 100644 index 0000000000000000000000000000000000000000..0c94151eadaacaf3118b154269d080f20c804ae9 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/BackgroundChangesWithTextSize.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现背景跟随文字大小改变 +*/ + +// [Start background_changes_with_text_size] +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + Column() { + Row() { + Text(this.message) + } + .backgroundImage($r('app.media.startIcon')) + .backgroundImageSize({ + width: '100%', + height: '100%' + }) + .height(100) + .border({ + width: 3, + color: Color.Pink + }) + + TextInput() + .onChange((value: string) => { + this.message = value; + }) + } + } +} +// [End background_changes_with_text_size] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/BadgeDoesNotFlash.ets b/ArkUI/entry/src/main/ets/pages/BadgeDoesNotFlash.ets new file mode 100644 index 0000000000000000000000000000000000000000..b07a2834f2cb71e96ad8bf7d57b3d5c93ab907a7 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/BadgeDoesNotFlash.ets @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取UI组件的显示或隐藏状态 +*/ + +// [Start badge_does_not_flash] +@Entry +@Component +struct BadgeDemo { + @State message: string = 'Hello World'; + @State sizes: string = '0'; + @State isDnd: boolean = false; + + + build() { + Row() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + this.isDnd = !this.isDnd; + }) + Stack() { + Badge({ + value: '', + position: { + x: 40, + y: 0 + }, + style: { + badgeSize: 15, + badgeColor: Color.Red + } + }) { + Image($r('app.media.startIcon')) + .width(50) + .height(50) + .onComplete(() => { + this.isDnd = !this.isDnd; + }) + } + .visibility(this.isDnd ? Visibility.Visible : Visibility.None) + + + Badge({ + count: 98, + maxCount: 99, + position: { x: 30, y: 0 }, + style: { + fontSize: 15, + badgeSize: 15, + badgeColor: Color.Red + } + }) { + Image($r('app.media.startIcon')) + .width(50) + .height(50) + .onComplete(() => { + this.isDnd = !this.isDnd; + }) + } + .visibility(this.isDnd ? Visibility.None : Visibility.Visible) + } + } + .height('100%') + } +} +// [End badge_does_not_flash] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/BindDifferentCustomKeyboards.ets b/ArkUI/entry/src/main/ets/pages/BindDifferentCustomKeyboards.ets new file mode 100644 index 0000000000000000000000000000000000000000..65385cbd40ffbcffd5e42f8108281287185f7c79 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/BindDifferentCustomKeyboards.ets @@ -0,0 +1,126 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何给不同输入框绑定不同的自定义键盘 +*/ + +// [Start bind_different_custom_keyboards] +@Entry +@Component +struct TextInputExample { + controller: TextInputController = new TextInputController(); + @State inputValue: string = ''; + controller1: TextInputController = new TextInputController(); + @State inputValue1: string = ''; + controller2: TextInputController = new TextInputController(); + @State inputValue2: string = ''; + + + build() { + Column() { + this.input({ inputValue: this.inputValue, controller: this.controller, index: 0 }); + this.input({ inputValue: this.inputValue1, controller: this.controller1, index: 1 }); + this.input({ inputValue: this.inputValue2, controller: this.controller2, index: 2 }); + } + } + + + @Builder + input(tmp: Tmp) { + if (tmp.index === 0) { + TextInput({ controller: tmp.controller, text: tmp.inputValue }) + .customKeyboard(this.keyboard()) + .margin(10) + .border({ width: 1 }) + .height('48vp') + } else if (tmp.index === 1) { + TextInput({ controller: tmp.controller, text: tmp.inputValue }) + .customKeyboard(this.keyboard1()) + .margin(10) + .border({ width: 1 }) + .height('48vp') + } else { + TextInput({ controller: tmp.controller, text: tmp.inputValue }) + .customKeyboard(this.keyboard2()) + .margin(10) + .border({ width: 1 }) + .height('48vp') + } + } + + + @Builder + keyboard() { + CustomKeyboardBuilder({ inputValue: this.inputValue, controller: this.controller, index: 0 }); + } + + + @Builder + keyboard1() { + CustomKeyboardBuilder({ inputValue: this.inputValue1, controller: this.controller1, index: 1 }); + } + + + @Builder + keyboard2() { + CustomKeyboardBuilder({ inputValue: this.inputValue2, controller: this.controller2, index: 2 }); + } +} + + +class Tmp { + inputValue?: string; + controller?: TextInputController; + index?: number; +} + + +// Customize keyboard components +@Component +export struct CustomKeyboardBuilder { + controller?: TextInputController = new TextInputController(); + index: number = 0; + @Link inputValue: string; + + + build() { + Column() { + Button('x').onClick(() => { + // Turn off custom keyboard + this.controller?.stopEditing(); + }) + Grid() { + ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, '*', 0, '#'], (item: number | string) => { + GridItem() { + Button(item + '') + .backgroundColor(this.index === 0 ? Color.Blue : + (this.index === 1 ? Color.Green : Color.Red)) + .width(110) + .onClick(() => { + this.inputValue += item; + }) + } + }) + } + .maxCount(3) + .columnsGap(10) + .rowsGap(10) + .padding(5) + } + .backgroundColor(Color.Gray) + } +} +// [End bind_different_custom_keyboards] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/BindPopupAdaptsToTheWeb.ets b/ArkUI/entry/src/main/ets/pages/BindPopupAdaptsToTheWeb.ets new file mode 100644 index 0000000000000000000000000000000000000000..8d758b9eaec29e76a826a619e8eb42c7f9d042eb --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/BindPopupAdaptsToTheWeb.ets @@ -0,0 +1,104 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:bindPopup适配Web组件长按菜单功能,设置offset控制弹窗的偏移 +*/ + +// [Start bindPopup_adapts_to_the_web] +import { webview } from '@kit.ArkWeb'; + + +@Entry +@Component +struct BindPopupOffset { + controller: webview.WebviewController = new webview.WebviewController(); + private result: WebContextMenuResult | undefined = undefined; + @State linkUrl: string = ''; + @State offsetX: number = 0; + @State offsetY: number = 0; + @State showMenu: boolean = false; + + + @Builder + MenuBuilder() { + Menu() { + MenuItem({ + content: 'copy picture', + }) + .width(100) + .height(50) + .onClick(() => { + this.result?.copyImage(); + this.showMenu = false; + }) + MenuItem({ + content: 'cut' + }) + .width(100) + .height(50) + .onClick(() => { + this.result?.cut(); + this.showMenu = false; + }) + } + .width(150) + .backgroundColor('#eeeeee') + } + + + build() { + Column() { + Row() + .width(0) + .height(0) + .position({ x: 0, y: 0 }) + .bindPopup(this.showMenu, + { + builder: this.MenuBuilder(), + enableArrow: false, + placement: Placement.LeftTop, + targetSpace: 0, + shadow: { + radius: 0 + }, + offset: { + x: this.offsetX - 7, + y: this.offsetY + }, + mask: false, + onStateChange: (e) => { + if (!e.isVisible) { + this.showMenu = false; + this.result!.closeContextMenu(); + } + } + }) + + + Web({ src: $rawfile('index.html'), controller: this.controller })//Trigger custom pop ups + .onContextMenuShow((event) => { + if (event) { + this.result = event.result; + this.showMenu = true; + this.offsetX = Math.max(px2vp(event?.param.x() ?? 0) - 0, 0); + this.offsetY = Math.max(px2vp(event?.param.y() ?? 0) - 0, 0); + } + return true; + }) + } + } +} +// [End bindPopup_adapts_to_the_web] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/BottomOfScreenObstruction.ets b/ArkUI/entry/src/main/ets/pages/BottomOfScreenObstruction.ets new file mode 100644 index 0000000000000000000000000000000000000000..b76840ea01901f5e013dfff52d0e964628c687bb --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/BottomOfScreenObstruction.ets @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:在屏幕底部的组件的响应区域是否存在遮挡 +*/ + +// [Start bottom_of_screen_obstruction] +@Entry +@Component +struct Index { + build() { + Column() { + Column() { + } + .width('100%') + .height(5) // 5px click range + .backgroundColor(Color.Red) + .onClick(() => { + console.log("Trigger click event") + }) + } + .height('100%') + .width('100%') + .justifyContent(FlexAlign.End) + } +} +// [End bottom_of_screen_obstruction] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ButtonCannotSetFont.ets b/ArkUI/entry/src/main/ets/pages/ButtonCannotSetFont.ets new file mode 100644 index 0000000000000000000000000000000000000000..593e32b2aff389bdfb13981d80c5b2514c9eba80 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ButtonCannotSetFont.ets @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Button组件无法设置字体最大、最小值 +*/ + +// [Start button_cannot_set_font] +@Entry +@Component +struct ButtonSetTheMaximumAndMinimumFontSizes { + @State text: string = 'hello'; + @State widthShortSize: number = 300; + + + build() { + Row() { + Button(this.text) + .width(this.widthShortSize) + .height(100) + .labelStyle({ + overflow: TextOverflow.Clip, + maxLines: 1, + minFontSize: 20, + maxFontSize: 40, + font: { + size: 30, + weight: FontWeight.Bolder, + family: 'cursive', + style: FontStyle.Italic + } + }) + } + } +} +// [End button_cannot_set_font] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ButtonSetGradientBackgroundColor.ets b/ArkUI/entry/src/main/ets/pages/ButtonSetGradientBackgroundColor.ets new file mode 100644 index 0000000000000000000000000000000000000000..b2aa0f08086173d36de27315c9c285f47e6d601c --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ButtonSetGradientBackgroundColor.ets @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Button组件如何设置渐变背景色 +*/ + +// [Start button_set_gradient_background_color] +@Entry +@Component +struct Index { + build() { + Button('test') + .width(200) + .height(50) + .backgroundColor('#00000000') + .linearGradient({ + angle: 90, + colors: [[0xff0000, 0.0], [0x0000ff, 0.3], [0xffff00, 1.0]] + }) + } +} +// [End button_set_gradient_background_color] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/CanCustomComponentsBeSavedInContainers.ets b/ArkUI/entry/src/main/ets/pages/CanCustomComponentsBeSavedInContainers.ets new file mode 100644 index 0000000000000000000000000000000000000000..30cdcf184518a3385c292de4ba206fe295b2c2df --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/CanCustomComponentsBeSavedInContainers.ets @@ -0,0 +1,92 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:自定义组件是否能通过容器保存 +*/ + +// [Start can_custom_components_be_saved_in_containers] +@Component +struct ComA { + build() { + Text('ComA').fontSize(50).fontWeight(FontWeight.Bold) + } +} + +@Component +struct ComB { + build() { + Text('ComB').fontSize(50).fontWeight(FontWeight.Bold) + } +} + +@Component +struct ComC { + build() { + Text('ComC').fontSize(50).fontWeight(FontWeight.Bold) + } +} + +//if else logical branch writing +@Builder +function buildCom(param: string) { + if (param == 'ComA') { + ComA() + } else if (param == 'ComB') { + ComB() + } else if (param == 'ComC') { + ComC() + } +} + +@Builder +function buildComA() { + ComA() +} + +@Builder +function buildComB() { + ComB() +} + +@Builder +function buildComC() { + ComC() +} + +//Encapsulate in container through map +let map: Map> = new Map() +map.set('ComA', wrapBuilder(buildComA)) +map.set('ComB', wrapBuilder(buildComB)) +map.set('ComC', wrapBuilder(buildComC)) + +@Component +struct Page12 { + @State message: string = 'Hello World'; + @State arr: string[] = ['ComA', 'ComB', 'ComC']; + + build() { + Column() { + ForEach(this.arr, (item: string) => { + //Retrieve based on the key during use + map.get(item)?.builder() + }) + } + .justifyContent(FlexAlign.Center) + .width('100%') + .height('100%') + } +} +// [End can_custom_components_be_saved_in_containers] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/CanvasDrawingContentDynamicallyUpdates.ets b/ArkUI/entry/src/main/ets/pages/CanvasDrawingContentDynamicallyUpdates.ets new file mode 100644 index 0000000000000000000000000000000000000000..d3cef5017782e4b7a13cc77e0c7bb8479d79a556 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/CanvasDrawingContentDynamicallyUpdates.ets @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Canvas绘制内容如何动态更新 +*/ + +// [Start canvas_drawing_content_dynamically_updates] +@Entry +@Component +struct CanvasContentUpdate { + private settings: RenderingContextSettings = new RenderingContextSettings(true); + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + @State @Watch('draw')content: string = ''; + + draw() { + this.context.clearRect(0, 0, 200, 200); // Clean up canvas content + this.context.fillText(this.content, 50, 50); // Refill + } + + build() { + Column() { + Canvas(this.context) + .width('100%') + .height('25%') + .backgroundColor('#F5DC62') + .onReady(() => { + //You can draw content here. + this.context.font = '55px sans-serif'; + this.context.fillText(this.content, 50, 50); + }) + TextInput({ + text:$$this.content + }) + } + .borderColor('#31525B') + .borderWidth(12) + .width('100%') + .height('100%') + } +} +// [End canvas_drawing_content_dynamically_updates] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/CanvasRealizesRegionHollowingOut.ets b/ArkUI/entry/src/main/ets/pages/CanvasRealizesRegionHollowingOut.ets new file mode 100644 index 0000000000000000000000000000000000000000..d6ee28378f51a41387e57fe4296086a178cce06e --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/CanvasRealizesRegionHollowingOut.ets @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:使用Canvas如何实现部分区域镂空的效果 +*/ + +// [Start canvas_realizes_region_hollowing_out] +@Entry +@Component +struct HollowOutWithCanvas { + @State circleCenterX: number = 0; + @State circleCenterY: number = 0; + @State circleRadius: number = 100; + private settings: RenderingContextSettings = new RenderingContextSettings(true); + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + + + build() { + Row() { + Column() { + Stack() { + Image($r('app.media.startIcon')) + .height(300) + // Use Canvas to draw masks to cover images, cameras, etc + Canvas(this.context) + .width('100%') + .height('100%') + .backgroundColor('#00000000') + .onReady(() => { + this.circleCenterX = this.context.width / 2; + this.circleCenterY = this.context.height / 2; + this.context.fillStyle = '#aa000000'; + // Draw a circular path for semi transparent filling + this.context.beginPath(); + this.context.moveTo(0, 0); + this.context.lineTo(0, this.context.height); + this.context.lineTo(this.context.width, this.context.height); + this.context.lineTo(this.context.width, 0); + this.context.lineTo(0, 0); + this.context.arc(this.circleCenterX, this.circleCenterY, this.circleRadius, 0, Math.PI * 2); + this.context.fill(); + this.context.closePath(); + }) + } + .width('1456px') + .height('1456px') + } + .width('100%') + } + .height('100%') + } +} +// [End canvas_realizes_region_hollowing_out] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ChangeTextInputInputMode.ets b/ArkUI/entry/src/main/ets/pages/ChangeTextInputInputMode.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c03e567ec24c1e24731bf3c4d559af4fca594 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ChangeTextInputInputMode.ets @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何更改TextInput密码输入模式下passwordIcon的大小、颜色、位置 +*/ + +// [Start change_textInput_input_mode] +@Entry +@Component +struct TextInputDemo { + @State text: string = ''; + @State changeType: InputType = InputType.Password; + @State isVisible: boolean = false; + @State changeState: boolean = false; + controller: TextInputController = new TextInputController(); + + + build() { + Stack() { + TextInput({ text: this.text, controller: this.controller }) + .type(this.changeType) + .placeholderFont({ + size: 16, + weight: 400 + }) + .showPasswordIcon(false) + .width(336) + .height(56) + .padding({ right: 50 }) + .onChange((value: string) => { + this.text = value; + }) + //Image overlay passwordIcon implementation + Image($r(this.isVisible ? 'app.media.startIcon' : 'app.media.invisible')) + .margin({ left: 280 }) + .backgroundColor('#E7E8EA') + .width(20) + .height(20) + .onClick(() => { + this.changeState = !this.changeState; + this.isVisible = !this.isVisible; + if (this.changeState) { + this.changeType = InputType.Normal; + } else { + this.changeType = InputType.Password; + } + }) + } + .width('100%') + .height('100%') + .backgroundColor('#F1F3F5') + } +} +// [End change_textInput_input_mode] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ChangeTheFontColorOfTheStatusBar.ets b/ArkUI/entry/src/main/ets/pages/ChangeTheFontColorOfTheStatusBar.ets new file mode 100644 index 0000000000000000000000000000000000000000..9e7393bc817147ddbdcda5db90bf8e35fb5f967c --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ChangeTheFontColorOfTheStatusBar.ets @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何修改状态栏字体颜色 +*/ + +// [Start change_the_font_color_of_the_status_bar_two] +import { window } from '@kit.ArkUI'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Component +struct ChangeStatusBar { + windowStage: window.WindowStage = AppStorage.get("windowStage") as window.WindowStage; + // How to get the main window + mainWin: window.Window = this.windowStage.getMainWindowSync(); + + aboutToAppear(): void { + let sysBarProps: window.SystemBarProperties = { + statusBarColor: '#000000', + statusBarContentColor: '#ffffff' + }; + this.mainWin.setWindowSystemBarProperties(sysBarProps, (err: BusinessError) => { + let errCode: number = err.code; + if (errCode) { + console.error('[StaticUtils] Failed to set the system bar properties. Cause: ' + JSON.stringify(err)); + return; + } + console.info('[StaticUtils] Succeeded in setting the system bar properties.'); + }); + } + + build() { + Row() { + Column({ space: 10 }) { + Text('Demo of modifying the status bar') + .fontSize(25) + .margin(20) + .fontColor(0x3399FF) + }.width('100%') + }.height('100%').backgroundColor(Color.White) + } +} +// [End change_the_font_color_of_the_status_bar_two] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ClickButtonSoftwareKeyboardToClose.ets b/ArkUI/entry/src/main/ets/pages/ClickButtonSoftwareKeyboardToClose.ets new file mode 100644 index 0000000000000000000000000000000000000000..186031ad5d1cd641c6ae687a1cd27465692e926f --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ClickButtonSoftwareKeyboardToClose.ets @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现点击输入框时会拉起软键盘,点击Button时软键盘关闭 +*/ + +// [Start click_button_software_keyboard_to_close] +import { inputMethod } from '@kit.IMEKit'; + +@Entry +@Component +struct ClickBlankHideKeyboard { + build() { + Column({ space: 12 }) { + TextInput({ placeholder: 'Please enter your account' }) + .height(40) + TextInput({ placeholder: 'Please input a password' }) + .height(40) + Button('log on').width('100%') + .onClick(() => { + // Exit text editing mode + inputMethod.getController().stopInputSession(); + }) + } + } +} +// [End click_button_software_keyboard_to_close] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/CombiningListItemGroupAndLazyForEach.ets b/ArkUI/entry/src/main/ets/pages/CombiningListItemGroupAndLazyForEach.ets new file mode 100644 index 0000000000000000000000000000000000000000..0af59e4565f0926fcf0bf0d989711b26eae90ed7 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/CombiningListItemGroupAndLazyForEach.ets @@ -0,0 +1,190 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:ListItemGroup和LazyForEach如何结合使用 +*/ + +// [Start combining_istItemGroup_and_lazyForEach] +@Entry +@Component +struct LazyForEachDemo { + private list: MyDataSource2 = new MyDataSource2(); + + @Builder + itemHead(text: string) { + Text(text) + .fontSize(20) + .backgroundColor(0xAABBCC) + .width('100%') + .padding(10) + } + + @Builder + itemFoot(num: number) { + Text('common' + num + 'period') + .fontSize(16) + .backgroundColor(0xAABBCC) + .width('100%') + .padding(5) + } + + aboutToAppear() { + for (let date = 1; date < ~~(Math.random() * 30) + 3; date++) { + let dayData = new dateListItem(date + ''); + for (let index = 1; index < ~~(Math.random() * 100) + 30; index++) { + dayData.orderList.pushData(`hello${index}`); + } + this.list.pushData(dayData); + } + } + + build() { + Column() { + List({ space: 20 }) { + LazyForEach(this.list, (item: dateListItem) => { + ListItemGroup({ header: this.itemHead(item.date + ''), footer: this.itemFoot(item.orderList.totalCount()) }) { + LazyForEach(item.orderList, (order: string, ) => { + ListItem() { + Text(order) + .width('100%') + .height(60) + .fontSize(20) + .textAlign(TextAlign.Center) + .backgroundColor(0xFFFFFF) + } + }, (item: string) => JSON.stringify(item)) + } + .divider({ strokeWidth: 1, color: Color.Blue }) + }) + } + .height('100%') + .cachedCount(1) + .width('90%') + .sticky(StickyStyle.Header | StickyStyle.Footer) + .scrollBar(BarState.Off) + } + .width('100%') + .height('100%') + .backgroundColor(0xDCDCDC) + .padding({ top: 5 }) + } +} + +class BasicDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + private originDataArray: string[] = []; + + public totalCount(): number { + return 0; + } + + public getData(index: number): string | dateListItem { + return this.originDataArray[index]; + } + + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener); + } + } + + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + this.listeners.splice(pos, 1); + } + } + + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } +} + +class MyDataSource1 extends BasicDataSource { + private dataArray: string[] = []; + + public totalCount(): number { + return this.dataArray.length; + } + + public getData(index: number): string { + return this.dataArray[index]; + } + + public addData(index: number, data: string): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + public pushData(data: string): void { + this.dataArray.push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } +} + + +class MyDataSource2 extends BasicDataSource { + private dataArray: dateListItem[] = []; + + public totalCount(): number { + return this.dataArray.length; + } + + public getData(index: number): dateListItem { + return this.dataArray[index]; + } + + public addData(index: number, data: dateListItem): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + public pushData(data: dateListItem): void { + this.dataArray.push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } +} + +class dateListItem { + date: string; + orderList: MyDataSource1; + + constructor(date: string) { + this.date = date; + this.orderList = new MyDataSource1(); + } +} +// [End combining_istItemGroup_and_lazyForEach] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/CommonText.ets b/ArkUI/entry/src/main/ets/pages/CommonText.ets new file mode 100644 index 0000000000000000000000000000000000000000..fc5bc1a414e3a51ff0a1724b0d129f589580ebbc --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/CommonText.ets @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现跨文件组件复用 +*/ + +// [Start implement_cross_file_component_reuse_one] +export class ImageModifier implements AttributeModifier { + width: number = 60; + height: number = 60; + + constructor(width: number, height: number) { + this.width = width; + this.height = height + } + + applyNormalAttribute(instance: ImageAttribute): void { + instance.width(this.width); + instance.height(this.height); + } +} + +/* + Custom class implementation of the AttributeModifier interface for text, used for initialization +*/ +export class TextModifier implements AttributeModifier { + textSize: number = 12; + + constructor(textSize: number) { + this.textSize = textSize; + } + + applyNormalAttribute(instance: TextAttribute): void { + instance.fontSize(this.textSize); + instance.fontColor(Color.Orange); + instance.textAlign(TextAlign.Center); + instance.border({ width: 1, color: Color.Orange, style: BorderStyle.Solid }); + instance.margin({ right: 10 }); + } +} + +/* + Customize class to implement the AttributeModifier interface for the checkbox, used for initialization +*/ +export class CheckboxModifier implements AttributeModifier { + size: number = 15; + + constructor(size: number) { + this.size = size; + } + + applyNormalAttribute(instance: CheckboxAttribute): void { + instance.width(this.size); + instance.height(this.size); + } +} + +/** + * Customize encapsulated graphic and text components + */ +@Component +export struct ImageText { + @State textOneContent: string | Resource = 'default'; + @State imageSrc: PixelMap | ResourceStr | DrawableDescriptor = $r('app.media.icon'); + //Accept externally passed AttributeModifier class instances, which can customize only some components and selectively pass parameters. + @State textOne: AttributeModifier = new TextModifier(12); + @State imageModifier: AttributeModifier = new ImageModifier(60, 60); + @State checkboxModifier: AttributeModifier = new CheckboxModifier(15); + + build() { + Row() { + Checkbox() + .attributeModifier(this.checkboxModifier) + + Image(this.imageSrc) + .attributeModifier(this.imageModifier) + .margin({ right: 10 }) + + Text(this.textOneContent) + .attributeModifier(this.textOne) + .fontColor(Color.Orange) + } + .padding({ top: 5 }) + .margin({ right: 10, bottom: 15 }) + .width(200) + .height(100) + } +} +// [End implement_cross_file_component_reuse_one] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ComponentStatusSynchronization_One.ets b/ArkUI/entry/src/main/ets/pages/ComponentStatusSynchronization_One.ets new file mode 100644 index 0000000000000000000000000000000000000000..89980664e82c709958328c4f74b4d2fa552b17ed --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ComponentStatusSynchronization_One.ets @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:父组件如何与孙子组件进行状态同步 +*/ + +// [Start component_status_synchronization_one_one] +@Entry +@ComponentV2 +struct Father{ + @Provider("reviewVote") reviewVotes: number = 0; + + + build() { + Column() { + Son() + Button(`Father: ${this.reviewVotes}`) + } + } +} +// [End component_status_synchronization_one_one] + +// [Start component_status_synchronization_one_two] +@ComponentV2 +struct Son{ + build() { + Column() { + Grandson() + } + } +} +// [End component_status_synchronization_one_two] + +// [Start component_status_synchronization_one_three] +@ComponentV2 +struct Grandson{ + @Consumer("reviewVote") reviewVotes: number = 0; + + + build() { + Column() { + Button(`Grandson: ${this.reviewVotes}`) + }.width('100%') + } +} +// [End component_status_synchronization_one_three] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ComponentStatusSynchronization_Two.ets b/ArkUI/entry/src/main/ets/pages/ComponentStatusSynchronization_Two.ets new file mode 100644 index 0000000000000000000000000000000000000000..1ff759c6814dbf86c51d32af603064c7333141c1 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ComponentStatusSynchronization_Two.ets @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:父组件如何与孙子组件进行状态同步 +*/ + +// [Start component_status_synchronization_two_one] +@Entry +@ComponentV2 +struct Father { + @Local reviewVotes: number = 0; + + + build() { + Column() { + Son({ reviewVotes: this.reviewVotes }) + Button(`Father: ${this.reviewVotes}`) + } + } +} +// [End component_status_synchronization_two_one] + +// [Start component_status_synchronization_two_two] +@ComponentV2 +struct Son { + @Require @Param reviewVotes: number = 1; + + + build() { + Column() { + Grandson({ reviewVotes: this.reviewVotes }) + } + } +} +// [End component_status_synchronization_two_two] + +// [Start component_status_synchronization_two_three] +@ComponentV2 +struct Grandson { + @Require @Param reviewVotes: number = 1; + + + build() { + Column() { + Button(`Grandson: ${this.reviewVotes}`) + }.width('100%') + } +} +// [End component_status_synchronization_two_three] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ConvertChineseCharactersToPinyin.ets b/ArkUI/entry/src/main/ets/pages/ConvertChineseCharactersToPinyin.ets new file mode 100644 index 0000000000000000000000000000000000000000..84e3da7890033f90a14ab37e198db2df24368810 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ConvertChineseCharactersToPinyin.ets @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:汉字转拼音如何去掉音标 +*/ + +// [Start convert_chinese_characters_to_pinyin] +import { i18n } from '@kit.LocalizationKit'; + + +@Entry +@Component +struct RemovePinyin { + @State message: string = 'Hello World'; + + + build() { + RelativeContainer() { + Text(this.message) + .fontSize(50) + .onClick(() => { + let transliterator1 = i18n.Transliterator.getInstance('Any-Latn'); + let res = transliterator1.transform('China'); + + + let transliterator2 = i18n.Transliterator.getInstance('Latin-ASCII'); + let res2 = transliterator2.transform(res); + console.info('res2: ' + res2); + }) + } + .height('100%') + .width('100%') + } +} +// [End convert_chinese_characters_to_pinyin] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/CorrectWayToUseForEach.ets b/ArkUI/entry/src/main/ets/pages/CorrectWayToUseForEach.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e7e4be695ab03253bb2bb33ac949ba245ef7608 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/CorrectWayToUseForEach.ets @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:绑定类型的组件和ForEach的正确连用方式 +*/ + +// [Start correct_way_to_use_forEach] +@Entry +@Component +export struct BindSheetAndForEach { + @State isShow: boolean = false; + @State arr: number[] = [1, 2, 3, 4]; + @State isHoverText: Array = new Array(this.arr.length).fill(false); + + + @Builder + myBuilder() { + Column() { + Button('content1') + .margin(10) + .fontSize(20) + } + .width('100%') + } + + + build() { + Column() { + ForEach(this.arr, (item: number, idx: number) => { + Row() { + Text('item') + Button('Bullet Frame') + .onClick(() => { + this.isHoverText[idx] = true; + }) + .fontSize(15) + .margin(10) + .bindSheet(this.isHoverText[idx], this.myBuilder(), { + backgroundColor: Color.Gray, + height: SheetSize.MEDIUM, + showClose: true, + onDisappear: () => { + this.isHoverText[idx] = false; + } + }) + Checkbox() + } + .border({ width: 1, radius: 5 }) + }) + } + .justifyContent(FlexAlign.Start) + .width('100%') + .height('100%') + } +} +// [End correct_way_to_use_forEach] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/CustomPopUpPhysicalReturnInterception.ets b/ArkUI/entry/src/main/ets/pages/CustomPopUpPhysicalReturnInterception.ets new file mode 100644 index 0000000000000000000000000000000000000000..f326ff30a28c1393640ac54b6b0a6694dfc80a08 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/CustomPopUpPhysicalReturnInterception.ets @@ -0,0 +1,108 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:CustomDialog自定义弹窗组件如何进行物理返回拦截 +*/ + +// [Start custom_pop_up_physical_return_interception] +@CustomDialog +struct CustomDialogExample { + cancel?: () => void; + confirm?: () => void; + controller: CustomDialogController; + + build() { + Column() { + Text('Are you sure?') + .fontSize(20) + .margin({ + top: 10, + bottom: 10 + }) + Row() { + Button('cancel') + .onClick(() => { + this.controller.close(); + if (this.cancel) { + this.cancel(); + } + }) + .backgroundColor(0xffffff) + .fontColor(Color.Black) + Button('confirm') + .onClick(() => { + this.controller.close(); + if (this.confirm) { + this.confirm(); + } + }) + .backgroundColor(0xffffff) + .fontColor(Color.Red) + } + .width('100%') + .justifyContent(FlexAlign.SpaceAround) + .margin({ bottom: 10 }) + } + } +} + +@Component +export struct InterceptCustomDialog { + dialogController: CustomDialogController = new CustomDialogController({ + builder: CustomDialogExample({ + cancel: () => { + this.onCancel(); + }, + confirm: () => { + this.onAccept(); + } + }), + onWillDismiss: (dismissDialogAction: DismissDialogAction) => { + console.log('dialog onWillDismiss reason: ' + dismissDialogAction.reason); + // 1、PRESS_BACK Click the back button, swipe left/right, and ESC on the keyboard. + // 2、TOUCH_OUTSIDE When clicking on the barrier layer + // 3、CLOSE_BUTTON Click the close button + if (dismissDialogAction.reason === DismissReason.PRESS_BACK) { + // After processing the business logic, actively close the dialog box through 'dismiss' + // dismissDialogAction.dismiss(); + } + if (dismissDialogAction.reason === DismissReason.TOUCH_OUTSIDE) { + // dismissDialogAction.dismiss(); + } + }, + alignment: DialogAlignment.Bottom, + offset: { dx: 0, dy: -20 } + }) + + onCancel() { + console.info('Callback when the first button is clicked'); + } + + onAccept() { + console.info('Callback when the second button is clicked'); + } + + build() { + Column() { + Button('click me') + .onClick(() => { + this.dialogController.open(); + }) + } + .width('100%') + } +} +// [End custom_pop_up_physical_return_interception] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/CustomizePopUpAndCloseAnimations.ets b/ArkUI/entry/src/main/ets/pages/CustomizePopUpAndCloseAnimations.ets new file mode 100644 index 0000000000000000000000000000000000000000..ca0645d7ac56bf5829d138c54178cc71d2175510 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/CustomizePopUpAndCloseAnimations.ets @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何自定义弹窗的弹出动画和关闭动画 +*/ + +// [Start customize_pop_up_and_close_animations] +@CustomDialog +struct CustomDialogExample { + controller: CustomDialogController; + @State showFlag: Visibility = Visibility.Visible; + + build() { + Column() { + Button('Close the pop-up window') + } + .width('100%') + .height(400) + .backgroundColor(Color.Gray) + .onClick(() => { + this.cancel(); + }) + .visibility(this.showFlag) + //Set the animation event to 200ms in the core code, and set the starting point and ending point for component transitions to 100vp below the screen + .transition(TransitionEffect.OPACITY.animation({ duration: 200 }).combine(TransitionEffect.translate({ y: 100 }))) + } + + //When deleting, it should be noted that if the pop-up window is closed directly, there will be no transition effect. You can first use explicit and implicit control, + //Set the pop-up window to be hidden, and the downward exit animation will take effect. Then set a delay to close the pop-up window. + cancel() { + this.showFlag = Visibility.Hidden; + setTimeout(() => { + this.controller.close(); + }, 200) + } +} + +@Entry +@Component +struct CustomDialogUser { + dialogController: CustomDialogController = new CustomDialogController({ + builder: CustomDialogExample(), + autoCancel: false, + customStyle: true + }) + + build() { + Column() { + Button('click me') + .onClick(() => { + this.dialogController.open(); + }) + } + .width('100%') + .height('100%') + } +} +// [End customize_pop_up_and_close_animations] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/CustomizeTabs.ets b/ArkUI/entry/src/main/ets/pages/CustomizeTabs.ets new file mode 100644 index 0000000000000000000000000000000000000000..0643fbf289aa039f47aae15ce0ec24e21c45782e --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/CustomizeTabs.ets @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何自定义Tabs页签导航栏及其对齐方式 +*/ + +// [Start customize_tabs] +@Entry +@Component +struct CustomizeTheTabsBarAndItsAlignment { + @State focusIndex: number = 0; + private controller: TabsController = new TabsController(); + tabArray = [0, 1]; + + + // Custom tab + @Builder + Tab(tabName: string, tabItem: number, tabIndex: number) { + Column({ space: 20 }) { + Text(tabName).fontSize(18) + Image($r('app.media.startIcon')).width(20).height(20) + } + .width(100) + .height(60) + .borderRadius({ topLeft: 10, topRight: 10 }) + .onClick(() => { + this.controller.changeIndex(tabIndex); + this.focusIndex = tabIndex; + }) + .backgroundColor(tabIndex === this.focusIndex ? '#ffffffff' : '#ffb7b7b7') + } + + + build() { + Column() { + Column() { + // tab + Row({ space: 6 }) { + Scroll() { + Row() { + ForEach(this.tabArray, (item: number, index: number) => { + this.Tab('page' + item, item, index); + }) + } + .justifyContent(FlexAlign.Start) + } + // Set left alignment + .align(Alignment.Start) + .scrollable(ScrollDirection.Horizontal) + .scrollBar(BarState.Off) + .width('80%') + .backgroundColor('#ffb7b7b7') + } + .width('100%') + .backgroundColor('#ffb7b7b7') + + + // tabs + Tabs({ barPosition: BarPosition.Start, controller: this.controller }) { + ForEach(this.tabArray, (item: number, index: number) => { + TabContent() { + Text('I am the page ' + item + ' The content') + .height(300) + .width('100%') + .fontSize(30) + } + .backgroundColor(Color.Pink) + }) + } + .barHeight(0) + .animationDuration(100) + .onContentWillChange((currentIndex, comingIndex) => { + this.focusIndex = comingIndex; + console.info('foo change' + this.focusIndex); + return true; + }) + } + .alignItems(HorizontalAlign.Start) + .width('100%') + } + .height('100%') + } +} +// [end customize_tabs] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/CustomizeVideoStyles.ets b/ArkUI/entry/src/main/ets/pages/CustomizeVideoStyles.ets new file mode 100644 index 0000000000000000000000000000000000000000..e65d6d607e5e0d99079a8e8862f758cf811c5588 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/CustomizeVideoStyles.ets @@ -0,0 +1,109 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何自定义Video组件控制栏样式 +*/ + +// [Start customize_video_styles] +@Entry +@Component +struct VideoCreateComponent { + @State videoSrc: Resource = $rawfile('xxx.mp4') + @State previewUri: Resource = $r('app.media.xxx') + @State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_X + @State isAutoPlay: boolean = false + @State showControls: boolean = true + controller: VideoController = new VideoController() + + build() { + Column() { + Video({ + src: this.videoSrc, + previewUri: this.previewUri, + currentProgressRate: this.curRate, + controller: this.controller + }) + .width('100%') + .height(600) + .autoPlay(this.isAutoPlay) + .controls(this.showControls) + .onStart(() => { + console.info('onStart') + }) + .onPause(() => { + console.info('onPause') + }) + .onFinish(() => { + console.info('onFinish') + }) + .onError(() => { + console.info('onError') + }) + .onPrepared((e) => { + console.info('onPrepared is ' + e.duration) + }) + .onSeeking((e) => { + console.info('onSeeking is ' + e.time) + }) + .onSeeked((e) => { + console.info('onSeeked is ' + e.time) + }) + .onUpdate((e) => { + console.info('onUpdate is ' + e.time) + }) + Row() { + Button('src').onClick(() => { + this.videoSrc = $rawfile('xxx.mp4') // Switch video source + }).margin(5) + Button('previewUri').onClick(() => { + this.previewUri = $r('app.media.xxx') // Switch video preview poster + }).margin(5) + + Button('controls').onClick(() => { + this.showControls = !this.showControls // Switch whether to display the video control bar + }).margin(5) + } + + Row() { + Button('start').onClick(() => { + this.controller.start() // 开始播放 + }).margin(5) + Button('pause').onClick(() => { + this.controller.pause() // 暂停播放 + }).margin(5) + Button('stop').onClick(() => { + this.controller.stop() // 结束播放 + }).margin(5) + Button('setTime').onClick(() => { + this.controller.setCurrentTime(10, SeekMode.Accurate) // Accurately jump to the 10s position of the video + }).margin(5) + } + + Row() { + Button('rate 0.75').onClick(() => { + this.curRate = PlaybackSpeed.Speed_Forward_0_75_X // 0.75 times playback speed + }).margin(5) + Button('rate 1').onClick(() => { + this.curRate = PlaybackSpeed.Speed_Forward_1_00_X // Original speed playback + }).margin(5) + Button('rate 2').onClick(() => { + this.curRate = PlaybackSpeed.Speed_Forward_2_00_X // Play at 2x speed + }).margin(5) + } + } + } +} +// [End customize_video_styles] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/CutOffWhenSettingLargeIcon.ets b/ArkUI/entry/src/main/ets/pages/CutOffWhenSettingLargeIcon.ets new file mode 100644 index 0000000000000000000000000000000000000000..98c338946b39121d385f16db9f9bc38a3e0a5e52 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/CutOffWhenSettingLargeIcon.ets @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Navigation的toolbar中设置大图标时被切断 +*/ + +// [Start cut_off_when_setting_large_icon] +@Entry +@Component +struct NavigationExample { + build() { + Column() { + Navigation() { + }.toolbarConfiguration(this.NavigationToolbar) + } + .height('100%') + .width('100%') + .backgroundColor(Color.Gray) + } + + @Builder + NavigationToolbar() { + Row() { + Column() { + Image($r('app.media.icon')).width(24) + }.layoutWeight(1) + + Column() { + Image($r('app.media.icon')).width(24).scale({ x: 2, y: 2 }) + }.layoutWeight(1) + + Column() { + Image($r('app.media.icon')).width(24) + }.layoutWeight(1) + } + .height(34) + .width('100%').backgroundColor(Color.White) + } +} +// [End cut_off_when_setting_large_icon] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/DarkModeSwitchStatusBarColor.ets b/ArkUI/entry/src/main/ets/pages/DarkModeSwitchStatusBarColor.ets new file mode 100644 index 0000000000000000000000000000000000000000..a2b9b0ae9fd91e0cc3b144d4f72c73039d7246ec --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/DarkModeSwitchStatusBarColor.ets @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:在深色模式切换下如何适配状态栏颜色? +*/ + +// [Start dark_mode_switch_status_bar_color] +import { window } from '@kit.ArkUI'; +import { ConfigurationConstant } from '@kit.AbilityKit'; + + +@Entry +@Component +struct SysDarkMode { + @State message: string = 'page layout'; + @StorageProp('currentColorMode') @Watch('onColorModeChange') currentColorMode: number = + ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT; + + + aboutToAppear(): void { + this.onColorModeChange(); + } + + + onColorModeChange(): void { + // Get the current application window + let windowClass = AppStorage.get('windowClass') as window.Window; + + + if (this.currentColorMode === ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT) { + // Currently in light color mode + //Set the font to black + windowClass.setWindowSystemBarProperties({ + // Status bar text color + statusBarContentColor: '#000000' + }); + } else if (this.currentColorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK) { + // Currently in dark mode + //Set the font to white + windowClass.setWindowSystemBarProperties({ + // Status bar text color + statusBarContentColor: '#FFFFFF' + }); + } + } + + + build() { + Column() { + Row() + .width('100%') + .height(100) + .backgroundColor($r('app.color.status_bar')) + // page layout + Text(this.message) + .fontSize(50) + .fontColor(Color.Red) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { + anchor: '__container__', + align: VerticalAlign.Center + }, + middle: { + anchor: '__container__', + align: HorizontalAlign.Center + } + }) + .layoutWeight(1) + } + .height('100%') + .width('100%') + } +} +// [End dark_mode_switch_status_bar_color] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/DataUtil.ets b/ArkUI/entry/src/main/ets/pages/DataUtil.ets new file mode 100644 index 0000000000000000000000000000000000000000..fe80e1c9166287fa5ea351823f596e7a58577205 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/DataUtil.ets @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何合并两个列表并支持懒加载 +*/ + +// [Start merge_two_lists_and_support_lazy_loading_two] +// DataUtil.ets +export class BasicDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + private originDataArray: string[] = []; + + + public totalCount(): number { + return 0; + } + + + public getData(index: number): string { + return this.originDataArray[index]; + } + + + // This method is called on the framework side to add listener listening to the LazyForEach component at its data source + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + console.info('add listener'); + this.listeners.push(listener); + } + } + + + // This method is called on the framework side to remove listener listening for the corresponding LazyForEach component at the data source + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + console.info('remove listener'); + this.listeners.splice(pos, 1); + } + } + + + // Notify LazyForEach component to reload all child components + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + + // Notify LazyForEach component to add a sub component at the index corresponding to the index + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + + // Notify LazyForEach component that there is a change in data at the index corresponding to the index, and that the sub component needs to be rebuilt + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + + // Notify LazyForEach component to remove the sub component at the index corresponding to the index + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + + // Notify LazyForEach component to swap the subcomponents at the from index and to index + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } +} + + +export class MyDataSource extends BasicDataSource { + private dataArray: string[] = []; + + + public totalCount(): number { + return this.dataArray.length; + } + + + public getData(index: number): string { + return this.dataArray[index]; + } + + + public addData(index: number, data: string): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + + public pushData(data: string): void { + this.dataArray.push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } +} +// [End merge_two_lists_and_support_lazy_loading_two] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/DetermineWhetherTheListDataExceedsOneScreen_One.ets b/ArkUI/entry/src/main/ets/pages/DetermineWhetherTheListDataExceedsOneScreen_One.ets new file mode 100644 index 0000000000000000000000000000000000000000..6a7346db8cb951acc12bb26c8dda8c97a54545e9 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/DetermineWhetherTheListDataExceedsOneScreen_One.ets @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:List控件加载的数据如何判断是否超过一屏 +*/ + +// [Start determine_whether_the_list_data_exceeds_one_screen_one] +@Entry +@Component +struct AllListItemHeight { + private itemHeightArr = [100, 150, 200, 130, 120, 110.130]; + private listHeight = 700; + scroller = new ListScroller(); + + + build() { + Column() { + Button('Is it more than one screen') + .height(50) + .width('100%') + .onClick(() => { + let result = 0; + for (let i = 0; i < this.itemHeightArr.length; i++) { + result += this.itemHeightArr[i]; + } + console.info(result > this.listHeight ? 'More than one screen' : 'Not exceeding one screen'); + }) + List({ scroller: this.scroller }) { + ForEach(this.itemHeightArr, (_: number, index: number) => { + ListItem() { + Text(index.toString()) + .width('100%') + .textAlign(TextAlign.Center) + } + .height(this.itemHeightArr[index]) + .align(Alignment.Center) + }, (item: number) => JSON.stringify(item)) + } + .height(this.listHeight) + .width('100%') + } + } +} +// [End determine_whether_the_list_data_exceeds_one_screen_one] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/DetermineWhetherTheListDataExceedsOneScreen_Three.ets b/ArkUI/entry/src/main/ets/pages/DetermineWhetherTheListDataExceedsOneScreen_Three.ets new file mode 100644 index 0000000000000000000000000000000000000000..ca30bd954bb29bd76782eec4edac14f5c9f7308a --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/DetermineWhetherTheListDataExceedsOneScreen_Three.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:List控件加载的数据如何判断是否超过一屏 +*/ + +// [Start determine_whether_the_list_data_exceeds_one_screen_three] +@Entry +@Component +struct GetLastGroup { + private groupItemHeightArr = + [[30, 50, 60, 40, 90, 80.60], + [50, 40, 50, 55, 77, 88.44],]; + private listHeight = 700; + scroller = new ListScroller(); + + + build() { + Column() { + Button('Is it more than one screen') + .height(50) + .width('100%') + .onClick(() => { + let lastGroupIndex = this.groupItemHeightArr.length - 1; + let lastItemIndex = this.groupItemHeightArr[lastGroupIndex].length - 1; + let result = this.scroller.getItemRectInGroup(lastGroupIndex, lastItemIndex); + let flag = result.x == 0 && result.y == 0 && result.width == 0 && result.height == 0 + console.info(flag ? 'More than one screen' : 'Not exceeding one screen') + }) + List({ scroller: this.scroller }) { + ForEach(this.groupItemHeightArr, (itemHeight: number[], index: number) => { + ListItemGroup() { + ForEach(itemHeight, (height: number) => { + ListItem() { + Text(index.toString()) + .width('100%') + .textAlign(TextAlign.Center) + } + .height(height) + .align(Alignment.Center) + }, (item: number, index: number) => JSON.stringify(item) + index) + } + }, (item: number[]) => JSON.stringify(item)) + } + .height(this.listHeight) + .width('100%') + } + } +} +// [End determine_whether_the_list_data_exceeds_one_screen_three] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/DetermineWhetherTheListDataExceedsOneScreen_Two.ets b/ArkUI/entry/src/main/ets/pages/DetermineWhetherTheListDataExceedsOneScreen_Two.ets new file mode 100644 index 0000000000000000000000000000000000000000..dc2c806ce3f661e1cb3edd1069e245dcc1b0dbdc --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/DetermineWhetherTheListDataExceedsOneScreen_Two.ets @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:List控件加载的数据如何判断是否超过一屏 +*/ + +// [Start determine_whether_the_list_data_exceeds_one_screen_two] +@Entry +@Component +struct GetLastItem { + private itemHeightArr = [100, 150, 200, 130, 120, 110.130]; + private listHeight = 700; + scroller = new ListScroller(); + + + build() { + Column() { + Button('Is it more than one screen') + .height(50) + .width('100%') + .onClick(() => { + let result = this.scroller.getItemRect(this.itemHeightArr.length - 1); + let flag = result.x == 0 && result.y == 0 && result.width == 0 && result.height == 0 + console.info(flag ? 'More than one screen' : 'Not exceeding one screen') + }) + List({ scroller: this.scroller }) { + ForEach(this.itemHeightArr, (_: number, index: number) => { + ListItem() { + Text(index.toString()) + .width('100%') + .textAlign(TextAlign.Center) + } + .height(this.itemHeightArr[index]) + .align(Alignment.Center) + }, (item: number) => JSON.stringify(item)) + } + .height(this.listHeight) + .width('100%') + } + } +} +// [End determine_whether_the_list_data_exceeds_one_screen_two] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/DoNotDisplayTransitionalTabs.ets b/ArkUI/entry/src/main/ets/pages/DoNotDisplayTransitionalTabs.ets new file mode 100644 index 0000000000000000000000000000000000000000..7563a6aa1f653c13d29c1fe9029c8b4db8c30922 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/DoNotDisplayTransitionalTabs.ets @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Tab组件页面切换时,如何不显示中间过渡的tab页 +*/ + +// [Start do_not_display_transitional_tabs] +@Entry +@Component +struct TABTransitionAnimation { + @State fontColor: string = '#182431'; + @State selectedFontColor: string = '#007DFF'; + @State currentIndex: number = 0; + private controller: TabsController = new TabsController(); + + + @Builder + tabBuilder(index: number, name: string) { + Column() { + Text(name) + .fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor) + .fontSize(16) + .fontWeight(this.currentIndex === index ? 500 : 400) + .lineHeight(22) + .margin({ + top: 17, + bottom: 7 + }) + Divider() + .strokeWidth(2) + .color($r('sys.color.brand')) + .opacity(this.currentIndex === index ? 1 : 0) + } + .width('100%') + } + + + build() { + Column() { + Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) { + TabContent() { + Column() + .width('100%') + .height('100%') + .backgroundColor('#00CB87') + }.tabBar(this.tabBuilder(0, 'green')) + + + TabContent() { + Column() + .width('100%') + .height('100%') + .backgroundColor($r('sys.color.brand')) + }.tabBar(this.tabBuilder(1, 'blue')) + + + TabContent() { + Column() + .width('100%') + .height('100%') + .backgroundColor($r('sys.color.multi_color_11')) + }.tabBar(this.tabBuilder(2, 'yellow')) + + + TabContent() { + Column() + .width('100%') + .height('100%') + .backgroundColor('#E67C92') + } + .tabBar(this.tabBuilder(3, 'pink')) + } + .width(360) + .height(296) + .barWidth(360) + .barHeight(56) + .vertical(false) + .barMode(BarMode.Fixed) + .backgroundColor('#F1F3F5') + .margin({ top: 52 }) + .animationDuration(0) // Setting the animation time to 0 can solve the problem of switching between pages and displaying intermediate transition pages + .onChange((index: number) => { + this.currentIndex = index; + }) + } + .width('100%') + } +} +// [End do_not_display_transitional_tabs] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/DoesGridSupportCustomization.ets b/ArkUI/entry/src/main/ets/pages/DoesGridSupportCustomization.ets new file mode 100644 index 0000000000000000000000000000000000000000..0266da9025ebd7cb49c31306b787f89bdb5bf50b --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/DoesGridSupportCustomization.ets @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Grid组件的scrollBar是否支持自定义 +*/ + +// [Start does_rid_support_customization] +@Entry +@Component +struct Index { + private scroller: Scroller = new Scroller() + private arr: number[] = []; + + build() { + Column() { + Stack({ alignContent: Alignment.End }) { + Grid(this.scroller) { + ForEach(this.arr, (item: number) => { + GridItem() { + Text(item.toString()) + .width(100) + .height(50) + .backgroundColor('#3366CC') + .borderRadius(15) + .fontSize(16) + .textAlign(TextAlign.Center) + } + }) + } + .width('100%') + .columnsTemplate("1fr 1fr 1fr") + .columnsGap(5) + .rowsGap(5) + .scrollBar(BarState.Off) + + ScrollBar({ scroller: this.scroller, direction: ScrollBarDirection.Vertical, state: BarState.Auto }) { + Text("A") + .width(20) + .height(50) + .borderRadius(10) + .backgroundColor('#C0C0C0') + }.width(20).backgroundColor('#ededed') + } + } + } + + aboutToAppear() { + for (let i = 0; i < 100; i++) { + this.arr.push(i) + } + } +} +// [End does_rid_support_customization] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/DoesWidthSupportSettingVariables.ets b/ArkUI/entry/src/main/ets/pages/DoesWidthSupportSettingVariables.ets new file mode 100644 index 0000000000000000000000000000000000000000..0c6bad08d2c0183abd51a8a34e5d156bf5117e35 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/DoesWidthSupportSettingVariables.ets @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:通用属性width是否支持设置变量 +*/ + +// [Start does_width_support_setting_variables] +@Entry +@Component +struct Page1 { + @State message: string = 'Hello'; + @State widNum: number = 300; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .width(this.widNum) + .backgroundColor(Color.Blue) + } + .width('100%') + } + .height('100%') + } +} +// [End does_width_support_setting_variables] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/DoubleNestedListsWork.ets b/ArkUI/entry/src/main/ets/pages/DoubleNestedListsWork.ets new file mode 100644 index 0000000000000000000000000000000000000000..fe465edfac4fd5f55615b944cdda7527b9ea2f3f --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/DoubleNestedListsWork.ets @@ -0,0 +1,278 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:双层嵌套list,如何使用LazyForEach起作用 +*/ + +// [Start double_nested_lists_work] +export class BaseDataSource implements IDataSource { + private readonly listeners: DataChangeListener[] = []; + protected dataset: T[]; + + + constructor(dataset?: T[]) { + this.dataset = dataset ?? []; + } + + + public resetDataset(dataset: T[]) { + this.dataset = dataset; + this.notifyDataReload(); + } + + + public updateDataAt(index: number, data: T) { + if (index >= 0 && index < this.dataset.length) { + this.dataset[index] = data; + this.notifyDataChange(index); + } + } + + + public getDataset() { + return this.dataset; + } + + + public totalCount(): number { + return this.dataset.length; + } + + + public getData(index: number): T { + return this.dataset[index]; + } + + + /** + * Notify LazyForEach component to reload all child components + */ + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + + /** + * Notify LazyForEach component to add a sub component at the index corresponding to the index + * @param index + */ + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + + /** + * Notify LazyForEach component that there is a change in data at the index corresponding to the index, and that the sub component needs to be rebuilt + * @param index + */ + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + + /** + * Notify LazyForEach component to remove the sub component at the index corresponding to the index + * @param index + */ + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + + /** + * Notify LazyForEach component to swap the subcomponents at the from index and to index + * @param from + * @param to + */ + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } + + + //---------------------------------------------------------------------------------------------------- + // This method is called on the framework side to add listener listening to the LazyForEach component at its data source + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener); + } + } + + + // This method is called on the framework side to remove listener listening for the corresponding LazyForEach component at the data source + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + this.listeners.splice(pos, 1); + } + } +} + + + + +class NewPosItemDataSource extends BaseDataSource { + private dataArray: string[] = []; + + + public totalCount(): number { + return this.dataArray.length; + } + + + public getData(index: number): string { + return this.dataArray[index]; + } + + + public addData(index: number, data: string): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + + public pushData(data: string): void { + this.dataArray.push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } +} + + +const bgColors: ResourceColor[] = [Color.Blue, Color.Gray]; +const rowHeight = 60; + + +@Component +struct header { + title: string = ''; + + + build() { + Column() { + Text(this.title) + .width('100%') + .height(40) + .fontSize(14) + .backgroundColor(Color.Yellow) + .fontColor(Color.Blue) + .textAlign(TextAlign.Center) + } + } +} + + +@Component +struct Itemcomponent { + title: string = ''; + @Prop datas: string[]; + + + generateDataSource() { + let datasource: NewPosItemDataSource = new NewPosItemDataSource(); + for (let index = 0; index < this.datas.length; index++) { + const element = this.datas[index]; + datasource.pushData(element); + } + return datasource; + } + + + build() { + Column() { + header({ title: this.title }) + List() { + LazyForEach(this.generateDataSource(), (data: string, index) => { + ListItem() { + Text(data) + .width('100%') + .fontSize(14) + .backgroundColor(Color.White) + .fontColor(bgColors[index % bgColors.length]) + .textAlign(TextAlign.Center) + } + .height(rowHeight) + }, (data: string, index) => { + console.log(`------- ${data + ' - ' + index.toString()}`); + return data + ' - ' + index.toString(); + }) + } + .layoutWeight(1) + .scrollBar(BarState.Off) + .cachedCount(10) + .friction(1.25) + .edgeEffect(EdgeEffect.None) + } + } +} + + +function generateData(pre: string, count: number) { + let datas: string[] = []; + for (let index = 0; index < count; index++) { + const element = pre + '-' + index.toString(); + datas.push(element); + } + return datas; +} + + +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + private scroll: Scroller = new Scroller(); + + + @Builder + private mainListView() { + List({ scroller: this.scroll }) { + ListItem() { + Itemcomponent({ title: 'A', datas: generateData('A', 200) }) + } + // .height(40 + 200 * rowHeight) // After adding the height attribute, the content area of the inner list will be as high as the visible area, causing LazyForEach to become invalid + + + ListItem() { + Itemcomponent({ title: 'B', datas: generateData('B', 20) }) + } + // .height(40 + 20 * rowHeight) // After adding the height attribute, the content area of the inner list will be as high as the visible area, causing LazyForEach to become invalid + } + .divider({ strokeWidth: 10, color: Color.Gray }) + .height("100%") + .width("100%") + .scrollBar(BarState.Off) + .edgeEffect(EdgeEffect.None) + } + + + build() { + Column() { + this.mainListView() + }.width('100%') + .height('100%') + .backgroundColor(Color.White) + } +} +// [End double_nested_lists_work] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/DrawRoundedRectanglesUsingCanvas.ets b/ArkUI/entry/src/main/ets/pages/DrawRoundedRectanglesUsingCanvas.ets new file mode 100644 index 0000000000000000000000000000000000000000..32be373fb4592ffd065b370e8b198b496e993728 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/DrawRoundedRectanglesUsingCanvas.ets @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何使用canvas绘制圆角矩形 +*/ + +// [Start draw_rounded_rectangles_using_canvas] +@Entry +@Component +struct CanvasDrawRoundedRectangle { + private readonly settings: RenderingContextSettings = new RenderingContextSettings(true); + private readonly ctx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); + + + drawRoundRect(x: number, y: number, width: number, height: number, radius: number, strokeColor?: string, + fillColor?: string, lineDash?: []) { + strokeColor = strokeColor || '#333'; + lineDash = lineDash || []; + this.ctx.beginPath(); + this.ctx.setLineDash(lineDash); + // Draw the first arc path + this.ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2); + // Draw the first straight path + this.ctx.lineTo(width - radius + x, y); + // Draw the second arc path + this.ctx.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2); + // Draw the second straight path + this.ctx.lineTo(width + x, height + y - radius); + // Draw the third arc path + this.ctx.arc(width - radius + x, height - radius + y, radius, 0, Math.PI / 2); + // Draw the third straight path + this.ctx.lineTo(radius + x, height + y); + // Draw the fourth arc path + this.ctx.arc(radius + x, height - radius + y, radius, Math.PI / 2, Math.PI); + // Draw the fourth straight path + this.ctx.lineTo(x, y + radius); + // Set brush color + this.ctx.strokeStyle = strokeColor; + // Stroke drawing + this.ctx.stroke(); + if (fillColor) { + this.ctx.fillStyle = fillColor; + this.ctx.fill(); + } + this.ctx.closePath(); + } + + + build() { + Row() { + Column() { + Canvas(this.ctx) + .width('100%') + .height('100%') + .onReady(() => { + this.drawRoundRect(50, 50, 100, 100, 10); + }) + } + .width('100%') + } + .height('100%') + } +} +// [End draw_rounded_rectangles_using_canvas] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/DynamicallyControlKeyboardBinding.ets b/ArkUI/entry/src/main/ets/pages/DynamicallyControlKeyboardBinding.ets new file mode 100644 index 0000000000000000000000000000000000000000..af565985c17c4164b9a68f05fdd469391699d6b4 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/DynamicallyControlKeyboardBinding.ets @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何动态控制键盘绑定在不同的TextInput上 +*/ + +// [Start dynamically_control_keyboard_binding] +@Entry +@Component +struct DynamicControlKeyboard { + private flag: boolean = true; + @Builder + Kb() { + Row() { + Text('Customize keyboard') + } + .justifyContent(FlexAlign.Center) + .width('1260px') + .height('1161px') + .backgroundColor(Color.Brown) + } + build() { + Column({space: 10}) { + TextInput() + .key('key1') + .onAppear(() => { + focusControl.requestFocus('key1'); + }) + .defaultFocus(true) + TextInput() + .key('key2') + .customKeyboard(this.Kb()) + Button('Switch TextInput') + .onClick(() => { + if (this.flag) { + console.info('TextInput2 ==> ' + focusControl.requestFocus('key2')); + } else { + console.info('TextInput1 ==> ' + focusControl.requestFocus('key1')); + } + this.flag = !this.flag; + }) + Button() + .width(0) + .height(0) + .key('key3') + } + .padding({ top: 20 }) + .width('100%') + .height('100%') + .onClick(() => { + focusControl.requestFocus('key3'); + }) + } +} +// [End dynamically_control_keyboard_binding] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/FullScreenStatusBar.ets b/ArkUI/entry/src/main/ets/pages/FullScreenStatusBar.ets new file mode 100644 index 0000000000000000000000000000000000000000..461337e6ca6aeb65c6ff6d8690603704017dfdff --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/FullScreenStatusBar.ets @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:进入全屏模式后隐藏状态栏,退出全屏模式如何显示状态栏? +*/ + +// [Start full_screen_status_bar] +import { window } from '@kit.ArkUI'; + + +@Entry +@Component +struct GridImage { + @State message: string = 'Hello World'; + @State isVisible: boolean = true; + @State isVisibleButton: boolean = true; + data: number[] = []; + windowClass = AppStorage.get('windowClass') as window.Window; + + + aboutToAppear(): void { + for (let i = 0; i < 40; i++) { + this.data.push(i); + } + } + + + build() { + Stack() { + Grid() { + ForEach(this.data, (item: number, index: number) => { + GridItem() { + Image($r('app.media.startIcon')) + .width('100%') + .objectFit(ImageFit.Cover) + .onClick(() => { + let isLayoutFullScreen = true; + this.windowClass.setWindowLayoutFullScreen(isLayoutFullScreen); + this.windowClass.setSpecificSystemBarEnabled('status', false); + this.windowClass.setSpecificSystemBarEnabled('navigationIndicator', false); + this.isVisible = !this.isVisible; + }) + } + .aspectRatio(1) + }, (item: number, index: number) => JSON.stringify(item) + index) + } + .visibility(this.isVisible ? Visibility.Visible : Visibility.None) + .columnsTemplate('1fr 1fr 1fr 1fr') + .rowsGap(2) + .columnsGap(2) + .height('100%') + .width('100%') + + + Image($r('app.media.startIcon')) + .objectFit(ImageFit.Contain) + .width('100%') + .visibility(this.isVisible ? Visibility.None : Visibility.Visible) + .onClick(() => { + let isLayoutFullScreen = false; + this.windowClass.setSpecificSystemBarEnabled('status', true); + this.windowClass.setSpecificSystemBarEnabled('navigationIndicator', true); + this.windowClass.setWindowLayoutFullScreen(isLayoutFullScreen); + this.isVisible = !this.isVisible; + }) + } + } +} +// [End full_screen_status_bar] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/GetPhoneScreenInformation.ets b/ArkUI/entry/src/main/ets/pages/GetPhoneScreenInformation.ets new file mode 100644 index 0000000000000000000000000000000000000000..69d671c75da7490f3a0930759930c4f1078fc01f --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/GetPhoneScreenInformation.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取手机屏幕信息 +*/ + +// [Start get_phone_screen_information] +import { display } from '@kit.ArkUI'; + +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + private screenWidth: number = 0; + private screenHeight: number = 0; + + aboutToAppear() { + try { + this.screenWidth = display.getDefaultDisplaySync().width; + this.screenHeight = display.getDefaultDisplaySync().height; + } catch (e) { + console.error('Fail with code: ' + JSON.stringify(e)); + } + } + + build() { + Row() { + Column() { + Text('---->width: ' + this.screenWidth) + Text('---->height: ' + this.screenHeight) + } + .width('100%') + } + .height('100%') + } +} +// [End get_phone_screen_information] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/GetTheFocusScene_Four.ets b/ArkUI/entry/src/main/ets/pages/GetTheFocusScene_Four.ets new file mode 100644 index 0000000000000000000000000000000000000000..aa5482e05ebde6c959360325c04176554b52527a --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/GetTheFocusScene_Four.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:TextInput组件获取焦点的几种场景 +*/ + +// [Start get_the_focus_scene_four] +// xxx.ets +@Entry +@Component +struct TextInputExample { + build() { + Column() { + TextInput({ placeholder: 'Please enter the content.' }) + } + .width('100%') + } +} +// [End get_the_focus_scene_four] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/GetTheFocusScene_One.ets b/ArkUI/entry/src/main/ets/pages/GetTheFocusScene_One.ets new file mode 100644 index 0000000000000000000000000000000000000000..9b722dbe02d171b47eb55eb9894d2792c6588595 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/GetTheFocusScene_One.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:TextInput组件获取焦点的几种场景 +*/ + +// [Start get_the_focus_scene_one] +// xxx.ets +@Entry +@Component +struct TextInputExample { + build() { + Row() { + Column() { + Button('The second focus acquisition') + .onClick(() => { + focusControl.requestFocus('BBB'); // Get focus on the second input box + }) + + + TextInput({ placeholder: 'Please enter the content.' }) + .showUnderline(true) + .width(380) + .height(60) + .key('AAA') + TextInput({ placeholder: 'Please enter the content.' }) + .showUnderline(true) + .width(380) + .height(60) + .key('BBB') + } + .width('100%') + } + .height('100%') + } +} +// [End get_the_focus_scene_one] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/GetTheFocusScene_Three.ets b/ArkUI/entry/src/main/ets/pages/GetTheFocusScene_Three.ets new file mode 100644 index 0000000000000000000000000000000000000000..8854c832912fa13c44620c9a3dd9f953462b8966 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/GetTheFocusScene_Three.ets @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:TextInput组件获取焦点的几种场景 +*/ + +// [Start get_the_focus_scene_three] +// xxx.ets +@Entry +@Component +struct TextInputExample { + build() { + Row() { + Column() { + TextInput({ placeholder: 'Please enter the content.' }) + .defaultFocus(true) // When the page is first opened, this TextInput gets focus + .enableKeyboardOnFocus(false) // Is TextInput bound to an input method when focusing through methods other than clicking. + .placeholderColor(Color.Grey) + .placeholderFont({ size: 14, weight: 400 }) + .caretColor(Color.Blue) + .width('95%') + .height(40) + .margin(20) + } + .width('100%') + } + .height('100%') + } +} +// [End get_the_focus_scene_three] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/GetTheFocusScene_Two.ets b/ArkUI/entry/src/main/ets/pages/GetTheFocusScene_Two.ets new file mode 100644 index 0000000000000000000000000000000000000000..edf8e4cc381ad0d0f548bcffae116dbfd45af7d2 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/GetTheFocusScene_Two.ets @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:TextInput组件获取焦点的几种场景 +*/ + +// [Start get_the_focus_scene_two] +// xxx.ets +@Entry +@Component +struct TextInputExample { + build() { + Row() { + Column() { + TextInput({ placeholder: 'Please enter the content.' }) + .showUnderline(true) + .width(380) + .height(60) + + + TextInput({ placeholder: 'Please enter the content.' }) + .showUnderline(true) + .defaultFocus(true) // When the page is first opened, this TextInput gets focus + .width(380) + .height(60) + } + .width('100%') + } + .height('100%') + } +} +// [End get_the_focus_scene_two] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/GetUIComponentStatus.ets b/ArkUI/entry/src/main/ets/pages/GetUIComponentStatus.ets new file mode 100644 index 0000000000000000000000000000000000000000..e681252bc9300ba7d1e7005c00bc755db030c79b --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/GetUIComponentStatus.ets @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取UI组件的显示或隐藏状态 +*/ + +// [Start get_ui_component_status] +@Component +struct componentA { + aboutToAppear(): void { + // Perception components are visible and hidden + console.log('Component A display'); + } + + aboutToDisappear(): void { + // Perception components are visible and hidden + console.log('Component A hidden'); + } + + build() { + Column() { + Text('Component A').fontSize(16).fontColor(Color.Black); + } + .width(100) + .height(50) + } +} + +@Entry +@Component +struct componentB { + @State @Watch('onCompAShowStatusChange') isShowA: boolean = false; + onCompAShowStatusChange() { + // Perception components are visible and hidden + console.log('Monitor component A:' + `${this.isShowA ? 'display' : 'hide'}`); + } + + build() { + Column() { + Button('Switch between visible and hidden').type(ButtonType.Normal).width(100).height(50).onClick(() => { + this.isShowA = !this.isShowA; + }) + if (this.isShowA) { + componentA(); + } + } + } +} +// [End get_ui_component_status] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/GradientMaskForLiveCommentScene.ets b/ArkUI/entry/src/main/ets/pages/GradientMaskForLiveCommentScene.ets new file mode 100644 index 0000000000000000000000000000000000000000..d85ee2b3efe175c760d56e38df892b5e6c60e509 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/GradientMaskForLiveCommentScene.ets @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现直播评论场景中顶部渐变遮罩效果 +*/ + +// [Start gradient_mask_for_live_comment_scene] +@Entry +@Component +struct MaskDemo { + private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + + + @Builder + overlayBuilder() { + Stack() + .height('100%') + .width('100%') + .linearGradient({ + direction: GradientDirection.Bottom, // Gradient direction + colors: [['#00FFFFFF', 0.0], ['#FFFFFFFF', 0.3]] // When the proportion of elements at the end of the array is less than 1, it satisfies the repeated shading effect + }) + .blendMode(BlendMode.DST_IN, BlendApplyType.OFFSCREEN) + .hitTestBehavior(HitTestMode.None) + } + + + build() { + Column() { + List({ space: 20, initialIndex: 0 }) { + ForEach(this.arr, (item: number) => { + ListItem() { + Text('' + item) + .width('100%') + .height(100) + .fontSize(16) + .textAlign(TextAlign.Center) + .borderRadius(10) + .backgroundColor(0xFFFFFF) + } + .onClick(() => { + console.log('is click'); + }) + }, (item: string) => item) + } + .width('90%') + .height('100%') + .scrollBar(BarState.Off) + .overlay(this.overlayBuilder()) + .blendMode(BlendMode.SRC_OVER, BlendApplyType.OFFSCREEN) + } + .width('100%') + .height('100%') + .backgroundColor(0xDCDCDC) + } +} +// [End gradient_mask_for_live_comment_scene] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/GradientTransparencyVaries.ets b/ArkUI/entry/src/main/ets/pages/GradientTransparencyVaries.ets new file mode 100644 index 0000000000000000000000000000000000000000..28cf4db7b8a9bbefcb459b4b0fe6efa214b4b4f1 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/GradientTransparencyVaries.ets @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:使用0x八位颜色设置渐变透明度为什么与#八位资源颜色值不同 +*/ + +// [Start gradient_transparency_varies] +@Entry +@Component +struct ColorGradientExample { + @State transparent: number | string = '#00333333'; + bool: boolean = true; + + build() { + Column({ space: 5 }) { + Text('linearGradient') + .fontSize(12) + .width('90%') + .fontColor(0xCCCCCC) + Row() + .width('90%') + .height(150) + .linearGradient({ + direction: GradientDirection.Bottom, + colors: [[this.transparent, 0.0], [0x80000000, 1.0]] + }) + Button('Switch color resources') + .onClick(() => { + if (this.bool) { + this.transparent = 0x00333333; + this.bool = false; + } else { + this.transparent = '#00333333'; + this.bool = true; + } + }) + } + .justifyContent(FlexAlign.Center) + .width('100%') + .height('100%') + .padding({ top: 5 }) + } +} +// [End gradient_transparency_varies] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/GridImplementationDragAndDrop.ets b/ArkUI/entry/src/main/ets/pages/GridImplementationDragAndDrop.ets new file mode 100644 index 0000000000000000000000000000000000000000..2bcb7e1005bb3afb3b6c8f9cbbeea7ca62516947 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/GridImplementationDragAndDrop.ets @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Grid如何实现拖拽功能 +*/ + +// [Start grid_implementation_drag_and_drop] +@Component +export struct GridExample { + @State numbers: string[] = []; + scroller: Scroller = new Scroller(); + + // Drag and drop process style + @Builder + pixelMapBuilder(text: string) { + Column() { + Text(text) + .fontSize(16) + .backgroundColor(0xF9CF93) + .width(80) + .height(80) + .textAlign(TextAlign.Center) + } + } + + aboutToAppear() { + for (let i = 1; i <= 15; i++) { + this.numbers.push(i + ''); + } + } + + // Swap array positions + changeIndex(index1: number, index2: number) { + let temp: string; + temp = this.numbers[index1]; + this.numbers[index1] = this.numbers[index2]; + this.numbers[index2] = temp; + } + + build() { + Column({ space: 5 }) { + Grid(this.scroller) { + ForEach(this.numbers, (day: string) => { + GridItem() { + this.pixelMapBuilder(day) + } + }) + } + .columnsTemplate('1fr 1fr 1fr') + .columnsGap(10) + .rowsGap(10) + .width('90%') + .backgroundColor(0xFAEEE0) + .height(500) + .editMode(true) // Set whether the Grid enters editing mode. When entering editing mode, you can drag and drop the GridItem inside the Grid component + .onItemDragStart((event: ItemDragInfo, itemIndex: number) => { // 第一次拖拽此事件绑定的组件时,触发回调。 + // Set the image displayed during the drag and drop process + return this.pixelMapBuilder(this.numbers[itemIndex]); + }) + .onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => { + // The component bound to this event can be used as a drag and drop release target. When the drag behavior stops within the scope of this component, a callback is triggered. + // When isSuccess=false, it indicates that the drop is located outside the grid; When insertIndex>length, it indicates that an event of adding new elements has occurred + if (!isSuccess || insertIndex >= this.numbers.length) { + return; + } + this.changeIndex(itemIndex, insertIndex); + }) + } + .width('100%') + .margin({ top: 5 }) + } +} +// [End grid_implementation_drag_and_drop] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/IgnoreSingleClickGestures.ets b/ArkUI/entry/src/main/ets/pages/IgnoreSingleClickGestures.ets new file mode 100644 index 0000000000000000000000000000000000000000..cdfcd68f5b4cd8bf45f7ef4f5ad92608c8eb0e7a --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/IgnoreSingleClickGestures.ets @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何识别双击手势时忽视单击手势? +*/ + +// [Start ignore_single_click_gestures] +@Entry +@Component +struct TapGestureExample { + build() { + Column() { + Text('Click twice') + .fontSize(28) + .gesture(GestureGroup(GestureMode.Exclusive, + TapGesture({ count: 2 }) + .onAction(() => { + console.info('TapGesture 2'); + }), + TapGesture({ count: 1 }) + .onAction(() => { + console.info('TapGesture 1'); + }) + ) + ) + } + .width('100%') + .height('100%') + .justifyContent(FlexAlign.Center) + .alignSelf(ItemAlign.Center) + } +} +// [End ignore_single_click_gestures] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImageAddGradientBlur.ets b/ArkUI/entry/src/main/ets/pages/ImageAddGradientBlur.ets new file mode 100644 index 0000000000000000000000000000000000000000..c2cc20f12f80c7bf15b76eefb15614ae97fee3a4 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImageAddGradientBlur.ets @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:图片如何添加渐变模糊 +*/ + +// [Start image_add_gradient_blur] +@Entry +@Component +struct ImageExample1 { + private_resource1: Resource = $r('app.media.icon'); + @State image_src: Resource = this.private_resource1; + + build() { + Column() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) { + Row({ space: 5 }) { + Image(this.image_src) + .linearGradientBlur(60, { + fractionStops: [[0, 0], [0, 0.33], [1, 0.66], [1, 1]], + direction: GradientDirection.Bottom + }) + } + } + } + } +} +// [End image_add_gradient_blur] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImageComponentGestureConflict.ets b/ArkUI/entry/src/main/ets/pages/ImageComponentGestureConflict.ets new file mode 100644 index 0000000000000000000000000000000000000000..e005307fba63f46dc080d86d2388ea39d03413f6 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImageComponentGestureConflict.ets @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Image组件长按和拖拽的系统手势和自定义手势冲突 +*/ + +// [Start image_component_gesture_conflict] +@Entry +@Component +struct Index { + build() { + Column() { + Image($r('app.media.app_icon')) + .width('80%') + .parallelGesture(GestureGroup(GestureMode.Exclusive, + TapGesture({ count: 2, fingers: 1 }) + .onAction(() => { + console.log('TapGesture--double click'); + }), + TapGesture({ count: 1, fingers: 1 }) + .onAction(() => { + console.log('TapGesture--single click'); + }), + LongPressGesture({ repeat: true }) + .onAction(() => { + console.log('LongPressGesture--Long press'); + }), + PanGesture() + .onActionStart((event: GestureEvent | undefined) => { + console.info('PanGesture--drag'); + }) + )) + } + .height('100%') + .width('100%') + } +} +// [End image_component_gesture_conflict] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImmersingBackgroundColorOfStatusBar_One.ets b/ArkUI/entry/src/main/ets/pages/ImmersingBackgroundColorOfStatusBar_One.ets new file mode 100644 index 0000000000000000000000000000000000000000..5219d9ccdd54eb55e013cb6f468f27eca9cb2ce5 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImmersingBackgroundColorOfStatusBar_One.ets @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现状态栏背景颜色沉浸? +*/ + +// [Start immersing_background_color_of_status_bar_one] +@Entry +@Component +struct Example { + build() { + Column() { + Row() { + Text('Top Row') + .fontSize(40) + .textAlign(TextAlign.Center) + .width('100%') + } + .backgroundColor('#F08080') + // Set the top drawing to extend to the status bar + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP]) + + + Row() { + Text('ROW2') + .fontSize(40) + } + .backgroundColor(Color.Orange) + .padding(20) + + + Row() { + Text('ROW3') + .fontSize(40) + } + .backgroundColor(Color.Orange) + .padding(20) + + + Row() { + Text('ROW4') + .fontSize(40) + } + .backgroundColor(Color.Orange) + .padding(20) + + + Row() { + Text('ROW5') + .fontSize(40) + } + .backgroundColor(Color.Orange) + .padding(20) + + + Row() { + Text('Bottom Row') + .fontSize(40) + .textAlign(TextAlign.Center) + .width('100%') + } + .backgroundColor(Color.Orange) + // Set the bottom drawing to extend to the navigation bar + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + } + .width('100%') + .height('100%') + .alignItems(HorizontalAlign.Center) + .backgroundColor('#008000') + .justifyContent(FlexAlign.SpaceBetween) + } +} +// [End immersing_background_color_of_status_bar_one] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImmersingBackgroundColorOfStatusBar_Two.ets b/ArkUI/entry/src/main/ets/pages/ImmersingBackgroundColorOfStatusBar_Two.ets new file mode 100644 index 0000000000000000000000000000000000000000..10c5236621a850a2e28105c13170f2c89760189a --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImmersingBackgroundColorOfStatusBar_Two.ets @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现状态栏背景颜色沉浸? +*/ + +// [Start immersing_background_color_of_status_bar_two] +import { window } from '@kit.ArkUI'; + + +@Entry +@Component +struct CommonTopBar { + @State message: string = 'Hello World'; + + + aboutToAppear() { + // Get the current application window + let windowClass = AppStorage.get('windowClass') as window.Window; + // Set the background color of the status bar and navigation bar to the same color as the application window + windowClass.setWindowSystemBarProperties({ + // The color attribute is ARGB, set the dust cover to 0% to make it transparent + // Navigation bar color + navigationBarColor: '#fd121de5', + // Status bar color + statusBarColor: '#ff0ad9c2', + // Status bar text color + statusBarContentColor: '#fff1e50a' + }) + } + + + build() { + RelativeContainer() { + Text(this.message) + .id('PageHelloWorld') + .fontSize(50) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { + anchor: '__container__', + align: VerticalAlign.Center + }, + middle: { + anchor: '__container__', + align: HorizontalAlign.Center + } + }) + } + .height('100%') + .width('100%') + } +} +// [End immersing_background_color_of_status_bar_two] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementArkUIComponentStringVariableConcatenation.ets b/ArkUI/entry/src/main/ets/pages/ImplementArkUIComponentStringVariableConcatenation.ets new file mode 100644 index 0000000000000000000000000000000000000000..bc8b7f5041a9b7a6f204902a279e2e4414017286 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementArkUIComponentStringVariableConcatenation.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现ArkUI组件字符串变量拼接 +*/ + +// [Start implement_ArkUI_component_string_variable_concatenation] +@Entry +@Component +struct Page1 { + @State num1: number = 100; + + build() { + Row() { + Column() { + Text($r('app.string.module_desc', this.num1)) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } +} +// [End implement_ArkUI_component_string_variable_concatenation] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementCrossFilComponentReuse.ets b/ArkUI/entry/src/main/ets/pages/ImplementCrossFilComponentReuse.ets new file mode 100644 index 0000000000000000000000000000000000000000..3817788efadc179a1df96c9cc174f700e8f10772 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementCrossFilComponentReuse.ets @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现跨文件组件复用 +*/ + +// [Start implement_cross_file_component_reuse_two] +import { ImageText, ImageModifier, TextModifier, CheckboxModifier } from './CommonText'; + +@Entry +@Component +struct Details { + // User creates an AttributeModifier implementation class instance for the provider + @State textOne: TextModifier = new TextModifier(36); + @State imageModifier: ImageModifier = new ImageModifier(100, 100); + @State checkboxModifier: CheckboxModifier = new CheckboxModifier(20); + + build(){ + Row(){ + ImageText({ + textOne: this.textOne, + imageModifier: this.imageModifier, + imageSrc: $r('app.media.icon'), + checkboxModifier: this.checkboxModifier, + textOneContent: 'hello' + }) + } + .width('100%') + .height('100%') + .alignItems(VerticalAlign.Center) + .justifyContent(FlexAlign.Center) + } +} +// [End implement_cross_file_component_reuse_two] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementCrossFileStyleReuse.ets b/ArkUI/entry/src/main/ets/pages/ImplementCrossFileStyleReuse.ets new file mode 100644 index 0000000000000000000000000000000000000000..fb45e9e00b91c2f40f7d1fdb23a28164376d7070 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementCrossFileStyleReuse.ets @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取UI组件的显示或隐藏状态 +*/ + +// [Start implement_cross_file_style_reuse_two] +import { CommodityText, TextType } from './attributeModifier'; + +@Entry +@Component +export struct Details { + // User creates an AttributeModifier implementation class instance for the provider + @State textOne: CommodityText = new CommodityText(TextType.TYPE_FOUR, 15); + + build(){ + Row(){ + Text($r('app.string.app_name')) + .attributeModifier(this.textOne) + .textAlign(TextAlign.Center) + } + .width('100%') + .height('100%') + .alignItems(VerticalAlign.Center) + .justifyContent(FlexAlign.Center) + } +} +// [End implement_cross_file_style_reuse_two] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementDropdownBackgroundBlurring.ets b/ArkUI/entry/src/main/ets/pages/ImplementDropdownBackgroundBlurring.ets new file mode 100644 index 0000000000000000000000000000000000000000..7f4a2163229f51606f9c273520705a2035d9c471 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementDropdownBackgroundBlurring.ets @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:控制中心的下拉背景实时模糊是如何实现的 +*/ + +// [Start implement_dropdown_background_blurring] +// xxx.ets +@Entry +@Component +struct BackGroundBlur { + private imageSize: number = 150; + + build() { + Column() { + // backdropBlur Only blur radius and grayscale parameters can be set + Stack() { + Image($r('app.media.startIcon')) + .width(this.imageSize) + .height(this.imageSize) + Column() + .width(this.imageSize) + .height(this.imageSize) + .backdropBlur(20, { grayscale: [30, 50] }) + } + } + .width('100%') + .padding({ top: 5 }) + } +} +// [End implement_dropdown_background_blurring] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementDynamicComponentTreeUpAndDown.ets b/ArkUI/entry/src/main/ets/pages/ImplementDynamicComponentTreeUpAndDown.ets new file mode 100644 index 0000000000000000000000000000000000000000..2b36c2672e58f89e94cc158090b05b5d1ff4e1b4 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementDynamicComponentTreeUpAndDown.ets @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现组件动态上下树 +*/ + +// [Start implement_dynamic_component_tree_up_and_down] +import { FrameNode, NodeController, BuilderNode } from '@kit.ArkUI'; + + +declare class Params { + text: string; +} + + +@Builder +function textInputBuilder(params: Params) { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceEvenly }) { + Text(params.text) + .fontSize(12) + Button(`This is a Button`, { type: ButtonType.Normal, stateEffect: true }) + .fontSize(12) + .borderRadius(8) + .backgroundColor(0x317aff) + } + .height(100) + .width(200) +} + + +class MyNodeController extends NodeController { + private rootNode: FrameNode | null = null; // Create root node + private textInputBuilder: WrappedBuilder<[Params]> = wrapBuilder(textInputBuilder); + private buildNode: BuilderNode<[Params]> | null = null; + + + makeNode(uiContext: UIContext): FrameNode | null { + this.rootNode = new FrameNode(uiContext); // Root node initialization + this.buildNode = new BuilderNode(uiContext); + const rootRenderNode = this.rootNode.getRenderNode(); // Get rendering nodes + if (rootRenderNode !== null) { + this.buildNode.build(this.textInputBuilder, { text: 'This is a Text' }); + rootRenderNode.appendChild(this.buildNode.getFrameNode()?.getRenderNode()); // Add new child nodes after rendering nodes + console.info('rootRenderNode.appendChild'); + } + return this.rootNode; + } +} + + +@Entry +@Component +struct RenderNode_pages { + private myNodeController: MyNodeController = new MyNodeController(); + + + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.SpaceEvenly }) { + NodeContainer(this.myNodeController) + .borderWidth(1) + .height(500) + .width(330) + + + Button(`Adding a Node`, { type: ButtonType.Normal, stateEffect: true }) + .fontSize(12) + .borderRadius(8) + .backgroundColor(0x317aff) + .onClick(() => { + this.myNodeController.rebuild(); + }) + } + .padding({ left: 35, right: 35, top: 35 }) + .height(500) + .width(500) + } +} +// [End implement_dynamic_component_tree_up_and_down] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementImmersivePages.ets b/ArkUI/entry/src/main/ets/pages/ImplementImmersivePages.ets new file mode 100644 index 0000000000000000000000000000000000000000..be88e0258ec4d0f0bd5a050d9824db85ed472adb --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementImmersivePages.ets @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现沉浸式页面(包括沉浸式状态栏、沉浸式导航条) +*/ + +// [Start implement_immersive_pages] +@Entry +@Component +struct Example { + build() { + Column() { + Row() { + Text('Top Row') + .fontSize(40) + .textAlign(TextAlign.Center) + .width('100%') + } + .backgroundColor('#F08080') + // Set the top drawing to extend to the status bar + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP]) + + + Row() { + Text('ROW2') + .fontSize(40) + } + .backgroundColor(Color.Orange) + .padding(20) + + + Row() { + Text('ROW3') + .fontSize(40) + } + .backgroundColor(Color.Orange) + .padding(20) + + + Row() { + Text('ROW4') + .fontSize(40) + } + .backgroundColor(Color.Orange) + .padding(20) + + + Row() { + Text('ROW5') + .fontSize(40) + } + .backgroundColor(Color.Orange) + .padding(20) + + + Row() { + Text('Bottom Row') + .fontSize(40) + .textAlign(TextAlign.Center) + .width('100%') + } + .backgroundColor(Color.Orange) + // Set the bottom drawing to extend to the navigation bar + .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) + } + .width('100%') + .height('100%') + .alignItems(HorizontalAlign.Center) + .backgroundColor('#008000') + .justifyContent(FlexAlign.SpaceBetween) + } +} +// [End implement_immersive_pages] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementLazyLoadingOfTwoDimensionalArrays.ets b/ArkUI/entry/src/main/ets/pages/ImplementLazyLoadingOfTwoDimensionalArrays.ets new file mode 100644 index 0000000000000000000000000000000000000000..b9c645535a04b8be54ea7e682647748a62e277cd --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementLazyLoadingOfTwoDimensionalArrays.ets @@ -0,0 +1,192 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现二维数组的懒加载? +*/ + +// [Start implement_lazy_loading_of_two_dimensional_arrays] +import { HashMap } from '@kit.ArkTS'; + +class BasicDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + private originDataArray: Array | Array = []; + + public totalCount(): number { + return 0; + } + + public getData(index: number): TimeTable | string { + return this.originDataArray[index]; + } + + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + console.info('add listener'); + this.listeners.push(listener); + } + } + + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + console.info('remove listener'); + this.listeners.splice(pos, 1); + } + } + + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } +} + +class MyDataSource extends BasicDataSource { + private dataArray: TimeTable[] | Array = []; + + constructor(data: Array | Array) { + super(); + this.dataArray = data; + } + + public totalCount(): number { + return this.dataArray.length; + } + + public getData(index: number): TimeTable | string { + return this.dataArray[index]; + } + + public addDataTimeTable(index: number, data: TimeTable): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + public addDataString(index: number, data: string): void { + this.dataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + public pushDataTimeTable(data: TimeTable): void { + (this.dataArray as Array).push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } + + public pushDataString(data: string): void { + (this.dataArray as Array).push(data); + this.notifyDataAdd(this.dataArray.length - 1); + } +} + +interface TimeTable { + title: string; + projects: string[]; +} + +@Component +export struct TwoNestingArrayLazy { + @State timeTable: TimeTable[] = [ + { + title: 'Monday', + projects: ['language', 'mathematics', 'English'] + }, + { + title: 'Tuesday', + projects: ['physics', 'chemistry', 'biology'] + }, + { + title: 'Wednesday', + projects: ['history', 'geography', 'politics'] + }, + { + title: 'Thursday', + projects: ['the fine arts', 'music', 'sport'] + } + ]; + private data1: MyDataSource = new MyDataSource(this.timeTable); + private hashMap: HashMap = new HashMap(); + + aboutToAppear(): void { + for (let index = 0; index < this.timeTable.length; index++) { + this.hashMap.set(this.timeTable[index].title, new MyDataSource(this.timeTable[index].projects)); + } + } + + @Builder + itemHead(text: string) { + Text(text) + .fontSize(20) + .backgroundColor(0xAABBCC) + .width('100%') + .padding(10) + } + + @Builder + itemFoot(num: number) { + Text('common' + num + 'period') + .fontSize(16) + .backgroundColor(0xAABBCC) + .width("100%") + .padding(5) + } + + build() { + List({ space: 3 }) { + LazyForEach(this.data1, (item: TimeTable) => { + ListItemGroup({ header: this.itemHead(item.title), footer: this.itemFoot(item.projects.length) }) { + LazyForEach(this.hashMap.get(item.title), (project: string) => { + ListItem() { + Text(project) + .width('100%') + .height(100) + .fontSize(20) + .textAlign(TextAlign.Center) + .backgroundColor(0xFFFFFF) + } + }, (item: string) => item) + } + .divider({ strokeWidth: 1, color: Color.Blue }) // The boundary line between each row + }, (item: string) => item) + } + .width('100%') + .height('100%') + } +} +// [End implement_lazy_loading_of_two_dimensional_arrays] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementPageSwitchingAnimation_One.ets b/ArkUI/entry/src/main/ets/pages/ImplementPageSwitchingAnimation_One.ets new file mode 100644 index 0000000000000000000000000000000000000000..6d8b62635d13eff4c00275f4bcf730a6daff39a0 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementPageSwitchingAnimation_One.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现上下切换的页面间跳转动画 +*/ + +// [Start implement_page_switching_animation_one] +// Index.ets +@Entry +@Component +struct PageTransition1 { + build() { + Stack({ alignContent: Alignment.Bottom }) { + Navigator({ target: 'pages/Page1'}) { + Image($r('app.media.ic_banner01')).width('100%').height(200) // The image is stored in the media folder + } + }.height('100%').width('100%') + } + + pageTransition() { + PageTransitionEnter({ duration: 500, curve: Curve.Linear }).slide(SlideEffect.Bottom) + PageTransitionExit({ duration: 500, curve: Curve.Ease }).slide(SlideEffect.Bottom) + } +} +// [End implement_page_switching_animation_one] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementPageSwitchingAnimation_Two.ets b/ArkUI/entry/src/main/ets/pages/ImplementPageSwitchingAnimation_Two.ets new file mode 100644 index 0000000000000000000000000000000000000000..d051b0a40c7ff44cdd5ed638e4cbfdf5f746de39 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementPageSwitchingAnimation_Two.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现上下切换的页面间跳转动画 +*/ + +// [Start implement_page_switching_animation_two] +// Page1.ets +@Entry +@Component +struct PageTransition2 { + build() { + Stack({ alignContent: Alignment.Bottom }) { + Navigator({ target: 'pages/Index'}) { + Image($r('app.media.ic_banner02')).width('100%').height(200) // The image is stored in the media folder + } + }.height('100%').width('100%') + } + + pageTransition() { + PageTransitionEnter({ duration: 500, curve: Curve.Linear }).slide(SlideEffect.Bottom) + PageTransitionExit({ duration: 500, curve: Curve.Ease }).slide(SlideEffect.Bottom) + } +} +// [End implement_page_switching_animation_two] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementPullDownAndUpwardSliding.ets b/ArkUI/entry/src/main/ets/pages/ImplementPullDownAndUpwardSliding.ets new file mode 100644 index 0000000000000000000000000000000000000000..6dde129892248c043cb4c43bfb9a624813ccc84f --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementPullDownAndUpwardSliding.ets @@ -0,0 +1,132 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现下拉刷新和上滑加载的效果 +*/ + +// [Start implement_pull_down_and_upward_sliding] +@Entry +@Component +struct PageToRefresh { + private currentOffsetY: number = 0; + @State refreshStatus: boolean = false; + @State refreshText: string = 'Refreshing'; + @State pullUpText: string = 'loading'; + private timer: number = 0; + @State isRefreshing: boolean = false; + @State isCanLoadMore: boolean = false; + @State ArrData: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; + @State newArr: string [] = ['10', '11'] + + putDownPullUpRefresh(event?: TouchEvent): void { + if (event === undefined) { + return; + } + switch (event.type) { + case TouchType.Down: + this.currentOffsetY = event.touches[0].y; + break; + case TouchType.Move: + let isDownPull = event.touches[0].y - this.currentOffsetY > 50; + if (isDownPull && this.isCanLoadMore === false) { + this.refreshStatus = true; + } + + if (this.ArrData.length <= 11) { + this.isCanLoadMore = true; + } + break; + case TouchType.Cancel: + break; + case TouchType.Up: + if (this.refreshStatus) { + this.timer = setTimeout(() => { + this.refreshStatus = false; + this.ArrData = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; + }, 1500) + } + + if (this.isCanLoadMore) { + this.timer = setTimeout(() => { + this.isCanLoadMore = false; + this.newArr.forEach((item) => { + this.ArrData.push(item) + }) + }, 1000) + } + + break; + default: + break; + } + } + + @Builder + putDown() { + Row() { + Image($r('app.media.refreshing')) + .width(40) + .height(20) + Text(this.refreshText).fontSize(16) + } + .justifyContent(FlexAlign.Center) + .width('94%') + .height('10%') + } + + @Builder + PullUp() { + Row() { + Image($r('app.media.refreshing')) + .width(40) + .height(40) + Text(this.pullUpText).fontSize(16) + } + .justifyContent(FlexAlign.Center) + .width('94%') + .height('5%') + } + + build() { + Column() { + Scroll() { + Column() { + Text('goods') + if (this.refreshStatus) { + this.putDown() + } + ForEach(this.ArrData, (item: string) => { + ListItem() { + Text(item) + .height(100) + } + }, (item: string) => JSON.stringify(item)) + if (this.isCanLoadMore) { + this.PullUp() + } + if (!this.isCanLoadMore) { + Text('No more data available at the moment') + } + } + } + .width('100%') + .onTouch((event?: TouchEvent) => { + this.putDownPullUpRefresh(event); + }) + } + } +} +// [End implement_pull_down_and_upward_sliding] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementQRCodeEffectWithImages.ets b/ArkUI/entry/src/main/ets/pages/ImplementQRCodeEffectWithImages.ets new file mode 100644 index 0000000000000000000000000000000000000000..67700ed0b65930b2b0ef2bd0c81ea76bea980e1e --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementQRCodeEffectWithImages.ets @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现带图片的二维码效果? +*/ + +// [Start implement_qr_code_effect_with_images] +@Entry +@Component +struct QRCodeWithImage { + private value: string = 'hello world'; + + + build() { + Stack() { + QRCode(this.value) + .width(200) + .height(200) + Image($r('app.media.app_icon')) + .height(50) + .width(50) + } + .height('100%') + .width('100%') + } +} +// [End implement_qr_code_effect_with_images] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementSlotFunction.ets b/ArkUI/entry/src/main/ets/pages/ImplementSlotFunction.ets new file mode 100644 index 0000000000000000000000000000000000000000..2aef3c7bf9995d564160924dc5a1b6d6def58b8e --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementSlotFunction.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现类似插槽的功能 +*/ + +// [Start implement_slot_function] +@Component +struct Child { + @Builder FunABuilder0() {} + @BuilderParam aBuilder0: () => void = this.FunABuilder0; + + + build() { + Column() { + this.aBuilder0() + } + } +} + + +@Entry +@Component +struct Parent { + @Builder componentBuilder() { + Text(`Parent builder `) + } + + + build() { + Column() { + Child({ aBuilder0: this.componentBuilder }) + } + } +} +// [End implement_slot_function] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementTabBarAlignmentToTheLeft.ets b/ArkUI/entry/src/main/ets/pages/ImplementTabBarAlignmentToTheLeft.ets new file mode 100644 index 0000000000000000000000000000000000000000..67750c79546d71ff3a75ab77885a576e777a5797 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementTabBarAlignmentToTheLeft.ets @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现Tabs组件的TabBar居左对齐 +*/ + +// [Start implement_tabBar_alignment_to_the_left] +// xxx.ets +@Entry +@Component +struct TabsExample { + @State tabArray: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + @State focusIndex: number = 0; + private controller: TabsController = new TabsController(); + + build() { + Column() { + // Use custom tab components + Scroll() { + Row() { + ForEach(this.tabArray, (item: number, index: number) => { + Row({ space: 20 }) { + Text('tab' + item) + .fontWeight(index === this.focusIndex ? FontWeight.Bold : FontWeight.Normal) + } + .padding({ left: 10, right: 10 }) + .onClick(() => { + this.controller.changeIndex(index); + this.focusIndex = index; + }) + }) + } + } + .align(Alignment.Start) + .scrollable(ScrollDirection.Horizontal) + .scrollBar(BarState.Off) + .width('100%') + + //The tabs component hides the tab bar + Tabs({ barPosition: BarPosition.Start, controller: this.controller }) { + ForEach(this.tabArray, (item: number, index: number) => { + TabContent() { + Text('I am the page ' + item + " the content") + .fontSize(30) + } + }) + }.barHeight(0) + } + .height('100%') + .width('100%') + } +} +// [End implement_tabBar_alignment_to_the_left] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementUnifiedPageGrayingFunction.ets b/ArkUI/entry/src/main/ets/pages/ImplementUnifiedPageGrayingFunction.ets new file mode 100644 index 0000000000000000000000000000000000000000..5ea8370b2d3de25c92a59e7186335af8d7edadb1 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementUnifiedPageGrayingFunction.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现页面统一置灰功能 +*/ + +// [Start implement_unified_page_graying_function] +@Entry +@Component +struct Index { + @State grayscaleValue: number = 0; + + build() { + Column({ space: 20 }) { + Flex() + Image($r("app.media.app_icon")) + .height(100) + Row({ space: 20 }) { + Button("Placing ashes") + .onClick(() => { + this.grayscaleValue = 1; // Page graying + }) + Button("restore") + .onClick(() => { + this.grayscaleValue = 0; // Page color restoration + }) + } + } + .width("100%") + .height("100%") + .backgroundColor('#fcd473') + .padding(10) + .grayscale(this.grayscaleValue) + } +} +// [End implement_unified_page_graying_function] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementingPageLoading.ets b/ArkUI/entry/src/main/ets/pages/ImplementingPageLoading.ets new file mode 100644 index 0000000000000000000000000000000000000000..4be3734c304ca71bae4e4ea9b1602f121339ce8d --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementingPageLoading.ets @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现页面加载的loading效果 +*/ + +// [Start implementing_page_loading] +@Entry +@Component +struct PageLoading { + @State isLoading: Boolean = true; + + aboutToAppear(): void { + // Simulate network request operation, request data from the network 3 seconds later, notify the component, and change the list data + setTimeout(() => { + this.isLoading = false; + }, 3000); + } + + build() { + Stack() { + if (this.isLoading) { + Column() { + LoadingProgress() + .color(Color.White) + .width(80).height(80) + Text('Effortlessly loading..') + .fontSize(16) + .fontColor(Color.White) + } + .width('100%') + .height('100%') + .backgroundColor('#40000000') + .justifyContent(FlexAlign.Center) + } else { + Column(){ + Text('主页') + } + } + } + .width('100%') + .height('100%') + .backgroundColor(Color.White) + } +} +// [End implementing_page_loading] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ImplementingStringVariableConcatenation.ets b/ArkUI/entry/src/main/ets/pages/ImplementingStringVariableConcatenation.ets new file mode 100644 index 0000000000000000000000000000000000000000..3adbf436669a51493649e83b4aa5a19bf7436eab --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ImplementingStringVariableConcatenation.ets @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:ArkUI组件的字符串中如何实现字符串变量拼接 +*/ + +@Component +struct implement { + build() { + // [Start implementing_string_variable_concatenation_one] + Text($r('app.string.EntryAbility_desc', 'Hello')) + // [End implementing_string_variable_concatenation_one] + } +} + +// [Start implementing_string_variable_concatenation_Four] +@Entry +@Component +struct Page1 { + @State num1: number = 100; + + + build() { + Row() { + Column() { + Text($r('app.string.module_desc', this.num1)) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } +} +// [End implementing_string_variable_concatenation_Four] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/JumpPagePopUpWindowExists.ets b/ArkUI/entry/src/main/ets/pages/JumpPagePopUpWindowExists.ets new file mode 100644 index 0000000000000000000000000000000000000000..cec4c03e6ae67e0623322222c32e5824c110c2a8 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/JumpPagePopUpWindowExists.ets @@ -0,0 +1,112 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现不关闭弹窗的情况下,跳转页面,并且返回时弹窗存在? +*/ + +// [Start jump_page_pop_up_window_exists] +@Component +struct DialogCpt { + @Consume('pageStack') pageStack: NavPathStack; + + + build() { + NavDestination() { + Column(){ + Column() { + Button('Next page').onClick(() => { + this.pageStack.pushPathByName('NextPage', ''); + }) + Blank() + Row() { + Button('Cancel') + .onClick(() => { + this.pageStack.pop(); + }) + Button('Confirm') + .onClick(() => { + this.pageStack.pop(); + }) + } + .width('100%') + .justifyContent(FlexAlign.SpaceEvenly) + } + .padding(16) + + + .height(300) + .width(300) + .backgroundColor(Color.White) + .borderRadius(16) + } + .justifyContent(FlexAlign.Center) + .height('100%') + .width('100%') + } + .mode(NavDestinationMode.DIALOG) + .hideTitleBar(true) + .backgroundColor('#40000000') + } +} + + +@Component +struct NextPage { + @Consume('pageStack') pageStack: NavPathStack; + + + build() { + NavDestination() { + Column() { + Button('Back') + .onClick(() => { + this.pageStack.pop(); + }) + } + } + } +} + + +@Entry +struct Index { + @Provide('pageStack') pageStack: NavPathStack = new NavPathStack() + + + @Builder + PageMap(name: string) { + if (name === 'DialogCpt') { + DialogCpt() + } else if (name === 'NextPage') { + NextPage() + } + } + + + build() { + Navigation(this.pageStack) { + Column() { + Button('Open dialog') + .onClick(() => { + this.pageStack.pushPathByName('DialogCpt', ''); + }) + } + } + .navDestination(this.PageMap) + .backgroundColor('#F1F3F5') + } +} +// [End jump_page_pop_up_window_exists] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/JumpPageTransferParameters.ets b/ArkUI/entry/src/main/ets/pages/JumpPageTransferParameters.ets new file mode 100644 index 0000000000000000000000000000000000000000..fbca1b0dcbbccf1212e884cc0cfdf1a28183a2a1 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/JumpPageTransferParameters.ets @@ -0,0 +1,113 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在Navigation跳转页面时返回传参 +*/ + +// [Start jump_page_transfer_parameters] +interface paramType { + param: string +} + +let paramA: paramType = { + param: 'test1' +} + +@Entry +@Component +struct Index { + @Provide('pathInfos') pathInfos: NavPathStack = new NavPathStack(); + + @Builder + myRouter(name: string) { + if (name === 'MyFirstNavDestination') { + MyFirstNavDestination() + } else if (name === 'MySecondNavDestination') { + MySecondNavDestination() + } + } + + build() { + Navigation(this.pathInfos) { + Row() { + Column() { + Text('hello world') + } + .height('100%') + } + .onClick(() => { + this.pathInfos.pushPathByName('MyFirstNavDestination', paramA); + }) + } + .navDestination(this.myRouter) + } +} + +@Component +export struct MyFirstNavDestination { + @Consume('pathInfos') pathInfos: NavPathStack; + + getParamsPrint() { + console.info('xuerui', 'param is ' + JSON.stringify(this.pathInfos.getParamByName('MyFirstNavDestination'))); + } + + build() { + NavDestination() { + Row() { + Column() { + Text('MyFirstNavDestination') + } + .width('100%') + } + .height('100%') + .onClick(() => { + this.pathInfos.pushPathByName('MySecondNavDestination', null); + }) + }.onShown(() => { + this.getParamsPrint(); + }) + } +} + +@Component +export struct MySecondNavDestination { + @Consume('pathInfos') pathInfos: NavPathStack; + private routerParams: paramType = { param: 'test 2' }; + + build() { + NavDestination() { + Row() { + Text('MySecondNavDestination') + } + .height('100%') + }.onBackPressed(() => { + // Pop B page + this.pathInfos.pop(); + + //Get the name of the current stack top page (page A) + let allPathName: Array = this.pathInfos.getAllPathName(); + let pathNameA: string = allPathName[allPathName.length - 1]; + + // Pop A page + this.pathInfos.pop(); + + // PUSH A page again + this.pathInfos.pushPath(new NavPathInfo(pathNameA, this.routerParams)) + return true; + }) + } +} +// [End jump_page_transfer_parameters] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/LimitInputCharacters.ets b/ArkUI/entry/src/main/ets/pages/LimitInputCharacters.ets new file mode 100644 index 0000000000000000000000000000000000000000..36b61b9ff3e56419112ecf9ecad53d6259c34d23 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/LimitInputCharacters.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:TextInput如何限制输入字符为某些字符 +*/ + +// [Start limit_input_characters] +@Entry +@Component +struct Index { + controller: TextInputController = new TextInputController(); + + build() { + Column() { + TextInput({ placeholder: 'Please input a password', text: '123456', controller: this.controller }) + .type(InputType.Password) + .placeholderColor(Color.Gray) + .inputFilter('[0-9]', (val) => { //Only allow the input of characters 0-9, other characters are invalid + console.error('TextInputExample : ' + val); + return 0; + }) + } + } +} +// [End limit_input_characters] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ListComponentDisplaysDifferentData.ets b/ArkUI/entry/src/main/ets/pages/ListComponentDisplaysDifferentData.ets new file mode 100644 index 0000000000000000000000000000000000000000..dee35a9c1b6ac7d978226a3fc339ad4584543c3f --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ListComponentDisplaysDifferentData.ets @@ -0,0 +1,93 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在List组件中分组展示不同种类的数据 +*/ + +// [Start list_component_displays_different_data] +// xxx.ets +@Entry +@Component +struct ListItemGroupExample { + private timetable: TimeTable[] = [ + { + title: 'Monday', + projects: ['language', 'mathematics', 'English'] + }, + { + title: 'Tuesday', + projects: ['physics', 'chemistry', 'biology'] + }, + { + title: 'Wednesday', + projects: ['history', 'geography', 'politics'] + }, + { + title: 'Thursday', + projects: ['the fine arts', 'music', 'sport'] + } + ] + + @Builder + itemHead(text: string) { + Text(text) + .fontSize(20) + .backgroundColor(0xAABBCC) + .width('100%') + .padding(10) + } + + @Builder + itemFoot(num: number) { + Text('common' + num + 'period') + .fontSize(16) + .backgroundColor(0xAABBCC) + .width('100%') + .padding(5) + } + + build() { + Column() { + List({ space: 20 }) { + ForEach(this.timetable, (item: TimeTable) => { + ListItemGroup({ header: this.itemHead(item.title), footer: this.itemFoot(item.projects.length) }) { + ForEach(item.projects, (project: string) => { + ListItem() { + Text(project) + .width('100%') + .height(100) + .fontSize(20) + .textAlign(TextAlign.Center) + .backgroundColor(0xFFFFFF) + } + }, (item: string) => item) + } + .divider({ strokeWidth: 1, color: Color.Blue }) // The boundary line between each row + }) + } + .width('90%') + .height('100%') + .sticky(StickyStyle.Header | StickyStyle.Footer) + .scrollBar(BarState.Off) + }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 }) + } +} + +interface TimeTable { + title: string; + projects: string[]; +} +// [End list_component_displays_different_data] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ListDoesNotSetHeight.ets b/ArkUI/entry/src/main/ets/pages/ListDoesNotSetHeight.ets new file mode 100644 index 0000000000000000000000000000000000000000..ccabe2f914ceaa89964199296c111bf33a2552f0 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ListDoesNotSetHeight.ets @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何解决List组件在不设置高度的情况下滑动不到底的问题 +*/ + +// [Start list_does_not_set_height] +// xxx.ets +@Entry +@Component +struct ListExample { + @State arr: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15']; + scroller: Scroller = new Scroller(); + + build() { + Column() { + RichText('') + .width('90%') + .height(300) + .backgroundColor(0XBDDB69) + List({ space: 22, initialIndex: 0, scroller: this.scroller }) { + ForEach(this.arr, (item: string) => { + ListItem() { + Text(item) + .width('100%') + .height(100) + .fontSize(16) + .textAlign(TextAlign.Center) + .borderRadius(10) + .backgroundColor(0xFFFFFF) + } + }, (item: string) => item) + } + .layoutWeight(1) // Adaptive occupancy of remaining space + .listDirection(Axis.Vertical) // Arrangement direction + .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // The boundary line between each row + .edgeEffect(EdgeEffect.Spring) // Sliding to the edge has no effect + .scrollBar(BarState.Off) // Set scrollbar + .margin({ top: 20 }) + .width('90%') + } + .width('100%') + .height('100%') + .backgroundColor(0xDCDCDC) + } +} +// [End list_does_not_set_height] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ListDropdownLoadRollbackCurrentLocation.ets b/ArkUI/entry/src/main/ets/pages/ListDropdownLoadRollbackCurrentLocation.ets new file mode 100644 index 0000000000000000000000000000000000000000..9a0132bcaeae8116a6f18255778e1e83d61ee2d7 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ListDropdownLoadRollbackCurrentLocation.ets @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:List的下拉加载如何回滚到当前展示位置 +*/ + +// [Start list_dropdown_load_rollback_current_location] +@Entry +@Component +struct RefreshDemo { + @State isRefreshing: boolean = false; + @State arr: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']; + private listScroller: Scroller = new Scroller(); + + build() { + Column() { + Refresh({ refreshing: $$this.isRefreshing }) { + List({ scroller: this.listScroller, space: 10 }) { + ForEach(this.arr, (item: string) => { + ListItem() { + Text(item) + .width('100%') + .height(100) + .textAlign(TextAlign.Center) + .backgroundColor(Color.Grey) + } + }, (item: string) => item) + } + .onScrollIndex((first: number) => { + console.info(first.toString()); + }) + .width('100%') + .height('100%') + } + .onRefreshing(() => { + setTimeout(() => { + this.isRefreshing = false; + }, 2000) + this.arr.unshift('11'); + this.arr.unshift('12'); + this.listScroller.scrollToIndex(2); + }) + } + } +} +// [End list_dropdown_load_rollback_current_location] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ListExchangeSubcomponentPositions.ets b/ArkUI/entry/src/main/ets/pages/ListExchangeSubcomponentPositions.ets new file mode 100644 index 0000000000000000000000000000000000000000..825f2c6df413cdd8a9bfa3e8c504cddc6a637490 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ListExchangeSubcomponentPositions.ets @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现List内拖拽交换子组件位置 +*/ + +// [Start list_exchange_subcomponent_positions] +@Entry +@Component +struct Index { + @State listArr: string[] = []; + + @Builder + pixelMapBuilder(text: string) { + Column() { + Text(text) + .fontSize(16) + .backgroundColor(0xDCDCDC) + .width(80) + .height(80) + .textAlign(TextAlign.Center) + } + } + + aboutToAppear() { + for (let i = 0; i < 16; i++) { + this.listArr.push(i + ''); + } + } + + // Swap the position of listItem in the listArr array + changeListItemIndex(index1: number, index2: number) { + let tempItem = this.listArr[index1]; + this.listArr[index1] = this.listArr[index2]; + this.listArr[index2] = tempItem; + } + + build() { + Column() { + List() { + ForEach(this.listArr, (item: string) => { + ListItem() { + Text(item) + } + .width(80) + .height(80) + .backgroundColor(Color.White) + .borderRadius(4) + .margin({ top: 10 }) + }, (item: string) => item) + } + .width('100%') + .height(500) + .lanes({ minLength: 80, maxLength: 80 }) + .alignListItem(ListItemAlign.Center) + .onItemDragStart((event: ItemDragInfo, index: number) => { + return this.pixelMapBuilder(this.listArr[index]); + }) + .onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => { + if (!isSuccess || insertIndex >= this.listArr.length) { + return; + } + this.changeListItemIndex(itemIndex, insertIndex); + }) + } + .width('100%') + .height('100%') + .backgroundColor(0xDCDCDC) + } +} +// [End list_exchange_subcomponent_positions] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ListImplementsMultiColumnEffect.ets b/ArkUI/entry/src/main/ets/pages/ListImplementsMultiColumnEffect.ets new file mode 100644 index 0000000000000000000000000000000000000000..577aa1f3d7d55e8296a568104016e0c6317b2ccd --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ListImplementsMultiColumnEffect.ets @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:List组件如何实现多列效果 +*/ + +// [Start list_implements_multi_column_effect] +// xxx.ets +@Entry +@Component +struct ListExample { + @State arr: string[] = ['1', '2', '3', '4', '5', '6', '7', '8', '9']; + + build() { + Column() { + List() { + ForEach(this.arr, (item: string) => { + ListItem() { + Row() { + Text(item) + .fontColor(Color.Red) + .fontSize(40) + } + } + .width('100%') + .border({ + width: 1, + color: Color.Black, + radius: 5 + }) + }) + } + .lanes(3) + .alignListItem(ListItemAlign.Center) + } + .padding({ top: 30 }) + } +} +// [End list_implements_multi_column_effect] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ListItemPlaceholderAnimation.ets b/ArkUI/entry/src/main/ets/pages/ListItemPlaceholderAnimation.ets new file mode 100644 index 0000000000000000000000000000000000000000..212252590e44b1255ae353b67f29cd008708215e --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ListItemPlaceholderAnimation.ets @@ -0,0 +1,93 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现拖拽时列表项占位动画的效果 +*/ + +// [Start list_item_placeholder_animation] +@Entry +@Component +struct GridExample { + @State numbers: String[] = []; + scroller: Scroller = new Scroller(); + @State text: string = 'drag'; + + @Builder + pixelMapBuilder() { + Column() { + Text(this.text) + .fontSize(16) + .backgroundColor(0xF9CF93) + .width(80) + .height(80) + .textAlign(TextAlign.Center) + } + } + + aboutToAppear() { + for (let i = 1; i <= 15; i++) { + this.numbers.push(i + ''); + } + } + + changeIndex(index1: number, index2: number) { + // Swap array positions + let temp = this.numbers[index1]; + this.numbers[index1] = this.numbers[index2]; + this.numbers[index2] = temp; + } + + build() { + Column({ space: 5 }) { + Grid(this.scroller) { + ForEach(this.numbers, (day: string) => { + GridItem() { + Text(day) + .fontSize(16) + .backgroundColor(0xF9CF93) + .width(80) + .height(80) + .textAlign(TextAlign.Center) + .onTouch((event: TouchEvent) => { + if (event.type === TouchType.Up) { + this.text = day; + } + }) + } + }) + } + .columnsTemplate('1fr 1fr 1fr') + .columnsGap(10) + .rowsGap(10) + .onScrollIndex((first: number) => { + console.info(first.toString()); + }) + .width('90%') + .backgroundColor(0xFAEEE0) + .height(300) + .editMode(true) // Set whether the Grid enters editing mode. When entering editing mode, you can drag and drop the GridItem inside the Grid component + .onItemDragStart((event: ItemDragInfo, itemIndex: number) => { // When dragging the component bound to this event for the first time, a callback is triggered. + return this.pixelMapBuilder(); //Set the image displayed during the drag and drop process. + }) + // The component bound to this event can be used as a drag and drop release target. When the drag behavior stops within the scope of this component, a callback is triggered. + .onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => { + // Drag the starting position of itemIndex, drag the insertion position of insertIndex + this.changeIndex(itemIndex, insertIndex) + }) + }.width('100%').margin({ top: 5 }) + } +} +// [End list_item_placeholder_animation] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ListSettingGradientEffect.ets b/ArkUI/entry/src/main/ets/pages/ListSettingGradientEffect.ets new file mode 100644 index 0000000000000000000000000000000000000000..89b753c5d6f0c30cbe28a066981f3696a0c2a75b --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ListSettingGradientEffect.ets @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:List组件如何设置两端的渐变效果 +*/ + +// [Start list_setting_gradient_effect] +@Entry +@Component +struct ListExample { + @State arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9] + private scroller: Scroller = new Scroller() + + build() { + Stack() { + List({ space: 10 }) { + ForEach(this.arr, (item: string) => { + ListItem() { + Text("Hello World") + .width(100) + .height(64) + .fontColor(Color.White) + .backgroundColor(Color.Black) + .textAlign(TextAlign.Center) + } + }, (item: string) => item) + } + .listDirection(Axis.Horizontal) + .scrollBar(BarState.Off) + .padding({ top: 20, bottom: 20 }) + .width("80%") + .height("100%") + + Stack() { + + } + .linearGradient({ + angle: 90, + colors: [[0x000000, 0.0], ['rgba(0,0,0,0)', 0.1], ['rgba(0,0,0,0)', 0.9], [0x000000, 1.0]] + }) + .width("80%") + .height("100%") + .hitTestBehavior(HitTestMode.None) + }.height(100).width('100%').backgroundColor(Color.Black) + } +} +// [End list_setting_gradient_effect] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ListSettingMultipleColumns.ets b/ArkUI/entry/src/main/ets/pages/ListSettingMultipleColumns.ets new file mode 100644 index 0000000000000000000000000000000000000000..b12954c8f5345639a0c029c6d9e54cef09e889f7 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ListSettingMultipleColumns.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:List组件如何设置多列 +*/ + +// [Start list_setting_multiple_columns] +@Entry +@Component +struct ListLanesExample { + @State arr: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19']; + @State alignListItem: ListItemAlign = ListItemAlign.Start; + + build() { + Column() { + List({ space: 20, initialIndex: 0 }) { + ForEach(this.arr, (item: string) => { + ListItem() { + Text('' + item) + .width('100%') + .height(100) + .fontSize(16) + .textAlign(TextAlign.Center) + .borderRadius(10) + .backgroundColor(0xFFFFFF) + } + .border({ width: 2, color: Color.Green }) + }, (item: string) => item) + } + .height(300) + .width('90%') + .border({ width: 3, color: Color.Red }) + .lanes({ minLength: 40, maxLength: 40 }) + .alignListItem(this.alignListItem) + + Button('Click to change alignListItem:' + this.alignListItem).onClick(() => { + if (this.alignListItem == ListItemAlign.Start) { + this.alignListItem = ListItemAlign.Center; + } else if (this.alignListItem == ListItemAlign.Center) { + this.alignListItem = ListItemAlign.End; + } else { + this.alignListItem = ListItemAlign.Start; + } + }) + }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 }) + } +} + + +// [End list_setting_multiple_columns] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ListWiperGridPullDownPullUp.ets b/ArkUI/entry/src/main/ets/pages/ListWiperGridPullDownPullUp.ets new file mode 100644 index 0000000000000000000000000000000000000000..99ad428ba03cfee6b191ccf67d1ed2f5bdafa7ac --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ListWiperGridPullDownPullUp.ets @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现List/Swiper/Grid嵌套滚动的下拉刷新和上拉加载更多 +*/ +@Component +struct PullDownPullUp { + @State isRefreshing: string = '' + + @Builder searchBarBuilder() {} + @Builder bannerBuilder() {} + @Builder quickBuilder() {} + @Builder flashBuilder() {} + @Builder productsBuilder() {} + @Builder footerLoadingBuilder() {} + + // [Start list_wiper_grid_pull_down_pull_up] + build() { + Column() { + // Search box at the top + this.searchBarBuilder() + // Pull down refresh component + Refresh({ refreshing: $$this.isRefreshing }) { + // List component as long list layout + List({ space: 10 }) { + // ListItem Customize the Swiper carousel module + ListItem() { + this.bannerBuilder() + } + // ListItem Custom Grid Quick Access Module + ListItem() { + this.quickBuilder() + } + // ListItem Custom Column Flash Sale Module + ListItem() { + this.flashBuilder() + } + // ListItemGroup Product Classification List + this.productsBuilder() + // 最后ListItem Customize bottom loading for more + ListItem() { + this.footerLoadingBuilder() + }.height(50).width('100%').backgroundColor(0xeeeeee) + } + .sticky(StickyStyle.Header) + .height('100%') + // List component hits bottom to simulate network requests + .onReachEnd(() => { + // Load more data logic + }) + } + // Pull down refresh simulation network request + .onRefreshing(() => { + // Data refresh logic + }) + .layoutWeight(1) + .width('100%') + } + } + // [End list_wiper_grid_pull_down_pull_up] +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/LoadUnicodeCharacters.ets b/ArkUI/entry/src/main/ets/pages/LoadUnicodeCharacters.ets new file mode 100644 index 0000000000000000000000000000000000000000..99e144f7b79c83b9f3f5378b6e960e9e1e80bad0 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/LoadUnicodeCharacters.ets @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Text 组件如何加载Unicode字符 +*/ + +// [Start load_unicode_characters] +@Entry +@Component +struct text { + build() { + Column() { + Text("\u{1F468}\u200D\u{1F469}\u200D\u{1F467}\u200D\u{1F466}") + .width(100) + .height(100) + .fontSize(50) + } + } +} +// [End load_unicode_characters] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/LoadingAndUsingCustomFonts.ets b/ArkUI/entry/src/main/ets/pages/LoadingAndUsingCustomFonts.ets new file mode 100644 index 0000000000000000000000000000000000000000..395439b82dcf44401d06212bdfe2fd6d4b5966b9 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/LoadingAndUsingCustomFonts.ets @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何加载和使用自定义字体 +*/ + +// [Start loading_and_using_custom_fonts] +// xxx.ets +import { Font } from '@kit.ArkUI'; + +@Entry +@Component +struct FontExample { + @State message: string = 'Hello World'; + + aboutToAppear() { + // Register in black font + let font: Font = this.getUIContext().getFont() + font.registerFont({ + familyName: 'Condensed_Black', // Registered font name + familySrc: '/font/Sans_Condensed_Black.ttf' // The font folder is at the same level as the pages directory + }) + + // Register in black oblique font + font.registerFont({ + familyName: 'Condensed_Black_Italic', // Registered font name + familySrc: '/font/Sans_Condensed_Black_Italic.ttf' // The font folder is at the same level as the pages directory + }) + } + + build() { + Column() { + Text(this.message) + .align(Alignment.Center) + .fontSize(50) + .fontFamily('Condensed_Black') // Use black font + Text(this.message) + .align(Alignment.Center) + .fontSize(50) + .fontFamily('Condensed_Black_Italic') // Use black oblique font + Text(this.message) + .align(Alignment.Center) + .fontSize(50) + } + .width('100%') + .margin({ top: 30 }) + } +} +// [End loading_and_using_custom_fonts] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/MarqueeAvoidsBlankSpacesFromAppearing.ets b/ArkUI/entry/src/main/ets/pages/MarqueeAvoidsBlankSpacesFromAppearing.ets new file mode 100644 index 0000000000000000000000000000000000000000..f139f2d3f227ab19da9d9780b5e27a57ea8e146c --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/MarqueeAvoidsBlankSpacesFromAppearing.ets @@ -0,0 +1,126 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Marquee组件的文字滚动,第一次滚动出现大量空白,如何避免空白出现 +*/ + +// [Start marquee_avoids_blank_spaces_from_appearing] +@Entry +@Component +struct MarqueeScroll { + @State textList: string[] = [ + 'this is a test string1 this is a test string1', + 'this is a test string2 this is a test string2 this is a test string2', + 'this is a test string3 this is a test string3 this is a test string3 this is a test string3' + ]; + @State count: number = 1; + + + build() { + Row() { + Column() { + myMarqueeCard({ + textList: $textList, + updateList: () => { + this.textList = [ + `This is test data${this.count++}This is test data${this.count++}`, + `This is test data${this.count++}This is test data${this.count++}This is test data${this.count++}`, + `This is test data${this.count++}This is test data${this.count++}This is test data${this.count++}This is test data${this.count++}` + ]; + } + }) + } + .width('100%') + .margin(20) + } + .height('100%') + } +} + + +@Component +struct myMarqueeCard { + @Link @Watch('handleNewList') textList: string[]; + @State list: string[] = []; + scroller1: Scroller = new Scroller(); + scroller2: Scroller = new Scroller(); + scroller3: Scroller = new Scroller(); + updateList?: () => void; + + + handleNewList() { + console.info(JSON.stringify(this.textList)); + } + + + build() { + Column() { + this.SingleText({ text: this.textList[0], scroller: this.scroller1 }) + this.SingleText({ text: this.textList[1], scroller: this.scroller2 }) + this.SingleText({ text: this.textList[2], scroller: this.scroller3 }) + } + } + + + @Builder + SingleText($$: Tmp) { + Scroll($$.scroller) { + Row() { + Text($$.text) + .fontSize(30) + .onAppear(() => { + this.handleScroll($$.scroller); + }) + } + } + .width(300) + .scrollable(ScrollDirection.Horizontal) + .enableScrollInteraction(false) + .scrollBar(BarState.Off) + + + } + + + handleScroll(scroller: Scroller) { + setInterval(() => { + const curOffset: OffsetResult = scroller.currentOffset(); + scroller.scrollTo({ + xOffset: curOffset.xOffset + 50, yOffset: curOffset.yOffset, animation: { + duration: 1000, + curve: Curve.Linear + } + }); + if (scroller.isAtEnd()) { + if (this.scroller1.isAtEnd() && this.scroller2.isAtEnd() && this.scroller3.isAtEnd()) { + if (this.updateList) { + this.scroller1.scrollTo({ xOffset: 0, yOffset: 0, animation: { duration: 0 } }); + this.scroller2.scrollTo({ xOffset: 0, yOffset: 0, animation: { duration: 0 } }); + this.scroller3.scrollTo({ xOffset: 0, yOffset: 0, animation: { duration: 0 } }); + this.updateList(); + } + } + } + }, 500); + } +} + + +class Tmp { + text: string = ''; + scroller: Scroller = new Scroller(); +} +// [End marquee_avoids_blank_spaces_from_appearing] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/MergeTwoListsAndSupportLazyLoading.ets b/ArkUI/entry/src/main/ets/pages/MergeTwoListsAndSupportLazyLoading.ets new file mode 100644 index 0000000000000000000000000000000000000000..cb0e53a8727631040776f0e9086481d2cf7154b5 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/MergeTwoListsAndSupportLazyLoading.ets @@ -0,0 +1,152 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何合并两个列表并支持懒加载 +*/ + +// [Start merge_two_lists_and_support_lazy_loading_one] +import { MyDataSource } from './DataUtil'; + + +@Entry +@Component +struct DoubleLazyForEach { + private scrollerForScroll: Scroller = new Scroller(); + + + build() { + Flex() { + Scroll(this.scrollerForScroll) { + Column() { + Text('Scroll Area') + .width('100%') + .height('40%') + .backgroundColor(0X330000FF) + .fontSize(16) + .textAlign(TextAlign.Center) + ListA().height('80%') + ListB().height('80%') + } + } + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + .backgroundColor(0xDCDCDC) + .padding(20) + } +} + + +@Component +struct ListA { + private scrollerForListA: Scroller = new Scroller(); + private dataOne: MyDataSource = new MyDataSource(); + + + aboutToAppear() { + for (let i = 0; i <= 20; i++) { + this.dataOne.pushData(`Hello One ${i}`); + } + } + + + build() { + Column() { + List({ space: 20, scroller: this.scrollerForListA }) { + LazyForEach(this.dataOne, (item: number) => { + ListItem() { + Text('ListItem' + item) + .width('100%') + .height('100%') + .borderRadius(15) + .fontSize(16) + .textAlign(TextAlign.Center) + .backgroundColor(Color.White) + } + .width('100%') + .height(100) + }, (item: string) => item) + } + .width('100%') + .height('100%') + .edgeEffect(EdgeEffect.None) + .friction(0.6) + .nestedScroll({ + scrollForward: NestedScrollMode.SELF_FIRST, + scrollBackward: NestedScrollMode.PARENT_FIRST + }) + } + .height('100%') + .width('100%') + } +} + + +@Component +struct ListB { + private dataTwo: MyDataSource = new MyDataSource(); + private scrollerForListB: Scroller = new Scroller(); + + + aboutToAppear() { + for (let i = 0; i <= 20; i++) { + this.dataTwo.pushData(`Hello Two ${i}`); + } + } + + + build() { + Column() { + List({ space: 20, scroller: this.scrollerForListB }) { + LazyForEach(this.dataTwo, (item: number) => { + ListItem() { + MyText({ state_value: item.toString() }) + } + .width('100%') + .height(100) + }, (item: string) => item) + } + .width('100%') + .height('100%') + .edgeEffect(EdgeEffect.None) + .friction(0.6) + .nestedScroll({ + scrollForward: NestedScrollMode.PARENT_FIRST, + scrollBackward: NestedScrollMode.SELF_FIRST + }) + } + } +} + + +@Component +struct MyText { + @State private state_value: string = 'Hello'; + + + build() { + Text('ListItem' + this.state_value) + .width('100%') + .height('100%') + .borderRadius(15) + .fontSize(16) + .textAlign(TextAlign.Center) + .backgroundColor(Color.Pink) + } +} +// [End merge_two_lists_and_support_lazy_loading_one] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ModifyBackgroundColorOfPressedState.ets b/ArkUI/entry/src/main/ets/pages/ModifyBackgroundColorOfPressedState.ets new file mode 100644 index 0000000000000000000000000000000000000000..df01cf613eeddffc34cddc5c5e3dd2466b766078 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ModifyBackgroundColorOfPressedState.ets @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:TextInput按压态背景色如何修改 +*/ + +// [Start modify_background_color_of_pressed_state] +@Entry +@Component +struct Index { + @Styles + pressedStyles() { + .backgroundColor(Color.White) + } + + build() { + Row() { + Column() { + TextInput() + .backgroundColor(Color.White) + .stateStyles({ + pressed: this.pressedStyles, + }) + } + .width('100%') + } + .height('100%') + } +} +// [End modify_background_color_of_pressed_state] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ModifyTheCornerSizeAndArrowColorOfBindPopup.ets b/ArkUI/entry/src/main/ets/pages/ModifyTheCornerSizeAndArrowColorOfBindPopup.ets new file mode 100644 index 0000000000000000000000000000000000000000..72f97d7289113fc96961fabeabeb964f1a0710e9 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ModifyTheCornerSizeAndArrowColorOfBindPopup.ets @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何修改bindPopup绑定的弹窗圆角大小和箭头颜色 +*/ + +// [Start modify_the_corner_size_and_arrow_color_of_bindPopup] +@Entry +@Component +struct BindPopupDemo { + @State handlePopup: boolean = false; + @State customPopup: boolean = false; + + + // Popup constructor defines the content of the popup box + @Builder + popupBuilder() { + Row({ space: 2 }) { + Image($r('app.media.startIcon')) + .width(24) + .height(24) + .margin({ left: -5 }) + Text('Custom Popup') + .fontSize(10) + } + .width(100) + .height(50) + .padding(5) + } + + + build() { + RelativeContainer() { + Button('CustomPopupOptions') + .onClick(() => { + this.customPopup = !this.customPopup; + }) + .bindPopup(this.customPopup, { + builder: this.popupBuilder, + radius: 30, + popupColor: Color.Yellow, + enableArrow: true, + onStateChange: (e) => { + if (!e.isVisible) { + this.customPopup = false; + } + } + }) + } + } +} +// [End modify_the_corner_size_and_arrow_color_of_bindPopup] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/MonitorFrontAndBackOfApplication.ets b/ArkUI/entry/src/main/ets/pages/MonitorFrontAndBackOfApplication.ets new file mode 100644 index 0000000000000000000000000000000000000000..6a211145f0348d33b85b82cec4f2b3e41f4b9430 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/MonitorFrontAndBackOfApplication.ets @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Component如何监听应用前后台切换 +*/ + +// [Start monitor_front_and_back_of_application] +@Entry +@Component +struct ComponentListenFrontAndBack { + @State message: string = 'Hello World'; + @StorageLink('isOnForeground') isOnForeground: boolean = true; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Vid({ isOnForeground: this.isOnForeground }) + } + .width('100%') + } + .height('100%') + } +} + +@Component +struct Vid { + @Watch('change') @Link isOnForeground: boolean; + @State message: string = 'video'; + + build() { + Text('message') + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + this.message += this.isOnForeground; + console.log('' + this.isOnForeground); + }) + } + + change() { + if (this.isOnForeground) { + console.log('The component is on foreground.'); + } else { + console.log('The component is on background.'); + } + } +} +// [End monitor_front_and_back_of_application] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/NavigationBarSwitching.ets b/ArkUI/entry/src/main/ets/pages/NavigationBarSwitching.ets new file mode 100644 index 0000000000000000000000000000000000000000..f01170c8ce963b806bc7c9bd44e494a568f61764 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/NavigationBarSwitching.ets @@ -0,0 +1,146 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现Tabs页签导航栏切换时,下划线也随之滑动 +*/ + +// [Start navigation_bar_switching] +@Entry +@Component +struct TabsBarUnderlineSwitching { + private controller: TabsController = new TabsController(); + @State indicatorColor: Color = Color.Blue; + @State indicatorWidth: number = 40; + @State indicatorHeight: number = 5; + @State indicatorBorderRadius: number = 5; + @State indicatorSpace: number = 10; + @State subTabBorderRadius: number = 20; + @State selectedMode: SelectedMode = SelectedMode.INDICATOR; + + + build() { + Column() { + Tabs({ barPosition: BarPosition.End, controller: this.controller }) { + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Pink).borderRadius('12vp') + }.tabBar(SubTabBarStyle.of('pink') + .indicator({ + color: this.indicatorColor, // Underline color + height: this.indicatorHeight, // Underline height + width: this.indicatorWidth, // Underline width + borderRadius: this.indicatorBorderRadius, // Underline corner radius + marginTop: this.indicatorSpace // The spacing between underline and text + }) + .selectedMode(this.selectedMode) + .board({ borderRadius: this.subTabBorderRadius }) + .labelStyle({}) + ) + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Yellow).borderRadius('12vp') + }.tabBar(SubTabBarStyle.of('yellow') + .indicator({ + color: this.indicatorColor, // Underline color + height: this.indicatorHeight, // Underline height + width: this.indicatorWidth, // Underline width + borderRadius: this.indicatorBorderRadius, // Underline corner radius + marginTop: this.indicatorSpace // The spacing between underline and text + }) + .selectedMode(this.selectedMode) + .board({ borderRadius: this.subTabBorderRadius }) + .labelStyle({}) + ) + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Blue).borderRadius('12vp') + }.tabBar(SubTabBarStyle.of('blue') + .indicator({ + color: this.indicatorColor, // Underline color + height: this.indicatorHeight, // Underline height + width: this.indicatorWidth, // Underline width + borderRadius: this.indicatorBorderRadius, // Underline corner radius + marginTop: this.indicatorSpace // The spacing between underline and text + }) + .selectedMode(this.selectedMode) + .board({ borderRadius: this.subTabBorderRadius }) + .labelStyle({}) + ) + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Green).borderRadius('12vp') + }.tabBar(SubTabBarStyle.of('green') + .indicator({ + color: this.indicatorColor, // Underline color + height: this.indicatorHeight, // Underline height + width: this.indicatorWidth, // Underline width + borderRadius: this.indicatorBorderRadius, // Underline corner radius + marginTop: this.indicatorSpace // The spacing between underline and text + }) + .selectedMode(this.selectedMode) + .board({ borderRadius: this.subTabBorderRadius }) + .labelStyle({}) + ) + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Gray).borderRadius('12vp') + }.tabBar(SubTabBarStyle.of('gray') + .indicator({ + color: this.indicatorColor, // Underline color + height: this.indicatorHeight, // Underline height + width: this.indicatorWidth, // Underline width + borderRadius: this.indicatorBorderRadius, // Underline corner radius + marginTop: this.indicatorSpace // The spacing between underline and text + }) + .selectedMode(this.selectedMode) + .board({ borderRadius: this.subTabBorderRadius }) + .labelStyle({}) + ) + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Orange).borderRadius('12vp') + }.tabBar(SubTabBarStyle.of('orange') + .indicator({ + color: this.indicatorColor, // Underline color + height: this.indicatorHeight, // Underline height + width: this.indicatorWidth, // Underline width + borderRadius: this.indicatorBorderRadius, // Underline corner radius + marginTop: this.indicatorSpace // The spacing between underline and text + }) + .selectedMode(this.selectedMode) + .board({ borderRadius: this.subTabBorderRadius }) + .labelStyle({}) + ) + } + .vertical(false) + .scrollable(true) + .fadingEdge(false) + .barMode(BarMode.Scrollable) + .barHeight(140) + .animationDuration(400) + .onChange((index: number) => { + console.info(index.toString()) + }) + .backgroundColor(0xF5F5F5) + .height(320) + }.width('100%').height(250).padding({ top: '24vp', left: '24vp', right: '24vp' }) + } +} +// [End navigation_bar_switching] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/NotRespondToParentComponentOnTouch.ets b/ArkUI/entry/src/main/ets/pages/NotRespondToParentComponentOnTouch.ets new file mode 100644 index 0000000000000000000000000000000000000000..a63bcf311688117d6b459dd18ce0e14bded2a8c9 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/NotRespondToParentComponentOnTouch.ets @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:当父组件绑定了onTouch,其子组件Button绑定了onClick,如何做到点击Button只响应Button的onClick,而不用响应父组件的onTouch +*/ + +// [Start not_respond_to_parent_component_on_touch] +@Entry +@Component +struct Index { + + build() { + Row() { + Button('Click on me') + .width(100) + .width(100) + .backgroundColor('#f00') + .onClick(() => { + console.log('Button onClick'); + }) + .onTouch((event) => { + console.log('Button onTouch'); + event.stopPropagation(); + }) + } + .onTouch(() => { + console.log('Row onTouch'); + }) + } +} +// [End not_respond_to_parent_component_on_touch] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ObtainStateManagementFramework.ets b/ArkUI/entry/src/main/ets/pages/ObtainStateManagementFramework.ets new file mode 100644 index 0000000000000000000000000000000000000000..b45f3aad33f9d15143b6f47d1624258acc3e6441 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ObtainStateManagementFramework.ets @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取状态管理框架代理前的原始对象 +*/ + +// [Start obtain_state_management_framework] +import { UIUtils } from '@kit.ArkUI'; + + +@Observed +class Info { + name: string = 'Tom'; +} + + +@Entry +@Component +struct GetTargetDemo { + @State info: Info = new Info(); + + + build() { + Column() { + Text(`info.name: ${this.info.name}`) + Button('Change the properties of the proxy object') + .onClick(() => { + this.info.name = 'Alice'; // The Text component can refresh + }) + Button('更改原始对象的属性') + .onClick(() => { + let rawInfo: Info = UIUtils.getTarget(this.info); + rawInfo.name = 'Bob'; // The Text component cannot be refreshed + }) + } + } +} +// [End obtain_state_management_framework] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ObtainTheWidthAndHeightOfTheImage.ets b/ArkUI/entry/src/main/ets/pages/ObtainTheWidthAndHeightOfTheImage.ets new file mode 100644 index 0000000000000000000000000000000000000000..cf67e5b9e49d024fa0baaf29fdfb90c237dceadc --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ObtainTheWidthAndHeightOfTheImage.ets @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取图片的宽高 +*/ + +@Component +struct ImageWidthHeight { + build() { + // [Start obtain_the_width_and_height_of_the_image] + Image($r('app.media.startIcon')) + .width(200) + .height(200) + .objectFit(ImageFit.Contain) + .onComplete((event) => { + let imageWidth = event?.width; + let imageHeight = event?.height; + console.info('imageWidth:'+imageWidth,'imageHeight:'+imageHeight); + }) + // [End obtain_the_width_and_height_of_the_image] + } +} diff --git a/ArkUI/entry/src/main/ets/pages/OneClickClearOfComponentContent.ets b/ArkUI/entry/src/main/ets/pages/OneClickClearOfComponentContent.ets new file mode 100644 index 0000000000000000000000000000000000000000..5199851a2d5843007bea7b74b1db559ed04fac3b --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/OneClickClearOfComponentContent.ets @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何一键清空TextInput、TextArea组件内容 +*/ + +// [Start one_click_clear_of_component_content] +@Entry +@Component +struct Index { + @State text: string = 'Hello World'; + controller: TextInputController = new TextInputController(); + + build() { + Row() { + Column() { + TextInput({ placeholder: 'Please input your words.', text: this.text, + controller:this.controller}).onChange((value) => { + this.text = value; + }) + Button('Clear TextInput').onClick(() => { + this.text = ''; + }) + } + .width('100%') + } + .height('100%') + } +} +// [End one_click_clear_of_component_content] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/PopUpAgainInCustomPopUps.ets b/ArkUI/entry/src/main/ets/pages/PopUpAgainInCustomPopUps.ets new file mode 100644 index 0000000000000000000000000000000000000000..35fbdb3728ea2eae31595a521d1265a96db4d253 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/PopUpAgainInCustomPopUps.ets @@ -0,0 +1,156 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在自定义弹窗中再次弹窗 +*/ + +// [Start pop_up_again_in_custom_pop_ups] +@CustomDialog +struct CustomDialogExampleTwo { + controllerTwo?: CustomDialogController; + + build() { + Column() { + Text('I am the second pop-up window') + .fontSize(30) + .height(100) + Button('Click on me to close the second pop-up window') + .onClick(() => { + if (this.controllerTwo != undefined) { + this.controllerTwo.close(); + } + }) + .margin(20) + } + } +} + +@CustomDialog +struct CustomDialogExample { + @Link textValue: string; + @Link inputValue: string; + dialogControllerTwo: CustomDialogController | null = new CustomDialogController({ + builder: CustomDialogExampleTwo(), + alignment: DialogAlignment.Bottom, + offset: { dx: 0, dy: -25 } + }) + // If you need to pass in controllers for multiple other pop ups in a custom pop-up, the controller definition for the current custom pop-up should be placed after the other incoming controllers + controller?: CustomDialogController; + cancel: () => void = () => { + } + confirm: () => void = () => { + } + + build() { + Column() { + Text('Change text') + .fontSize(20) + .margin({ top: 10, bottom: 10 }) + TextInput({ placeholder: '', text: this.textValue }) + .height(60) + .width('90%') + .onChange((value: string) => { + this.textValue = value; + }) + Text('Whether to change a text?') + .fontSize(16) + .margin({ bottom: 10 }) + Flex({ justifyContent: FlexAlign.SpaceAround }) { + Button('cancel') + .onClick(() => { + if (this.controller != undefined) { + this.controller.close(); + this.cancel(); + } + }).backgroundColor(0xffffff).fontColor(Color.Black) + Button('confirm') + .onClick(() => { + if (this.controller != undefined) { + this.inputValue = this.textValue; + this.controller.close(); + this.confirm(); + } + }) + .backgroundColor(0xffffff) + .fontColor(Color.Red) + } + .margin({ bottom: 10 }) + + Button('Click on me to open the second pop-up window') + .onClick(() => { + if (this.dialogControllerTwo != null) { + this.dialogControllerTwo.open(); + } + }) + .margin(20) + } + .borderRadius(10) + } +} + +@Component +export struct CustomDialogUser { + @State textValue: string = ''; + @State inputValue: string = 'click me'; + dialogController: CustomDialogController | null = new CustomDialogController({ + builder: CustomDialogExample({ + cancel: this.onCancel, + confirm: this.onAccept, + textValue: $textValue, + inputValue: $inputValue + }), + cancel: this.exitApp, + autoCancel: true, + alignment: DialogAlignment.Bottom, + offset: { dx: 0, dy: -20 }, + gridCount: 4, + customStyle: false, + backgroundColor: 0xd9ffffff, + cornerRadius: 10, + }) + + // When the custom component is about to be destructed, leave dialogController empty + aboutToDisappear() { + this.dialogController = null; // Set dialogController to empty + } + + onCancel() { + console.info('Callback when the first button is clicked'); + } + + onAccept() { + console.info('Callback when the second button is clicked'); + } + + exitApp() { + console.info('Click the callback in the blank area'); + } + + build() { + Column() { + Button(this.inputValue) + .onClick(() => { + if (this.dialogController != null) { + this.dialogController.open(); + } + }) + .backgroundColor(0x317aff) + } + .width('100%') + .margin({ top: 5 }) + } +} +// [End pop_up_again_in_custom_pop_ups] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ProactivelyClearTheFocusOfTheControl.ets b/ArkUI/entry/src/main/ets/pages/ProactivelyClearTheFocusOfTheControl.ets new file mode 100644 index 0000000000000000000000000000000000000000..5cfaea7cb0dc01bbeae1d3316691a112c43db45f --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ProactivelyClearTheFocusOfTheControl.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何主动清除控件的焦点? +*/ + +// [Start proactively_clear_the_focus_of_the_control] +@Entry +@Component +struct ClearComponentFocus { + @State textFocusable: boolean = true; + @State text: string = 'Gain focus'; + + build() { + Column() { + TextInput({ text: this.text }) + .focusable(this.textFocusable) + .onFocus(() => { + this.text = 'Gain focus'; + }) + .onBlur(() => { + this.text = 'Lost Focus'; + }) + Button('Button1') + .width(160) + .height(70) + .margin({ top: 20 }) + .onClick(() => { + this.textFocusable = !this.textFocusable; + }) + } + .width('100%') + .height('100%') + } +} +// [End proactively_clear_the_focus_of_the_control] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/RealizeAdaptiveHeight.ets b/ArkUI/entry/src/main/ets/pages/RealizeAdaptiveHeight.ets new file mode 100644 index 0000000000000000000000000000000000000000..969357f41901d544a040316b3537aa9f87194d15 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/RealizeAdaptiveHeight.ets @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现上下切换的页面间跳转动画 +*/ + +// [Start realize_adaptive_height] +interface Item { + text: string + img: Resource +} + +@Entry +@Component +struct Index { + data: Item[] = [ + { text: 'aaa', img: $r('app.media.app_icon') }, + { text: 'bbb', img: $r('app.media.app_icon') }, + { text: 'ccc', img: $r('app.media.app_icon') }, + { text: 'ddd', img: $r('app.media.app_icon') }, + { text: 'eee', img: $r('app.media.app_icon') }, + { text: 'fff', img: $r('app.media.app_icon') }, + { text: 'ggg', img: $r('app.media.app_icon') }, + { text: 'hhh', img: $r('app.media.app_icon') }, + { text: 'jjj', img: $r('app.media.app_icon') }, + { text: 'kkk', img: $r('app.media.app_icon') }] + // Calculate the number of rows in the grid + getCategoryRowCount() { + return Math.ceil(this.data.length / 4); + } + // Calculate the height of the grid based on the height of the item + getCategoryViewHeight() { + return `${68.33 * this.getCategoryRowCount()}vp`; + } + + build() { + Column() { + Grid() { + ForEach(this.data, (item: Item) => { + GridItem() { + Column() { + Image(item.img) + .width(40) + .height(40) + Text(item.text) + .margin({ top: 2 }) + .fontSize(14) + .textAlign(TextAlign.Center) + } + } + }, (item: Item) => item.text) + } + .height(this.getCategoryViewHeight()) + .columnsTemplate('1fr 1fr 1fr 1fr') + .columnsGap(10) + .rowsGap(10) + .margin({ top: 10 }) + } + .padding(10) + .width('100%') + } +} +// [End realize_adaptive_height] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/RealizePageLevelTransparencyEffect.ets b/ArkUI/entry/src/main/ets/pages/RealizePageLevelTransparencyEffect.ets new file mode 100644 index 0000000000000000000000000000000000000000..30c0ad6de7cfff7fdcc46bca79fd042e274fd5b8 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/RealizePageLevelTransparencyEffect.ets @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:跳转页面如何实现页面级别的透明效果 +*/ + +// [Start realize_page_level_transparency_effect] +@Component +export struct TransparentPage { + @Provide('NavPathStack') pageStack: NavPathStack = new NavPathStack(); + + @Builder + PagesMap(name: string) { + if (name === 'DialogPage') { + DialogPage() + } + } + + build() { + Navigation(this.pageStack) { + Button('Push DialogPage') + .margin(20) + .width('80%') + .onClick(() => { + this.pageStack.pushPathByName('DialogPage', ''); + }) + } + .mode(NavigationMode.Stack) + .title('Main') + .navDestination(this.PagesMap) + } +} + +@Component +export struct DialogPage { + @Consume('NavPathStack') pageStack: NavPathStack; + + build() { + NavDestination() { + Stack({ alignContent: Alignment.Center }) { + Column() { + Text("Dialog NavDestination") + .fontSize(20) + .margin({ bottom: 100 }) + Button("Close") + .onClick(() => { + this.pageStack.pop(); + }) + .width('30%') + } + .justifyContent(FlexAlign.Center) + .borderRadius(10) + .height('30%') + .width('80%') + } + .height("100%") + .width('100%') + } + // Set background color + //.backgroundColor(Color.Red) + .hideTitleBar(true) + .mode(NavDestinationMode.DIALOG) + } +} +// [End realize_page_level_transparency_effect] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/RealizeTransparentTransmissionOfEvents.ets b/ArkUI/entry/src/main/ets/pages/RealizeTransparentTransmissionOfEvents.ets new file mode 100644 index 0000000000000000000000000000000000000000..d23e9c22cc489ef6969fe9afcd1ffa160043d6b9 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/RealizeTransparentTransmissionOfEvents.ets @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现事件透传 +*/ + +// [Start realize_transparent_transmission_of_events] +@Entry +@Component +struct StackExample { + build() { + Stack({ alignContent: Alignment.Bottom }) { + Text('A') + .width('90%') + .height('100%') + .backgroundColor(0xd2cab3) + .align(Alignment.Top) + .onClick(() => { + console.log('11111') + }) + Text('B') + .width('70%') + .height('60%') + .backgroundColor(0xc1cbac) + .align(Alignment.Top) + .hitTestBehavior(HitTestMode.None) + .onClick(() => { + console.log('1111122222') + }) + }.width('100%').height(150).margin({ top: 5 }) + } +} +// [End realize_transparent_transmission_of_events] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ReduceCallsToAboutToBeDeleted.ets b/ArkUI/entry/src/main/ets/pages/ReduceCallsToAboutToBeDeleted.ets new file mode 100644 index 0000000000000000000000000000000000000000..50bcd189d4516dbf46e2fea2588330e1fd0ac02f --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ReduceCallsToAboutToBeDeleted.ets @@ -0,0 +1,106 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:使用LazyForEach时滑动列表产生大量aboutToBeDeleted的函数调用,如何减少? +*/ + +// [Start reduce_calls_to_aboutToBeDeleted] +class MyDataSource implements IDataSource { + private dataArray: string[] = []; + private listener: DataChangeListener | undefined; + + + public totalCount(): number { + return this.dataArray.length; + } + + + public getData(index: number): string { + return this.dataArray[index]; + } + + + public pushData(data: string): void { + this.dataArray.push(data); + } + + + public reloadListener(): void { + this.listener?.onDataReloaded(); + } + + + public registerDataChangeListener(listener: DataChangeListener): void { + this.listener = listener; + } + + + public unregisterDataChangeListener(listener: DataChangeListener): void { + this.listener = undefined; + } +} + + +@Entry +@Component +struct ReuseDemo { + private data: MyDataSource = new MyDataSource(); + + + aboutToAppear() { + for (let i = 1; i < 1000; i++) { + this.data.pushData(i + ""); + } + } + + + // ... + build() { + Column() { + List() { + LazyForEach(this.data, (item: string) => { + ListItem() { + CardView({ item: item }) + } + }, (item: string) => item) + } + } + } +} + + +// Reuse components +@Reusable +@Component +export struct CardView { + @State item: string = ''; + + + aboutToReuse(params: Record): void { + this.item = params.item as string; + } + + + build() { + Column() { + Text(this.item) + .fontSize(30) + } + .borderWidth(1) + .height(100) + } +} +// [End reduce_calls_to_aboutToBeDeleted] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/RemoveTabsComponentMask.ets b/ArkUI/entry/src/main/ets/pages/RemoveTabsComponentMask.ets new file mode 100644 index 0000000000000000000000000000000000000000..6541540d85828fa2bb708c8b429fac897bf55653 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/RemoveTabsComponentMask.ets @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何去除Tabs组件两侧的蒙层 +*/ + +// [Start remove_tabs_component_mask] +// xxx.ets +@Entry +@Component +struct TabsOpaque { + @State message: string = 'Hello World'; + private controller: TabsController = new TabsController(); + @State selfFadingFade: boolean = false; // Does the tab gradually disappear when it exceeds the width of the container? The default value is true. + + + build() { + Column() { + Tabs({ barPosition: BarPosition.End, controller: this.controller }) { + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Pink) + }.tabBar('pink') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Yellow) + }.tabBar('yellow') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Blue) + }.tabBar('blue') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Green) + }.tabBar('green') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Green) + }.tabBar('green') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Green) + }.tabBar('green') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Green) + }.tabBar('green') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Green) + }.tabBar('green') + } + .vertical(false) + .scrollable(true) + .barMode(BarMode.Scrollable) + .barHeight(80) + .animationDuration(400) + .onChange((index: number) => { + console.info(index.toString()); + }) + .fadingEdge(this.selfFadingFade) + .height('30%') + .width('100%') + } + .padding({ top: '24vp', left: '24vp', right: '24vp' }) + } +} +// [End remove_tabs_component_mask] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ResolveConflictsBetweenGestures.ets b/ArkUI/entry/src/main/ets/pages/ResolveConflictsBetweenGestures.ets new file mode 100644 index 0000000000000000000000000000000000000000..d6f62c4927bc466919df126899dea82055468784 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ResolveConflictsBetweenGestures.ets @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何解决滚动类容器的滚动事件和手势之间的冲突 +*/ + +// [Start resolve_conflicts_between_gestures] +@Entry +@Component +struct ScrollAndGesture { + scroller: Scroller = new Scroller(); + private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Up | PanDirection.Down }); + + + build() { + Stack({ alignContent: Alignment.TopStart }) { + Scroll(this.scroller) { + Column() { + ForEach(this.arr, (item: number) => { + Text(item.toString()) + .width('90%') + .height(150) + .backgroundColor(0xFFFFFF) + .borderRadius(15) + .fontSize(16) + .textAlign(TextAlign.Center) + .margin({ top: 10 }) + }, (item: string) => item) + }.width('100%') + } + .scrollable(ScrollDirection.Vertical) // Rolling direction vertically + .scrollBar(BarState.On) // Scroll bar permanent display + .scrollBarColor(Color.Gray) // Scroll bar color + .scrollBarWidth(10) // Scroll bar width + .friction(0.6) + .edgeEffect(EdgeEffect.None) + .onWillScroll((xOffset: number, yOffset: number) => { + console.info(xOffset + ' ' + yOffset); + }) + .onScrollEdge((side: Edge) => { + console.info('To the edge'); + }) + .onScrollStop(() => { + console.info('Scroll Stop'); + }) + } + + + .parallelGesture( + PanGesture(this.panOption) + .onActionStart((event?: GestureEvent) => { + console.info('wy Pan start',event); + }) + .onActionUpdate((event?: GestureEvent) => { + if (event) { + console.info('wy Pan event',event); + } + }) + .onActionEnd(() => { + console.info('wy Pan end'); + }) + ) + .width('100%') + .height('100%') + .backgroundColor(0xDCDCDC) + } +} +// [End resolve_conflicts_between_gestures] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ResolveFullScreenNonEffectiveness.ets b/ArkUI/entry/src/main/ets/pages/ResolveFullScreenNonEffectiveness.ets new file mode 100644 index 0000000000000000000000000000000000000000..d687259278db1a5992e85bba68c395c569faacf8 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ResolveFullScreenNonEffectiveness.ets @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何解决子组件全屏后margin不会生效的问题 +*/ + +// [Start resolve_full_screen_non_effectiveness] +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .textAlign(TextAlign.Center) + .width('100%') + .constraintSize({ maxWidth: '100%' }) + .backgroundColor(Color.Blue) + .margin({ left: 50, right: 50 }) + } + .width('100%') + } + .height('100%') + } +} +// [End resolve_full_screen_non_effectiveness] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ResolveOverlapBetweenStatusBarAndPage_One.ets b/ArkUI/entry/src/main/ets/pages/ResolveOverlapBetweenStatusBarAndPage_One.ets new file mode 100644 index 0000000000000000000000000000000000000000..11248dfb46b5def3fb2e0cbe739b430b5190a5a2 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ResolveOverlapBetweenStatusBarAndPage_One.ets @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:状态栏与页面内容发生重叠,如何解决? +*/ + +// [Start resolve_overlap_between_status_bar_and_page_one] +import { window } from '@kit.ArkUI'; + + +@Entry +@Component +struct ImagePreviewExample { + windowClass: window.Window = AppStorage.get('windowClass') as window.Window; + @State visible: Visibility = Visibility.None; + @State scaleValue: number = 1; + @State pinchValue: number = 1; + @State pinchX: number = 0; + @State pinchY: number = 0; + @State count: number = 0; + @State offsetX: number = 0; + @State offsetY: number = 0; + @State positionX: number = 0; + @State positionY: number = 0; + + + build() { + Stack() { + Row() { + Column() { + Image($r('app.media.startIcon')) + .width(100) + .height(100) + .onClick(() => { + if (this.visible === Visibility.Visible) { + this.visible = Visibility.None; + } else { + this.visible = Visibility.Visible; + this.windowClass.setSpecificSystemBarEnabled('status', false); + } + }) + } + .width('100%') + .justifyContent(FlexAlign.Center) + .alignItems(HorizontalAlign.Center) + } + .height('100%') + + + Text('') + .onClick(() => { + if (this.visible === Visibility.Visible) { + this.windowClass.setSpecificSystemBarEnabled('status', true); + this.visible = Visibility.None; + } else { + this.visible = Visibility.Visible; + } + }) + .width('100%') + .height('100%') + .opacity(0.16)// transparency + .backgroundColor(Color.Black) + .visibility(this.visible) + + + Column() { + Image($r('app.media.startIcon')) + .width(300) + .height(300) + .draggable(false) + .visibility(this.visible) + .scale({ + x: this.scaleValue, + y: this.scaleValue, + z: 1 + }) + .translate({ + x: this.offsetX, + y: this.offsetY, + z: 0 + }) + .gesture( + GestureGroup(GestureMode.Parallel, + PinchGesture({ fingers: 2 }) + .onActionUpdate((event?: GestureEvent) => { + if (event) { + this.scaleValue = this.pinchValue * event.scale; + this.pinchX = event.pinchCenterX; + this.pinchY = event.pinchCenterY; + } + }) + .onActionEnd(() => { + this.pinchValue = this.scaleValue; + }), + PanGesture() + .onActionUpdate((event?: GestureEvent) => { + if (event) { + this.offsetX = this.positionX + event.offsetX; + this.offsetY = this.positionY + event.offsetY; + } + }) + .onActionEnd(() => { + this.positionX = this.offsetX; + this.positionY = this.offsetY; + }) + ) + ) + } + } + .backgroundColor(Color.White) + .height('100%') + .width('100%') + } +} +// [End resolve_overlap_between_status_bar_and_page_one] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ResolveOverlapBetweenStatusBarAndPage_Two.ets b/ArkUI/entry/src/main/ets/pages/ResolveOverlapBetweenStatusBarAndPage_Two.ets new file mode 100644 index 0000000000000000000000000000000000000000..fc6c524cc104ed5a34673579521234e64f6c61f4 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ResolveOverlapBetweenStatusBarAndPage_Two.ets @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:状态栏与页面内容发生重叠,如何解决? +*/ + +// [Start resolve_overlap_between_status_bar_and_page_two] +@Entry +@Component +struct AvoidStatusBar { + statusBar: number = AppStorage.get('statusBar') as number; + + + build() { + + + Column() { + Row() { + Text('ROW1') + .fontSize(40) + } + .backgroundColor(Color.Orange) + .padding(20) + + + Row() { + Text('ROW2') + .fontSize(40) + } + .backgroundColor(Color.Orange) + .padding(20) + + + Row() { + Text('ROW3') + .fontSize(40) + } + .backgroundColor(Color.Orange) + .padding(20) + + + Row() { + Text('ROW4') + .fontSize(40) + } + .backgroundColor(Color.Orange) + .padding(20) + + + Row() { + Text('ROW5') + .fontSize(40) + } + .backgroundColor(Color.Orange) + .padding(20) + + + Row() { + Text('ROW6') + .fontSize(40) + } + .backgroundColor(Color.Orange) + .padding(20) + } + .width('100%') + .height('100%') + .alignItems(HorizontalAlign.Center) + .justifyContent(FlexAlign.SpaceBetween) + .padding({ top: this.statusBar }) // The specific value of the margin or padding here should be consistent with the height of the status bar area in practice + .backgroundColor('#008000') + } +} +// [End resolve_overlap_between_status_bar_and_page_two] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ResolveTextTruncationException.ets b/ArkUI/entry/src/main/ets/pages/ResolveTextTruncationException.ets new file mode 100644 index 0000000000000000000000000000000000000000..644dc90cf5f2beaa3ab1d8654ca7d3bfec66e1be --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ResolveTextTruncationException.ets @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何解决Text组件文本为中文、数字、英文混合时显示省略号截断异常的问题 +*/ + +// [Start resolve_text_truncation_exception] +@Entry +@Component +struct TextMixException { + @State text: string = '2 years · VIP membership for 3 months · 8GB · 230mm · Product color'; + + + build() { + RelativeContainer() { + Text(this.text) + .width(200)// Set maximum number of rows + .maxLines(1)// Long text display + .textOverflow({ overflow: TextOverflow.Ellipsis })// Long text display ellipsis + .ellipsisMode(EllipsisMode.END)// Set the line breaking rule WordBreak.BREAK_ALL and implement truncation on a letter by letter basis + .wordBreak(WordBreak.BREAK_ALL) + .textAlign(TextAlign.JUSTIFY) + .backgroundColor(Color.Green) + .fontSize(16) + } + .height('100%') + .width('100%') + } +} +// [End resolve_text_truncation_exception] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ResolveTheNestingOfWebAndList.ets b/ArkUI/entry/src/main/ets/pages/ResolveTheNestingOfWebAndList.ets new file mode 100644 index 0000000000000000000000000000000000000000..a8c1b4678dbe828766f59b8428fcfc3d47a6382c --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ResolveTheNestingOfWebAndList.ets @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何解决Web与List的嵌套滑动冲突 +*/ + +// [Start resolve_the_nesting_of_web_and_list] +import { webview } from '@kit.ArkWeb'; + +@Entry +@Component +struct SlidingConflictBetweenWebAndList { + webviewController: webview.WebviewController = new webview.WebviewController(); + + build() { + List() { + ListItem() { + Web({ + src: $rawfile('index.html'), + controller: this.webviewController + }) + .width('100%') + .height(220) + }.hitTestBehavior(HitTestMode.Block) + ListItem() { + Web({ + src: $rawfile('index.html'), + controller: this.webviewController + }) + .width('100%') + .height(220) + } + ListItem() { + Text('1') + } + .height(220) + ListItem() { + Text('2') + } + .height(220) + } + .backgroundColor(Color.Blue) + .width('100%') + .height('100%') + } +} +// [End resolve_the_nesting_of_web_and_list] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ResolveTriggerOfParentComponent.ets b/ArkUI/entry/src/main/ets/pages/ResolveTriggerOfParentComponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..a55f1877134219beb153d179a507396cf101efc7 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ResolveTriggerOfParentComponent.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:当子组件触发触摸事件的时候,父组件如果设置触摸事件的话,如何解决父组件也会被触发的问题 +*/ + +// [Start resolve_trigger_of_parent_component] +@Entry +@Component +struct TouchExample { + @State text: string = 'Parent component' + @State parentComponentResponse: string = 'Response times of parent component' + @State parentComponentResponseNum: number = 0 + @State childComponentResponse: string = 'Number of sub component responses' + @State childComponentResponseNum: number = 0 + + build() { + Column() { + Column(){ + Text(this.text).margin({bottom: 20}) + Text(this.parentComponentResponse + ':' + `${this.parentComponentResponseNum}`) + Text(this.childComponentResponse + ':' + `${this.childComponentResponseNum}`) + + Button('child').height(40).width(100).margin({top: 20}) + .onTouch((e) => { + this.childComponentResponseNum ++ + e.stopPropagation() + }) + } + .onTouch(() => { + this.parentComponentResponseNum ++ + }) + }.width('100%').padding(30) + } +} +// [End resolve_trigger_of_parent_component] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ResolveTriggerParentComponentClickEvent.ets b/ArkUI/entry/src/main/ets/pages/ResolveTriggerParentComponentClickEvent.ets new file mode 100644 index 0000000000000000000000000000000000000000..c41070ea87a25c8d7faacdc0b4d5b80f9762fb1f --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ResolveTriggerParentComponentClickEvent.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何解决点击子组件模块区域会触发父组件的点击事件问题 +*/ + +// [Start resolve_trigger_parent_component_click_event] +@Entry +@Component +struct TouchExample { + @State text: string = 'Parent component' + @State parentComponentResponse: string = 'Response times of parent component' + @State parentComponentResponseNum: number = 0 + + build() { + Column() { + Column(){ + Text(this.text).margin({bottom: 20}) + Text(this.parentComponentResponse + ':' + `${this.parentComponentResponseNum}`) + Row(){ + //Wrap a container component around the Button component and set the hitTestBehavior property to HitTestMode.Block, which can prevent event bubbling. + Button('Disable sub components').height(40).width(100).margin({top: 20}) + } + .hitTestBehavior(HitTestMode.Block) + }.onClick((e) => { + this.parentComponentResponseNum ++; + }) + .width('80%') + .height('30%') + .backgroundColor(Color.Gray) + } + .width('100%') + .padding(30) + } +} +// [End resolve_trigger_parent_component_click_event] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ResolveTwoLayersOfTabs.ets b/ArkUI/entry/src/main/ets/pages/ResolveTwoLayersOfTabs.ets new file mode 100644 index 0000000000000000000000000000000000000000..1cc4f100aa1df2c150f883b9abf59c81a4d6034f --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ResolveTwoLayersOfTabs.ets @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何解决两层Tabs出现滑动冲突的情况? +*/ + +// [Start resolve_two_layers_of_tabs] +@Entry +@Component +struct TwoLayerTabNestedSliding { + build() { + Column() { + Tabs({ barPosition: BarPosition.End }) { + TabContent() { + Column() { + Tabs() { + TabContent() { + Text('Focus on content') + } + .tabBar('follow with interest') + TabContent() { + Text('The content of the game') + } + .tabBar('game') + } + } + .backgroundColor('#f08a34') + .width('100%') + } + .tabBar('home page') + TabContent() { + Column() { + Tabs() { + TabContent() { + Text('The content of technology') + } + .tabBar('science and technology') + TabContent() { + Text('The content of the video') + } + .tabBar('video') + } + } + .backgroundColor('#f08a34') + .width('100%') + } + .tabBar('find') + } + .scrollable(false) + } + .width('100%') + .height('100%') + } +} +// [End resolve_two_layers_of_tabs] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ResolveWebPageAccidentalTouches.ets b/ArkUI/entry/src/main/ets/pages/ResolveWebPageAccidentalTouches.ets new file mode 100644 index 0000000000000000000000000000000000000000..73c216646c27f2427c022471c5cc02487b2c9a85 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ResolveWebPageAccidentalTouches.ets @@ -0,0 +1,101 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何解决Web页上下滑动时会误触发tab页翻页手势及tab页切换时Web组件还可以上下滚动问题 +*/ + +// [Start resolve_web_page_accidental_touches] +import { webview } from '@kit.ArkWeb'; + + +@Component +@Entry +struct TabWebScroll { + @State flag: boolean = true; // Control the sliding page for page switching + private tabsController = new TabsController(); + private currentIndex: number = 0; + private webviewController: webview.WebviewController = new webview.WebviewController(); + + + build() { + Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) { + TabContent() { + Web({ src: 'https://developer.huawei.com/consumer/cn/', controller: this.webviewController }) + .nestedScroll({ + // Set nested scrolling + scrollForward: NestedScrollMode.PARENT_FIRST, + scrollBackward: NestedScrollMode.SELF_FIRST + }) + } + .tabBar(this.tabBuilder('home page', 0)) + + + TabContent() { + Column() { + Text('find') + } + .width('100%') + .height('100%') + } + .tabBar(this.tabBuilder('find', 1)) + + + TabContent() { + Column() { + Text('recommend') + } + .width('100%') + .height('100%') + } + .tabBar(this.tabBuilder('recommend', 2)) + + + TabContent() { + Column() { + Text('my') + } + .width('100%') + .height('100%') + } + .tabBar(this.tabBuilder('my', 3)) + } + .onChange((index: number) => { + this.currentIndex = index; + }) + .scrollable(this.flag) + .onAnimationEnd(() => { + // Trigger this callback when the animation ends, and set the web component to slide + this.webviewController.setScrollable(true); + }) + .onGestureSwipe(() => { + // During the sliding process on the page, this callback is triggered frame by frame. When switching between tab pages, the web page cannot slide up or down + this.webviewController.setScrollable(false); + }) + } + + + @Builder + tabBuilder(title: string, targetIndex: number) { + Column() { + Text(title) + .fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B') + } + .width('100%') + .height(50) + .justifyContent(FlexAlign.Center) + } +} +// [End resolve_web_page_accidental_touches] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ResolvingIsNotCallable.ets b/ArkUI/entry/src/main/ets/pages/ResolvingIsNotCallable.ets new file mode 100644 index 0000000000000000000000000000000000000000..2d499f87665eef38e2d2cfd3c8622df92a373bc3 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ResolvingIsNotCallable.ets @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:使用BuilderParam在父组件调用this的方法报错:Error message:is not callable +*/ + +// [Start resolving_is_not_callable_one] +@Component +struct Child { + @Builder FunABuilder0() {} + @BuilderParam aBuilder0: () => void = this.FunABuilder0; + + build() { + Column() { + this.aBuilder0() + } + } +} + +@Entry +@Component +struct Parent { + @Builder componentBuilder() { + Text('Parent builder') + .onClick(()=>{ + this.test1(); + }) + } + + test1(): void { + console.log('test1'); + } + + build() { + Column() { + Child({ aBuilder0: this.componentBuilder }) + } + } +} +// [End resolving_is_not_callable_one] + + +@Component +struct ChildTest { + @Builder componentBuilder() { + Text('Parent builder') + .onClick(()=>{ + }) + } + + build() { + // [Start resolving_is_not_callable_two] + Child({ aBuilder0:()=>{ this.componentBuilder() } }) + // [End resolving_is_not_callable_two] + } +} diff --git a/ArkUI/entry/src/main/ets/pages/ReturnTheCursorToTheStartPoint.ets b/ArkUI/entry/src/main/ets/pages/ReturnTheCursorToTheStartPoint.ets new file mode 100644 index 0000000000000000000000000000000000000000..ee4aeafd36a69ed04634a102093700df25365cbd --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ReturnTheCursorToTheStartPoint.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:TextInput在聚焦时如何使光标回到起点 +*/ + +// [Start return_the_cursor_to_the_start_point] +@Entry +@Component +struct TextInputDemo { + controller: TextInputController = new TextInputController(); + + build() { + Column() { + TextInput({ controller: this.controller }) + .onEditChange((isEditing: boolean) => { + if (isEditing) { + setTimeout(() => { + this.controller.caretPosition(0); + }, 100) + } + }) + } + } +} +// [End return_the_cursor_to_the_start_point] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ReusingListItemGroupAndLazyForEachComponents.ets b/ArkUI/entry/src/main/ets/pages/ReusingListItemGroupAndLazyForEachComponents.ets new file mode 100644 index 0000000000000000000000000000000000000000..d58aa8607c3f5e1cf4450fe80375ea5521781514 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ReusingListItemGroupAndLazyForEachComponents.ets @@ -0,0 +1,231 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何使用ListItemGroup和LazyForEach结合并实现组件复用 +*/ + +// [Start reusing_listItemGroup_and_lazyForEach_components] +@Entry +@Component +struct ListItemGroupAndReusable { + data: DataSrc2 = new DataSrc2(); + + + @Builder + itemHead(text: string) { + Text(text) + .fontSize(20) + .backgroundColor(0xAABBCC) + .width('100%') + .padding(10) + } + + + aboutToAppear() { + for (let i = 0; i < 10000; i++) { + let data_1 = new DataSrc1(); + for (let j = 0; j < 12; j++) { + data_1.Data.push(`Test Data Test Data Test Data: ${i} - ${j}`); + } + this.data.Data.push(data_1); + } + } + + + build() { + Stack() { + List() { + LazyForEach(this.data, (item: DataSrc1, index: number) => { + ListItemGroup({ header: this.itemHead(index.toString()) }) { + LazyForEach(item, (ii: string, index: number) => { + ListItem() { + Inner({ str: ii }) + } + }) + } + .width('100%') + .height('60vp') + }) + } + } + .width('100%') + .height('100%') + } +} + + +@Reusable +@Component +struct Inner { + @State str: string = '' + + + aboutToReuse(param: ESObject) { + this.str = param.str; + } + + + build() { + Text(this.str) + } +} + + +class DataSrc1 implements IDataSource { + listeners: DataChangeListener[] = []; + Data: string[] = []; + + + public totalCount(): number { + return this.Data.length; + } + + + public getData(index: number): string { + return this.Data[index]; + } + + + // This method is called on the framework side to add listener listening to the LazyForEach component at its data source + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener); + } + } + + + // This method is called on the framework side to remove listener listening for the corresponding LazyForEach component at the data source + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + this.listeners.splice(pos, 1); + } + } + + + // Notify LazyForEach component to reload all child components + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + + // Notify LazyForEach component to add a sub component at the index corresponding to the index + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + + // Notify LazyForEach component that there is a change in data at the index corresponding to the index, and that the sub component needs to be rebuilt + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + + // Notify LazyForEach component to remove the sub component at the index corresponding to the index + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + + // Notify LazyForEach component to swap the subcomponents at the from index and to index + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } +} + + +class DataSrc2 implements IDataSource { + listeners: DataChangeListener[] = []; + Data: DataSrc1[] = []; + + + public totalCount(): number { + return this.Data.length; + } + + + public getData(index: number): DataSrc1 { + return this.Data[index]; + } + + + // This method is called on the framework side to add listener listening to the LazyForEach component at its data source + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener); + } + } + + + // This method is called on the framework side to remove listener listening for the corresponding LazyForEach component at the data source + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + this.listeners.splice(pos, 1); + } + } + + + // Notify LazyForEach component to reload all child components + notifyDataReload(): void { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + + // Notify LazyForEach component to add a sub component at the index corresponding to the index + notifyDataAdd(index: number): void { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + + // Notify LazyForEach component that there is a change in data at the index corresponding to the index, and that the sub component needs to be rebuilt + notifyDataChange(index: number): void { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } + + + // Notify LazyForEach component to remove the sub component at the index corresponding to the index + notifyDataDelete(index: number): void { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + + // Notify LazyForEach component to swap the subcomponents at the from index and to index + notifyDataMove(from: number, to: number): void { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } +} +// [End reusing_listItemGroup_and_lazyForEach_components] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ScrollListUnilateralReboundEffect.ets b/ArkUI/entry/src/main/ets/pages/ScrollListUnilateralReboundEffect.ets new file mode 100644 index 0000000000000000000000000000000000000000..9f07dc7275e606076872adb65a7aef4b304481bb --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ScrollListUnilateralReboundEffect.ets @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现Scroll、List单边回弹效果 +*/ + +// [Start scroll_list_unilateral_rebound_effect] +// Single side rebound effect of Scroll component +@Entry +@Component +struct ScrollSideRebound { + @State yOffset: number = 0; + scroller: Scroller = new Scroller(); + private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + + + build() { + Stack({ alignContent: Alignment.TopStart }) { + Scroll(this.scroller) { + Column() { + ForEach(this.arr, (item: number) => { + Text(item.toString()) + .width('90%') + .height(150) + .backgroundColor(0xFFFFFF) + .borderRadius(15) + .fontSize(16) + .textAlign(TextAlign.Center) + .margin({ top: 10 }) + }, (item: string) => item) + } + .width('100%') + } + .scrollable(ScrollDirection.Vertical) // Rolling direction vertically + .scrollBar(BarState.On) // Scroll bar permanent display + .scrollBarColor(Color.Gray) // Scroll bar color + .scrollBarWidth(2) // Scroll bar width + .friction(0.6) + .edgeEffect(this.yOffset <= 0 ? EdgeEffect.Spring : EdgeEffect.None) // Rebound after rolling to the edge + .onDidScroll(() => { + this.yOffset = this.scroller.currentOffset().yOffset; + }) + } + .width('100%') + .height('100%') + .backgroundColor(0xDCDCDC) + } +} +// [End scroll_list_unilateral_rebound_effect] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/SegmentedFontStyleSetting.ets b/ArkUI/entry/src/main/ets/pages/SegmentedFontStyleSetting.ets new file mode 100644 index 0000000000000000000000000000000000000000..4fcb08d1ea4a49f4db2852fc556df23e9c347bfe --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/SegmentedFontStyleSetting.ets @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:文本组件是否支持分段设置字体样式 +*/ + +// [Start segmented_font_style_setting] +@Entry +@Component +struct TestDemoPage { + @State message: string = "Hello World"; + + build() { + Row() { + Column() { + Text() { + Span('test text: ') + .fontSize(20) + .fontWeight(FontWeight.Bolder) + .fontColor(Color.Black) + Span(this.message) + .fontSize(15) + .fontColor(Color.Red) + } + } + .width('100%') + } + .height('100%') + } +} +// [End segmented_font_style_setting] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/SemiModalControlWithFixedHeight.ets b/ArkUI/entry/src/main/ets/pages/SemiModalControlWithFixedHeight.ets new file mode 100644 index 0000000000000000000000000000000000000000..e8365da1cf46a505059be9cae2c9a357899e380d --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/SemiModalControlWithFixedHeight.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:半模态转场如何控制固定高度 +*/ + +// [Start semi_modal_control_with_fixed_height] +@Entry +@Component +struct SheetTransitionExample { + @State isShow: boolean = false; + @State sheetHeight: number = 300; + + @Builder + myBuilder() { + Column() { + Button('change height') + .margin(10) + .fontSize(20) + .onClick(() => { + this.sheetHeight = 500; + }) + + Button('Set Illegal height') + .margin(10) + .fontSize(20) + .onClick(() => { + this.sheetHeight = 0; + }) + } + .width('100%') + .height('100%') + } + + build() { + Column() { + Button('transition modal 1') + .onClick(() => { + this.isShow = true; + }) + .fontSize(20) + .margin(10) + .bindSheet(this.isShow, this.myBuilder(), { height: this.sheetHeight, backgroundColor: Color.Green }) + } + .justifyContent(FlexAlign.Center) + .width('100%') + .height('100%') + } +} +// [End semi_modal_control_with_fixed_height] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/SetDifferentAttributes.ets b/ArkUI/entry/src/main/ets/pages/SetDifferentAttributes.ets new file mode 100644 index 0000000000000000000000000000000000000000..ca4cfc1a8b9ebbdf7bb721a00867ff95800aef1b --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/SetDifferentAttributes.ets @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何给UI组件设置不同情况下的属性 +*/ + +// [Start set_different_attributes] +@Entry +@Component +struct TestHeightPage { + @State message: string = 'Hello World'; + @State myHeight1: number = 30; + @State myHeight2: number = 60; + @State flag: Boolean = false + build() { + Column() { + Text(this.message) + .fontSize(20) + .fontWeight(FontWeight.Bold) + .width('100%') + .height(this.flag ? this.myHeight1 : this.myHeight2) + .backgroundColor(Color.Orange) + + Button('Modify Text attribute height').onClick(() => { + //1.if/else + if (this.flag) { + this.flag = false; + } else { + this.flag = true; + } + //2.取反 + this.flag = !this.flag; + }).margin({ top: 12 }) + } + .height('100%') + } +} +// [End set_different_attributes] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/SetRoundedCornersAndSpacing.ets b/ArkUI/entry/src/main/ets/pages/SetRoundedCornersAndSpacing.ets new file mode 100644 index 0000000000000000000000000000000000000000..adfca7d7c7e4b5c3b80bb9493dc3dd6d6082e185 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/SetRoundedCornersAndSpacing.ets @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何设置分组列表的圆角和间距 +*/ + +// [Start set_rounded_corners_and_spacing] +// xxx.ets +@Entry +@Component +struct ListItemGroupExample { + private timeTable: TimeTable[] = [ + { projects: ['language'] }, + { projects: ['mathematics', 'English'] }, + { projects: ['physics', 'chemistry', 'biology'] }, + { projects: ['the fine arts', 'music', 'sport'] } + ] + + build() { + Column() { + List({ space: 20 }) { // Set the spacing of the grouping list + ForEach(this.timeTable, (item: TimeTable) => { + ListItemGroup({ style: ListItemGroupStyle.CARD }) { // Set the rounded corners of the grouping list + ForEach(item.projects, (project: string) => { + ListItem() { + Text(project) + .width("100%") + .height(100) + .fontSize(20) + .textAlign(TextAlign.Center) + .backgroundColor(0xFFFFFF) + } + }, (item: string) => item) + } + }) + } + .width('90%') + .sticky(StickyStyle.Header | StickyStyle.Footer) + .scrollBar(BarState.Off) + } + .width('100%') + .height('100%') + .backgroundColor(0xDCDCDC) + .padding({ top: 5, bottom: 5 }) + } +} + +interface TimeTable { + projects: string[]; +} +// [End set_rounded_corners_and_spacing] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/SetStartingPositionOfTheCursor.ets b/ArkUI/entry/src/main/ets/pages/SetStartingPositionOfTheCursor.ets new file mode 100644 index 0000000000000000000000000000000000000000..6247d7b10fb7346c880e24814cbcaba11d9bbcc9 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/SetStartingPositionOfTheCursor.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:RichEditor组件如何设置光标的起始位置位于左上角 +*/ + +// [Start set_starting_position_of_the_cursor] +// xxx.ets +@Entry +@Component +struct RichEditorExample { + controller: RichEditorController = new RichEditorController(); + + build() { + Column() { + RichEditor({ controller: this.controller }) + .align(Alignment.TopStart) // Set the starting position of the cursor to the upper left corner + .height(200) + .borderWidth(1) + .borderColor(Color.Red) + .width('100%') + } + } +} +// [End set_starting_position_of_the_cursor] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/SetStylesForComponentsInDifferentStates.ets b/ArkUI/entry/src/main/ets/pages/SetStylesForComponentsInDifferentStates.ets new file mode 100644 index 0000000000000000000000000000000000000000..a1bafdb9f40b33a2c5addf42d35ff6e0bd55b8d9 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/SetStylesForComponentsInDifferentStates.ets @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何设置组件不同状态下的样式 +*/ + +// [Start set_styles_for_components_in_different_states] +@Component +struct PolymorphicStyle { + @Styles + pressedStyles() { + .backgroundColor('#ED6F21') + .borderRadius(10) + .borderStyle(BorderStyle.Dashed) + .borderWidth(2) + .borderColor('#33000000') + .width(120) + .height(30) + .opacity(1) + } + + + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) { + Text('pressed') + .backgroundColor('#0A59F7') + .borderRadius(20) + .borderStyle(BorderStyle.Dotted) + .borderWidth(2) + .borderColor(Color.Red) + .width(100) + .height(25) + .opacity(1) + .fontSize(14) + .fontColor(Color.White) + .stateStyles({ + pressed: this.pressedStyles + }) + .margin({ bottom: 20 }) + .textAlign(TextAlign.Center) + } + .width(350) + .height(300) + } +} +// [End set_styles_for_components_in_different_states] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/SetTabsGradientEffect_One.ets b/ArkUI/entry/src/main/ets/pages/SetTabsGradientEffect_One.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ed3cb02ff873b55d1568945ee3bc3888485557b --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/SetTabsGradientEffect_One.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何设置Tabs的末尾由透明到不透明的渐变效果 +*/ + +// [Start set_tabs_gradient_effect_one] +@Entry +@Component +struct ListExample { + @State arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + private scroller: Scroller = new Scroller(); + + + build() { + Stack() { + List({ space: 10 }) { + ForEach(this.arr, (item: string) => { + ListItem() { + Text("China Fashion") + .width(100) + .height(64) + .fontColor(Color.White) + .backgroundColor(Color.Black) + .textAlign(TextAlign.Center) + } + }, (item: string) => item); + } + .listDirection(Axis.Horizontal) + .scrollBar(BarState.Off) + .padding({ top: 20, bottom: 20 }) + .width("80%") + .height("100%") + + + Stack() { + + + } + .linearGradient({ + angle: 90, + colors: [[0x000000, 0.0], ['rgba(0,0,0,0)', 0.1], ['rgba(0,0,0,0)', 0.9], [0x000000, 1.0]] + }) + .width("80%") + .height("100%") + .hitTestBehavior(HitTestMode.None) + }.height(100).width('100%').backgroundColor(Color.Black) + } +} +// [End set_tabs_gradient_effect_one] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/SetTabsGradientEffect_Two.ets b/ArkUI/entry/src/main/ets/pages/SetTabsGradientEffect_Two.ets new file mode 100644 index 0000000000000000000000000000000000000000..570b5859167182b1611d620050dba60436421724 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/SetTabsGradientEffect_Two.ets @@ -0,0 +1,139 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何设置Tabs的末尾由透明到不透明的渐变效果 +*/ + +// [Start set_tabs_gradient_effect_two] +@Entry +@Component +struct TabsOpaque { + @State message: string = 'Hello World'; + private controller: TabsController = new TabsController(); + private controller1: TabsController = new TabsController(); + @State selfFadingFade: boolean = true; + + + build() { + Column() { + Button('Sub tab settings gradually disappear').width('100%').margin({ bottom: '12vp' }) + .onClick((event?: ClickEvent) => { + this.selfFadingFade = true; + }) + Button('Sub tab settings do not fade away').width('100%').margin({ bottom: '12vp' }) + .onClick((event?: ClickEvent) => { + this.selfFadingFade = false; + }) + Tabs({ barPosition: BarPosition.End, controller: this.controller }) { + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Pink) + }.tabBar('pink') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Yellow) + }.tabBar('yellow') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Blue) + }.tabBar('blue') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Green) + }.tabBar('green') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Green) + }.tabBar('green') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Green) + }.tabBar('green') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Green) + }.tabBar('green') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Green) + }.tabBar('green') + } + .vertical(false) + .scrollable(true) + .barMode(BarMode.Scrollable) + .barHeight(80) + .animationDuration(400) + .onChange((index: number) => { + console.info(index.toString()); + }) + .fadingEdge(this.selfFadingFade) + .height('30%') + .width('100%') + + + Tabs({ barPosition: BarPosition.Start, controller: this.controller1 }) { + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Pink) + }.tabBar('pink') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Yellow) + }.tabBar('yellow') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Blue) + }.tabBar('blue') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Green) + }.tabBar('green') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Green) + }.tabBar('green') + + + TabContent() { + Column().width('100%').height('100%').backgroundColor(Color.Green) + }.tabBar('green') + } + .vertical(true) + .scrollable(true) + .barMode(BarMode.Scrollable) + .barHeight(200) + .barWidth(80) + .animationDuration(400) + .onChange((index: number) => { + console.info(index.toString()); + }) + .fadingEdge(this.selfFadingFade) + .height('30%') + .width('100%') + } + .padding({ top: '24vp', left: '24vp', right: '24vp' }) + } +} +// [End set_tabs_gradient_effect_two] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/SideBarContainerSetControlButton.ets b/ArkUI/entry/src/main/ets/pages/SideBarContainerSetControlButton.ets new file mode 100644 index 0000000000000000000000000000000000000000..210bd7b40417665a0d8327ffd2f28bb5dfe13c18 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/SideBarContainerSetControlButton.ets @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:SideBarContainer如何设置controlButton属性 +*/ + +// [Start sideBarContainer_set_controlButton] +@Entry +@Component +struct SideBarContainerExample { + normalIcon: Resource = $r("app.media.icon") + selectedIcon: Resource = $r("app.media.icon") + @State arr: number[] = [1, 2, 3] + @State current: number = 1 + + build() { + SideBarContainer(SideBarContainerType.Embed) { + Column() { + ForEach(this.arr, (item: number, index) => { + Column({ space: 5 }) { + Image(this.current === item ? this.selectedIcon : this.normalIcon).width(64).height(64) + Text("Index0" + item) + .fontSize(25) + .fontColor(this.current === item ? '#0A59F7' : '#999') + .fontFamily('source-sans-pro,cursive,sans-serif') + } + .onClick(() => { + this.current = item + }) + }) + }.width('100%') + .justifyContent(FlexAlign.SpaceEvenly) + .backgroundColor('#19000000') + + Column() { + Text('SideBarContainer content text1').fontSize(25) + Text('SideBarContainer content text2').fontSize(25) + } + .margin({ top: 50, left: 20, right: 30 }) + } + .sideBarWidth(150) + .minSideBarWidth(50) + .controlButton({ + left: 32, + top: 32, + width: 32, + height: 32, + icons: { shown: $r("app.media.icon"), + hidden: $r("app.media.icon"), + switching: $r("app.media.icon") } + }) + .maxSideBarWidth(300) + .onChange((value: boolean) => { + console.info('status:' + value) + }) + } +} +// [End sideBarContainer_set_controlButton] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/SlideGestureToCloseFloatingFrame.ets b/ArkUI/entry/src/main/ets/pages/SlideGestureToCloseFloatingFrame.ets new file mode 100644 index 0000000000000000000000000000000000000000..7ded60da1a33c449ea054c78c36f65daa12b2b44 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/SlideGestureToCloseFloatingFrame.ets @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现通过侧滑手势关闭打开的悬浮框 +*/ + +// [Start slide_gesture_to_close_floating_frame] +import { window } from '@kit.ArkUI'; + + +@Entry +@Component +struct CloseWindowDemo { + @State message: string = 'Hello World'; + + + onBackPress(): boolean | void { + console.log('Triggered'); + window.findWindow('mySubWindow').destroyWindow(); + return true; + } + + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize(20) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + } + .height('100%') + .width('100%') + } +} +// [End slide_gesture_to_close_floating_frame] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/SlideTheListLeftRightUpAndDown.ets b/ArkUI/entry/src/main/ets/pages/SlideTheListLeftRightUpAndDown.ets new file mode 100644 index 0000000000000000000000000000000000000000..06bba23886e9c3e244245f87f70a911e4ce692f1 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/SlideTheListLeftRightUpAndDown.ets @@ -0,0 +1,310 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现列表既可以左右滑、又可以上下滑动 +*/ + +// [Start slide_the_list_left_right_up_and_down_one] +import { CommonDataSource } from '../viewmodel/CommonDataSource'; + + +@Observed +class ListItemData { + text: string = ''; + id: string = ''; +} + + +@Observed +class ListData { + id: string = ''; + fundName: string = ''; + textDataSource: CommonDataSource = new CommonDataSource(); +} + + +@Entry +@Component +struct ScrollListDemoPage { + // Horizontal scrolling distance of list data + @State remainOffset: number = 0; + // Maintain a list controller array to store ListScrollers for all horizontal lists + @State listScrollerArr: ListScroller[] = []; + // The starting index of the list is used to refresh the list area displayed on the current screen + @State startIndex: number = 0; + // End index of list + @State endIndex: number = 0; + // List Data - Displayed Content + @State listData: ListItemData[] = []; + // Head title list, titles for each column + private titleList: string[] = []; + // List data source + private dataSource = new CommonDataSource(); + // Vertical scrolling of list data + verticalScroller: Scroller = new Scroller(); + // Horizontal scrolling of list data + horizontalScroller: Scroller = new Scroller(); + // Scroll the left name column + leftScroller: Scroller = new Scroller(); + // Head title column scrolling + topScroller: Scroller = new Scroller(); + // Head Title List Data Source + headerList = new CommonDataSource(); + // Actual processed data + showList: ListData[] = []; + + + aboutToAppear(): void { + this.loadData(); + } + + + loadData() { + for (let i = 0; i < 30; i++) { + this.titleList.push('title' + i); + let itemData: ListItemData = { + text: 'content' + i, + id: i + '' + }; + this.listData.push(itemData); + } + this.headerList.setData(this.titleList); + + + for (let i = 0; i < 20; i++) { + // Every time the next page of data is obtained, it is necessary to synchronously add a controller to the list + this.listScrollerArr.push(new ListScroller()); + let listItemData: ListData = new ListData(); + listItemData.fundName = 'Equity fund' + i; + listItemData.id = 'Equity fund' + i; + listItemData.textDataSource = new CommonDataSource(); + listItemData.textDataSource.setData(this.listData); + this.showList.push(listItemData); + } + this.dataSource.setData(this.showList); + } + + + build() { + Column() { + // Headline Title + this.titleBuilder() + // Divider + Divider() + .strokeWidth('100%') + .color(0xeeeeee) + + + Row() { + // Left column + this.leftBuilder() + // Right column + this.rightScroll() + } + } + .height('100%') + .alignItems(HorizontalAlign.Start) + } + + + @Builder + titleBuilder() { + Row() { + Column() { + Text('name') + } + .width(140) + .height(48) + .backgroundColor(Color.White) + .justifyContent(FlexAlign.Center) + .alignItems(HorizontalAlign.Start) + .padding({ left: 16 }) + + + // Top Title List + List({ scroller: this.topScroller }) { + LazyForEach(this.headerList, (item: string) => { + ListItem() { + Text(item) + .height(48) + .width(120) + .textAlign(TextAlign.Start) + .padding({ left: 16 }) + .backgroundColor(0xFFFFFF) + } + }, (item: string) => item) + } + .listDirection(Axis.Horizontal) + .edgeEffect(EdgeEffect.None) + .scrollBar(BarState.Off) + .width('calc(100% - 140vp)') + .layoutWeight(1) + .onScrollFrameBegin((offset: number) => { + for (let i = this.startIndex; i <= this.endIndex; i++) { + this.listScrollerArr[i].scrollTo({ + xOffset: this.topScroller.currentOffset().xOffset + offset, + yOffset: 0, + animation: false + }); + } + return { offsetRemain: offset }; + }) + } + .height(48) + .width('100%') + .justifyContent(FlexAlign.Start) + } + + + @Builder + leftBuilder() { + List({ scroller: this.leftScroller }) { + LazyForEach(this.dataSource, (item: ListData) => { + ListItem() { + Column() { + Text(item.fundName) + .height('100%') + .backgroundColor(0xFFFFFF) + .layoutWeight(1) + .margin({ left: 16 }) + Divider() + .strokeWidth('100%') + .color(0xeeeeee) + } + .justifyContent(FlexAlign.Center) + .alignItems(HorizontalAlign.Start) + } + .height(60) + }, (item: ListData) => JSON.stringify(item)) + } + .listDirection(Axis.Vertical) + .scrollBar(BarState.Off) + .edgeEffect(EdgeEffect.None) + .height('calc(100% - 48vp)') + .width(140) + .onScrollFrameBegin((offset: number) => { + this.verticalScroller.scrollTo({ + xOffset: 0, + yOffset: this.leftScroller.currentOffset().yOffset + offset, + animation: false + }); + return { offsetRemain: offset }; + }) + } + + + @Builder + rightScroll() { + Scroll(this.horizontalScroller) { + List({ initialIndex: 0, scroller: this.verticalScroller }) { + LazyForEach(this.dataSource, (item: ListData, index: number) => { + ListItem() { + Column() { + List({ scroller: this.listScrollerArr[index] }) { + LazyForEach(item.textDataSource, (item: ListItemData) => { + ListItem() { + Text(item.text) + .height('100%') + .width('100%') + .textAlign(TextAlign.Start) + .padding({ left: 16 }) + .backgroundColor(0xFFFFFF) + .fontColor('#ffe72929') + .maxLines(1) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + } + .width(120) + }, (item: ListItemData, index: number) => JSON.stringify(item) + index + '') + } + .cachedCount(4) + .height('100%') + .width('100%') + .layoutWeight(1) + .listDirection(Axis.Horizontal) + .scrollBar(BarState.Off) + .nestedScroll({ + scrollForward: NestedScrollMode.PARENT_FIRST, + scrollBackward: NestedScrollMode.PARENT_FIRST + }) + .edgeEffect(EdgeEffect.None) + .onDidScroll(() => { + this.remainOffset = this.listScrollerArr[index]!.currentOffset().xOffset; + }) + .onScrollFrameBegin((offset: number) => { + this.topScroller.scrollTo({ + xOffset: this.listScrollerArr[index]!.currentOffset().xOffset + offset, + yOffset: 0, + animation: false + }); + for (let i = this.startIndex; i <= this.endIndex; i++) { + if (i !== index) { + this.listScrollerArr[i].scrollTo({ + xOffset: this.listScrollerArr[index]!.currentOffset().xOffset + offset, + yOffset: 0, + animation: false + }); + } + } + return { offsetRemain: offset }; + }) + + + Divider() + .strokeWidth('100%') + .color(0xeeeeee) + } + .height(60) + } + }, (item: ListData) => JSON.stringify(item)) + } + .height('100%') + .cachedCount(2) + .flingSpeedLimit(1600) + .listDirection(Axis.Vertical) + .scrollBar(BarState.Off) + .edgeEffect(EdgeEffect.None) + .nestedScroll({ scrollForward: NestedScrollMode.PARENT_FIRST, scrollBackward: NestedScrollMode.PARENT_FIRST }) + .onScrollFrameBegin((offset: number) => { + this.leftScroller.scrollTo({ + xOffset: 0, + yOffset: this.verticalScroller.currentOffset().yOffset + offset, + animation: false + }); + return { offsetRemain: offset }; + }) + .onScrollIndex((start: number, end: number) => { + this.startIndex = start; + this.endIndex = end; + // Scroll only the items within the current display range + for (let i = start; i <= end; i++) { + this.listScrollerArr[i].scrollTo({ xOffset: this.remainOffset, yOffset: 0, animation: false }); + } + }) + } + .position({ x: 140, y: 0 }) + .onDidScroll(() => { + this.topScroller.scrollTo({ xOffset: this.remainOffset, yOffset: 0, animation: false }); + }) + .scrollBar(BarState.Off) + .edgeEffect(EdgeEffect.None) + .scrollable(ScrollDirection.Horizontal) + .backgroundColor(0xDCDCDC) + .height('calc(100% - 48vp)') + .width('calc(100% - 140vp)') + } +} +// [End slide_the_list_left_right_up_and_down_one] + diff --git a/ArkUI/entry/src/main/ets/pages/SoftKeyboardPopsUp.ets b/ArkUI/entry/src/main/ets/pages/SoftKeyboardPopsUp.ets new file mode 100644 index 0000000000000000000000000000000000000000..15fa5ca695623a96d5c167516a6e19017b338133 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/SoftKeyboardPopsUp.ets @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现软键盘弹出后,整体布局不变 +*/ + +// [Start soft_keyboard_pops_up] +// xxx.ets +@Entry +@Component +struct TextInputExample { + scroller: Scroller = new Scroller(); + @State Text: string = ''; + + build() { + Scroll(this.scroller) { + Column({ space: 20 }) { + TextInput({ placeholder: 'Please enter the content.' }) + .expandSafeArea([SafeAreaType.KEYBOARD]) + .type(InputType.Password) + .margin({ top: 200 }) + TextInput({ placeholder: 'Please enter the content.' }) + .expandSafeArea([SafeAreaType.KEYBOARD]) + .margin({ top: 200 }) + Text(`UserName:${this.Text}`) + .expandSafeArea([SafeAreaType.KEYBOARD]) + .width('80%') + .margin({ top: 200 }) + TextInput({ placeholder: 'Please enter a user name.', text: this.Text }) + .expandSafeArea([SafeAreaType.KEYBOARD]) + .margin({ top: 200 }) + .onChange((value: string) => { + this.Text = value; + }) + } + .width('100%') + } + .scrollBar(BarState.Off) + } +} +// [End soft_keyboard_pops_up] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/SwitchingBetweenCustomAndSystemKeyboard.ets b/ArkUI/entry/src/main/ets/pages/SwitchingBetweenCustomAndSystemKeyboard.ets new file mode 100644 index 0000000000000000000000000000000000000000..778966fc75b266590647535d144c78332d6e5fbc --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/SwitchingBetweenCustomAndSystemKeyboard.ets @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:自定义键盘和系统键盘如何切换 +*/ + +// [Start switching_between_custom_and_system_keyboard] +@Component +export struct CustomSystemKeyboardToggle { + controller: TextInputController = new TextInputController(); + @State inputValue: string = ''; + @State show: boolean = false; + + // Customize keyboard components + @Builder + CustomKeyboardBuilder() { + Column() { + Button('x') + .onClick(() => { + // Turn off custom keyboard + this.controller.stopEditing(); + this.show = !this.show; + }) + Grid() { + ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, '*', 0, '#'], (item: number | string) => { + GridItem() { + Button(item + '') + .width(110) + .onClick(() => { + this.inputValue += item; + }) + } + }) + } + .maxCount(3) + .columnsGap(10) + .rowsGap(10) + .padding(5) + } + .backgroundColor(Color.Gray) + } + + build() { + Column() { + TextInput({ controller: this.controller, text: this.inputValue })// Bind custom keyboard + .customKeyboard(this.show ? this.CustomKeyboardBuilder() : undefined) + .margin(10) + .height(48) + Button('switch') + .onClick(() => { + this.show = !this.show; + }) + } + } +} +// [End switching_between_custom_and_system_keyboard] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/TabEdgeSlidingEffectTurnedOff.ets b/ArkUI/entry/src/main/ets/pages/TabEdgeSlidingEffectTurnedOff.ets new file mode 100644 index 0000000000000000000000000000000000000000..586cba409ec5b9a57c34c26159d5508d18bab1ac --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/TabEdgeSlidingEffectTurnedOff.ets @@ -0,0 +1,125 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何将Tab的边缘滑动效果关掉,不要回弹 +*/ + +// [Start tab_edge_sliding_effect_turned_off] +@Component +export struct TabsNoRebound { + @State currentIndex: number = 0; + private fontColor: string = '#182431'; + private selectedFontColor: string = '#007DFF'; + private controller: TabsController = new TabsController(); + private panOptionR: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Right }); + private panOptionL: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Left }); + + @Builder + tabBuilder(index: number, name: string) { + Column() { + Text(name) + .fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor) + .fontSize(16) + .fontWeight(this.currentIndex === index ? 500 : 400) + .lineHeight(22) + .margin({ + top: 17, + bottom: 7 + }) + Divider() + .strokeWidth(2) + .color('#007DFF') + .opacity(this.currentIndex === index ? 1 : 0) + } + .width('100%') + } + + build() { + Column() { + Tabs({ barPosition: BarPosition.Start, controller: this.controller }) { + TabContent() { + Column() + .width('100%') + .height('100%') + .backgroundColor('#00CB87') + } + .tabBar(this.tabBuilder(0, 'green')) + .gesture( + // Dragging to the right triggers this gesture event + PanGesture(this.panOptionR) + .onActionStart((event?: GestureEvent) => { + console.info('Pan start'); + }) + .onActionUpdate((event?: GestureEvent) => { + console.info('Pan onActionUpdate'); + }) + .onActionEnd(() => { + console.info('Pan end'); + }) + ) + + TabContent() { + Column() + .width('100%') + .height('100%') + .backgroundColor('#007DFF') + } + .tabBar(this.tabBuilder(1, 'blue')) + + TabContent() { + Column() + .width('100%') + .height('100%') + .backgroundColor('#FFBF00') + } + .tabBar(this.tabBuilder(2, 'yellow')) + + TabContent() { + Column() + .width('100%') + .height('100%') + .backgroundColor('#E67C92') + } + .tabBar(this.tabBuilder(3, 'pink')) + .gesture( + // Dragging to the left triggers this gesture event + PanGesture(this.panOptionL) + .onActionStart((event?: GestureEvent) => { + console.info('Pan start'); + }) + .onActionUpdate((event?: GestureEvent) => { + console.info('Pan onActionUpdate'); + }) + .onActionEnd(() => { + console.info('Pan end'); + }) + ) + } + .barMode(BarMode.Fixed) + .barWidth(360) + .barHeight(56) + .onChange((index: number) => { + this.currentIndex = index; + }) + .width(360) + .height(296) + .margin({ top: 52 }) + .backgroundColor('#F1F3F5') + } + .width('100%') + } +} +// [End tab_edge_sliding_effect_turned_off] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/TheOuterScrollScrollsTheEntireLayout.ets b/ArkUI/entry/src/main/ets/pages/TheOuterScrollScrollsTheEntireLayout.ets new file mode 100644 index 0000000000000000000000000000000000000000..3db07704810eedddef3036e88286150b425dd45d --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/TheOuterScrollScrollsTheEntireLayout.ets @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Scroll中嵌套List,可否设置事件响应顺序,让List不响应滚动事件,让外层的Scroll滚动整个布局? +*/ + +// [Start the_outer_scroll_scrolls_the_entire_layout] +@Component +export struct ScrollNestingList { + build() { + Scroll() { + Column() { + Text('This is the title') + .fontSize(50) + .fontWeight(FontWeight.Bold) + List() { + ForEach(['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], (item: string) => { + ListItem() { + Text(item) + .fontSize(50) + .height(150) + } + }, (item: string) => item) + } + .nestedScroll({ + scrollForward: NestedScrollMode.PARENT_FIRST, + scrollBackward: NestedScrollMode.SELF_FIRST + }) + .divider({ + strokeWidth: 1, + color: Color.Gray + }) + .edgeEffect(EdgeEffect.None) + .height('100%') + .width('100%') + } + } + .width('100%') + .height('100%') + } +} +// [End the_outer_scroll_scrolls_the_entire_layout] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ToggleComponentBlocksClickGestures.ets b/ArkUI/entry/src/main/ets/pages/ToggleComponentBlocksClickGestures.ets new file mode 100644 index 0000000000000000000000000000000000000000..a60952ff8a34e01b46ca6ff0311928a08621177f --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ToggleComponentBlocksClickGestures.ets @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:Toggle组件设置拖动的同时如何屏蔽其本身的点击手势 +*/ + +// [Start toggle_component_blocks_click_gestures] +import { hilog } from '@kit.PerformanceAnalysisKit'; + + +@Entry +@Component +struct ToggleDrag { + @State offsetX: number = 0; + @State offsetY: number = 0; + @State positionX: number = 0; + @State positionY: number = 0; + @State toggleIsOn: boolean = true; + private isDragging: boolean = false; + + + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) { + Toggle({ type: ToggleType.Button, isOn: this.toggleIsOn }) { + Text('Toggle') + } + .selectedColor(Color.Pink) + // Onchange callback precedes onActionEnd + .onChange((isOn: boolean) => { + hilog.info(0x0000, 'testTag', 'xxx %{public}s', `onClick Toggle, isOn: ${isOn}`); + console.info('isDragging======' + this.isDragging); + if (isOn === this.toggleIsOn) { + return; + } else { + this.toggleIsOn = isOn; + } + if (this.isDragging) { + this.toggleIsOn = !this.toggleIsOn; + } + }) + .translate({ x: this.offsetX, y: this.offsetY }) + .gesture( + PanGesture() + .onActionStart(() => { + this.isDragging = true; + }) + .onActionUpdate((event: GestureEvent) => { + this.offsetX = this.positionX + event.offsetX; + this.offsetY = this.positionY + event.offsetY; + }) + .onActionEnd(() => { + this.positionX = this.offsetX; + this.positionY = this.offsetY; + this.isDragging = false; + }) + ) + } + } +} +// [End toggle_component_blocks_click_gestures] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/TopBottomSuctionOfGroupingList.ets b/ArkUI/entry/src/main/ets/pages/TopBottomSuctionOfGroupingList.ets new file mode 100644 index 0000000000000000000000000000000000000000..9820d0c599fd6e1676b26f1507650cc092d4d32d --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/TopBottomSuctionOfGroupingList.ets @@ -0,0 +1,96 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现分组列表的吸顶/吸底效果 +*/ + +// [Start top_bottom_suction_of_grouping_list] +// xxx.ets +@Entry +@Component +struct ListItemGroupExample { + private timeTable: TimeTable[] = [ + { + title: 'Monday', + projects: ['language', 'mathematics', 'English'] + }, + { + title: 'Tuesday', + projects: ['physics', 'chemistry', 'biology'] + }, + { + title: 'Wednesday', + projects: ['history', 'geography', 'politics'] + }, + { + title: 'Thursday', + projects: ['the fine arts', 'music', 'sport'] + } + ] + + @Builder + itemHead(text: string) { + Text(text) + .fontSize(20) + .backgroundColor(0xAABBCC) + .width("100%") + .padding(10) + } + + @Builder + itemFoot(num: number) { + Text('common' + num + "period") + .fontSize(16) + .backgroundColor(0xAABBCC) + .width("100%") + .padding(5) + } + + build() { + Column() { + List({ space: 20 }) { + ForEach(this.timeTable, (item: TimeTable) => { + ListItemGroup({ header: this.itemHead(item.title), footer: this.itemFoot(item.projects.length) }) { + ForEach(item.projects, (project: string) => { + ListItem() { + Text(project) + .width("100%") + .height(100) + .fontSize(20) + .textAlign(TextAlign.Center) + .backgroundColor(0xFFFFFF) + } + }, (item: string) => item) + } + .divider({ strokeWidth: 1, color: Color.Blue }) // The boundary line between each row + }) + } + .width('90%') + .sticky(StickyStyle.Header | StickyStyle.Footer) + .scrollBar(BarState.Off) + } + .width('100%') + .height('100%') + .backgroundColor(0xDCDCDC) + .padding({ top: 5 }) + } +} + +interface TimeTable { + title: string; + projects: string[]; +} +// [End top_bottom_suction_of_grouping_list] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/TouchEventCallsStopPropagation.ets b/ArkUI/entry/src/main/ets/pages/TouchEventCallsStopPropagation.ets new file mode 100644 index 0000000000000000000000000000000000000000..61a571b87b719ec45a0350893347562d573294ce --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/TouchEventCallsStopPropagation.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:触摸事件的TouchEvent调用stopPropagation时无法阻止事件分发 +*/ + +@Component +struct TouchEventDome { + + build() { + // [Start touchEvent_calls_stopPropagation] + Button() { + Button() + .onTouch(xx) + } + .onTouch((event: TouchEvent) => { + // 没有阻止内部的button触发onTouch事件 + event.stopPropagation(); + }) + // [End touchEvent_calls_stopPropagation] + } +} + +function xx(event: TouchEvent): void { + throw new Error('Function not implemented.'); +} \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/TrackComponentData.ets b/ArkUI/entry/src/main/ets/pages/TrackComponentData.ets new file mode 100644 index 0000000000000000000000000000000000000000..8666800aed09e527e3e3cbd1f4ff476d56ce6a52 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/TrackComponentData.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在自定义组件的构建流程里跟踪组件数据或者状态,如在build里增加日志跟踪状态变量等 +*/ + +// [Start track_component_data] +@Component +struct TotalView { + @Prop @Watch('onCountUpdated') count: number = 0; + @State total: number = 0; + // @Watch callback + onCountUpdated(propName: string): void { + this.total += this.count; + } + + build() { + Text(`Total: ${this.total}`) + } +} + +@Entry +@Component +struct CountModifier { + @State count: number = 0; + + build() { + Column() { + Button('add to basket') + .onClick(() => { + this.count++ + }) + TotalView({ count: this.count }) + } + } +} +// [End track_component_data] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/TriggeringApplicationBackendRunningInCode.ets b/ArkUI/entry/src/main/ets/pages/TriggeringApplicationBackendRunningInCode.ets new file mode 100644 index 0000000000000000000000000000000000000000..aa5057be90847bee055ee2a39f924f9d588e41a1 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/TriggeringApplicationBackendRunningInCode.ets @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在代码中触发应用后台运行 +*/ + +// [Start triggering_application_backend_running_in_code] +import { window } from '@kit.ArkUI'; + +@Component +export struct BackgroundExecution { + @State message: string = '后台运行'; + + build() { + Column() { + Button(this.message) + .width('40%') + .onClick(() => { + let windowStage = AppStorage.get('context') as window.WindowStage; + windowStage.getMainWindowSync().minimize(); + }) + } + .height('100%') + .width('100%') + .justifyContent(FlexAlign.Center) + } +} +// [End triggering_application_backend_running_in_code] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/TurnApplicationGrayWithJustOneClick.ets b/ArkUI/entry/src/main/ets/pages/TurnApplicationGrayWithJustOneClick.ets new file mode 100644 index 0000000000000000000000000000000000000000..1e4c49d69c839ecbd271908ada2645c24196efa0 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/TurnApplicationGrayWithJustOneClick.ets @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何使应用一键变灰 +*/ + +// [Start turn_application_gray_with_just_one_click] +@Entry +@Component +struct Index { + @State message: string = 'Hello World' + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + + Image($r("app.media.icon")) + .autoResize(true) + .width(100) + .height(100) + } + } + .width('100%') + .height('100%') + .saturate(0) + } +} +// [End turn_application_gray_with_just_one_click] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/UncheckTheSelectedStatusOfTheText.ets b/ArkUI/entry/src/main/ets/pages/UncheckTheSelectedStatusOfTheText.ets new file mode 100644 index 0000000000000000000000000000000000000000..4837f216ba9475b909e05522bdb9ce145d794ac3 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/UncheckTheSelectedStatusOfTheText.ets @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何在Text组件关闭bindSelection自定义菜单时,取消文本的选中状态 +*/ + +// [Start uncheck_the_selected_status_of_the_text] +@Entry +@Component +struct TextMenuUnchecked { + controller: TextController = new TextController(); + options: TextOptions = { controller: this.controller }; + @State start: number = -1; + @State end: number = -1; + + + build() { + Column() { + Column() { + Text(undefined, this.options) { + Span('Hello World') + ImageSpan($r('app.media.app_icon')) + .width(50) + .height(50) + .objectFit(ImageFit.Fill) + .verticalAlign(ImageSpanAlignment.CENTER) + } + .selection(this.start, this.end) + .copyOption(CopyOptions.InApp) + // Long press to bring up a custom menu + .bindSelectionMenu(TextSpanType.TEXT, this.LongPressImageCustomMenu, TextResponseType.LONG_PRESS, { + onDisappear: () => { + console.info(`Custom selection menu callback when closed`); + }, + onAppear: () => { + console.info(`Callback when custom selection menu pops up`); + } + }) + // When the selected area changes, trigger a callback to update the starting and ending subscripts of the selected area + .onTextSelectionChange((selectionStart: number, selectionEnd: number) => { + this.start = selectionStart; + this.end = selectionEnd; + console.info(`Text selection area change callback, selectionStart: ${selectionStart}, selectionEnd: ${selectionEnd}`); + }) + .borderWidth(1) + .borderColor(Color.Red) + .width(200) + .height(100) + } + .width('100%') + .backgroundColor(Color.White) + .alignItems(HorizontalAlign.Start) + .padding(25) + } + .height('100%') + } + + + @Builder + LongPressImageCustomMenu() { + Column() { + Menu() { + MenuItemGroup() { + MenuItem({ + startIcon: $r('app.media.app_icon'), + content: 'Right Click Menu 1', + labelInfo: '' + }) + .onClick(() => { //When clicking on the custom menu, reset the starting and ending subscripts of the selected area + this.start = -1; + this.end = -1; + this.controller.closeSelectionMenu(); + }) + MenuItem({ startIcon: $r('app.media.app_icon'), content: 'Select Mixed Menu 2', labelInfo: '' }) + MenuItem({ startIcon: $r('app.media.app_icon'), content: 'Select Mixed Menu 3', labelInfo: '' }) + } + } + .radius($r('sys.float.ohos_id_corner_radius_card')) + .clip(true) + .backgroundColor('#F0F0F0') + } + } +} +// [End uncheck_the_selected_status_of_the_text] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/UnderstandTheAspectRatioLayout.ets b/ArkUI/entry/src/main/ets/pages/UnderstandTheAspectRatioLayout.ets new file mode 100644 index 0000000000000000000000000000000000000000..e2d9ff6b6b6f033a3b58a4fb9e65855aa1206a08 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/UnderstandTheAspectRatioLayout.ets @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何理解AspectRatio对布局的影响 +*/ + +// [Start understand_the_aspect_ratio_layout] +@Entry +@Component +struct VideoAdaptPage { + build() { + Column() { + Column() { + Video({}) + .layoutWeight(1) + .borderRadius(12) + .clip(true) + .aspectRatio(1) + .loop(true) + .autoPlay(true) + .muted(true) + .margin({ + left: 20, + top: 20, + right: 20, + }) + } + }.height(2000) + } +} +// [End understand_the_aspect_ratio_layout] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/UseSwiperDropdownToRefresh.ets b/ArkUI/entry/src/main/ets/pages/UseSwiperDropdownToRefresh.ets new file mode 100644 index 0000000000000000000000000000000000000000..a1953b2d0e3b6e534f84c277e87b319dc978a441 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/UseSwiperDropdownToRefresh.ets @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何使用Swiper组件实现下拉刷新 +*/ + +// [Start use_swiper_dropdown_to_refresh] +@Entry +@Component +struct SwiperItemLeak { + @State isStopSwiperSlide: boolean = false; + @State positionY: number = 0; + private swiperController: SwiperController = new SwiperController(); + @State curSwiperIndex: number = 0; + private list: number[] = []; + + aboutToAppear(): void { + for (let i = 1; i <= 10; i++) { + this.list.push(i); + } + } + + build() { + Refresh({ refreshing: $$this.isStopSwiperSlide}) { + Swiper(this.swiperController) { + ForEach(this.list, (item: number) => { + Text(item.toString()) + .width('100%') + .height('100%') + .backgroundColor(0xAFEEEE * ((item + 1) / 0x0f)) + .textAlign(TextAlign.Center) + .fontSize(30) + },(item: number) => JSON.stringify(item)) + } + .vertical(true) + .width('100%') + .height('100%') + .cachedCount(3) + .index(0) + .autoPlay(false) + .indicator(false) + .effectMode(EdgeEffect.None) + .loop(false) + .duration(100) + .disableSwipe(this.isStopSwiperSlide) + .displayCount(1) + .itemSpace(0) + .curve(Curve.Linear) + .backgroundColor(Color.Red) + .position({ y: this.positionY }) + .onChange((index: number) => { + this.curSwiperIndex = index; + }) + } + .onRefreshing(() => { + setTimeout(() => { + this.isStopSwiperSlide = false + }, 2000) + }) + .backgroundColor(0x89CFF0) + .refreshOffset(64) + .pullToRefresh(true) + .width('100%') + .height('100%') + } +} +// [End use_swiper_dropdown_to_refresh] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/UsingIconfont.ets b/ArkUI/entry/src/main/ets/pages/UsingIconfont.ets new file mode 100644 index 0000000000000000000000000000000000000000..8d9b43efb6a8fc51072c96a533bf52456348f5ca --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/UsingIconfont.ets @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何使用iconfont +*/ + +// [Start using_iconfont] +import { Font } from '@kit.ArkUI' +@Entry +@Component +struct UseIconFont { + // Assuming 0000 is the Unicode for the specified icon, developers actually need to obtain Unicode from the ttf file of the registered iconFont + @State unicode: string = '\u0000'; + aboutToAppear(): void { + let font: Font = this.getUIContext().getFont(); + font.registerFont({ + familyName: 'iconfont', + familySrc: 'xxx.ttf' + }) + } + build() { + Row() { + Column() { + Text(this.unicode) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .fontFamily('iconfont') + } + .width('100%') + } + .height('100%') + } +} +// [End using_iconfont] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/VerticalArrangementOfText.ets b/ArkUI/entry/src/main/ets/pages/VerticalArrangementOfText.ets new file mode 100644 index 0000000000000000000000000000000000000000..1aa74e58b58799338e9cb197436565032fabf46e --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/VerticalArrangementOfText.ets @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现文本竖向排列 +*/ + +// [Start vertical_arrangement_of_text] +@Entry +@Component +struct Index { + private message: string = 'This document is suitable for beginners in application development. By building a simple application with page jump/return function, quickly understand the main files of the project directory and familiarize yourself with the application development process.'; + build() { + Column() { + Text(this.message) + .fontSize(13) + .width(13) + } + } +} +// [End vertical_arrangement_of_text] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/ViewRangeOfTouchHotspots.ets b/ArkUI/entry/src/main/ets/pages/ViewRangeOfTouchHotspots.ets new file mode 100644 index 0000000000000000000000000000000000000000..af56edad8fb79e7e467813f2e61bd8b55c57f336 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/ViewRangeOfTouchHotspots.ets @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何查看触摸热区范围 +*/ + +// [Start view_range_of_touch_hotspots] +@Entry +@Component +struct TouchTargetExample { + @State text: string = ''; + @State x: number = 0; + @State y: number = 0; + @State reg_width: string = '50%'; + @State reg_height: string = '100%'; + + + build() { + Column({ space: 20 }) { + Text(`{x:0,y:0,width:'50%',height:'100%'}`) + // The width of the hot zone is half of the button, and there is no response when clicking on the right side + Button('button1') + .responseRegion({ + x: this.x, + y: this.y, + width: this.reg_width, + height: this.reg_height + }) + .onClick(() => { + this.text = 'button1 clicked'; + console.info('button1 clicked: ' + this.x + ' ' + this.y + ' ' + this.reg_width + ' ' + this.reg_height); + }) + + + Text(this.text) + .margin({ top: 10 }) + } + .width('100%') + .margin({ top: 100 }) + } +} +// [End view_range_of_touch_hotspots] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/WidthNotExceedingTheParentComponent.ets b/ArkUI/entry/src/main/ets/pages/WidthNotExceedingTheParentComponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..b949246734b64cd2c5c9a9cb30093bcd15c8266f --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/WidthNotExceedingTheParentComponent.ets @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何设置子组件宽度使其不超过父组件的大小 +*/ + +// [Start width_not_exceeding_the_parent_component] +@Entry +@Component +struct SizeExample { + @State flag:boolean = true; + + build() { + Row() { + Text(this.flag ? 'Followed by' : 'Not following') + .fontSize(20) + .fontWeight(FontWeight.Bold) + .backgroundColor(0xFFFAF0) + .textAlign(TextAlign.Center) + .margin( 10) + .size({ width: this.flag ? 60 : 80 }) + .onClick(()=>{ + this.flag = !this.flag + }) + Text('HarmonyOS Developer Community') + .fontSize(20) + .fontWeight(FontWeight.Bold) + .backgroundColor(0xFFFAF0) + .size({width: this.flag ? 'calc(100% - 60vp)' : 'calc(100% - 80vp)'}) + }.width(500).margin({ top: 5 }) + } +} +// [End width_not_exceeding_the_parent_component] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/pages/attributeModifier.ets b/ArkUI/entry/src/main/ets/pages/attributeModifier.ets new file mode 100644 index 0000000000000000000000000000000000000000..2973eb5910ff30508845ba39096560bb07114a51 --- /dev/null +++ b/ArkUI/entry/src/main/ets/pages/attributeModifier.ets @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何获取UI组件的显示或隐藏状态 +*/ + +// [Start implement_cross_file_style_reuse_one] +/* + Customize class to implement AttributeModifier interface for Text +*/ +export class CommodityText implements AttributeModifier { + textType: TextType = TextType.TYPE_ONE; + textSize: number = 15; + + constructor( textType: TextType, textSize: number) { + this.textType = textType; + this.textSize = textSize; + } + + applyNormalAttribute(instance: TextAttribute): void { + if (this.textType === TextType.TYPE_ONE) { + instance.fontSize(this.textSize); + instance.fontColor(Color.Orange); + instance.fontWeight(FontWeight.Bolder); + instance.width(200); + } else if (this.textType === TextType.TYPE_TWO) { + instance.fontSize(this.textSize); + instance.fontWeight(FontWeight.Bold); + instance.fontColor(Color.Blue); + instance.width(200); + } else if (this.textType === TextType.TYPE_Three) { + instance.fontColor(Color.Gray); + instance.fontSize(this.textSize); + instance.fontWeight(FontWeight.Normal); + instance.width(200); + } else if (this.textType === TextType.TYPE_FOUR) { + instance.fontSize(this.textSize); + instance.fontColor(Color.Orange); + instance.textAlign(TextAlign.Center); + instance.border({ width: 1, color: Color.Orange, style: BorderStyle.Solid }); + instance.margin({ right: 10 }); + } + } +} +/* + 枚举文本类型 +*/ +export enum TextType { + TYPE_ONE, + TYPE_TWO, + TYPE_Three, + TYPE_FOUR +} +// [End implement_cross_file_style_reuse_one] \ No newline at end of file diff --git a/ArkUI/entry/src/main/ets/viewmodel/CommonDataSource.ets b/ArkUI/entry/src/main/ets/viewmodel/CommonDataSource.ets new file mode 100644 index 0000000000000000000000000000000000000000..10a9010e3a64ae2d6322cd29ba893e5ccc0cc840 --- /dev/null +++ b/ArkUI/entry/src/main/ets/viewmodel/CommonDataSource.ets @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:如何实现列表既可以左右滑、又可以上下滑动 +*/ + +// [Start slide_the_list_left_right_up_and_down_two] +export class CommonDataSource implements IDataSource { + private listeners: DataChangeListener[] = []; + protected originDataArray: T[] = []; + + + totalCount(): number { + return this.originDataArray.length; + } + + + getAllData(): T[] { + return this.originDataArray; + } + + + getData(index: number) { + return this.originDataArray[index]; + } + + + addData(index: number, data: T): void { + this.originDataArray.splice(index, 0, data); + this.notifyDataAdd(index); + } + + + pushData(data: T): void { + this.originDataArray.push(data); + this.notifyDataAdd(this.originDataArray.length - 1); + } + + + pushDataArray(...items: T[]): void { + for (let data of items) { + this.originDataArray.push(data); + this.notifyDataAdd(this.originDataArray.length - 1); + } + } + + + clear() { + this.originDataArray.splice(0, this.originDataArray.length) + this.listeners.forEach(listener => { + listener.onDataDelete(0); + }) + } + + + setData(dataArray?: T[]) { + if (dataArray) { + this.originDataArray = dataArray; + } else { + this.originDataArray = []; + } + this.notifyDataReload(); + } + + + registerDataChangeListener(listener: DataChangeListener): void { + if (this.listeners.indexOf(listener) < 0) { + this.listeners.push(listener); + } + } + + + unregisterDataChangeListener(listener: DataChangeListener): void { + const pos = this.listeners.indexOf(listener); + if (pos >= 0) { + this.listeners.splice(pos, 1); + } + } + + + notifyDataReload() { + this.listeners.forEach(listener => { + listener.onDataReloaded(); + }) + } + + + notifyDataAdd(index: number) { + this.listeners.forEach(listener => { + listener.onDataAdd(index); + }) + } + + + notifyDataMove(from: number, to: number) { + this.listeners.forEach(listener => { + listener.onDataMove(from, to); + }) + } + + + notifyDataDelete(index: number) { + this.listeners.forEach(listener => { + listener.onDataDelete(index); + }) + } + + + notifyDataChange(index: number) { + this.listeners.forEach(listener => { + listener.onDataChange(index); + }) + } +} +// [End slide_the_list_left_right_up_and_down_two] \ No newline at end of file diff --git a/ArkUI/entry/src/main/resources/base/element/color.json b/ArkUI/entry/src/main/resources/base/element/color.json index a4a39f5fd96561697195e2fca6b6396d36db6eb7..60baa6018f95f33a3328dcd3e9927aee99e46ae7 100644 --- a/ArkUI/entry/src/main/resources/base/element/color.json +++ b/ArkUI/entry/src/main/resources/base/element/color.json @@ -7,6 +7,10 @@ { "name": "xxx", "value": "#FFFFFF" + }, + { + "name": "status_bar", + "value": "#FFFFFF" } ] } \ No newline at end of file diff --git a/ArkUI/entry/src/main/resources/base/element/string.json b/ArkUI/entry/src/main/resources/base/element/string.json index f94595515a99e0c828807e243494f57f09251930..32fd12426f68627a56cf140c4a65ba5c75390a86 100644 --- a/ArkUI/entry/src/main/resources/base/element/string.json +++ b/ArkUI/entry/src/main/resources/base/element/string.json @@ -11,6 +11,10 @@ { "name": "EntryAbility_label", "value": "label" + }, + { + "name": "EntryAbility1_label2", + "value": "" } ] } \ No newline at end of file diff --git a/ArkUI/entry/src/main/resources/base/media/app_icon.png b/ArkUI/entry/src/main/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/ArkUI/entry/src/main/resources/base/media/app_icon.png differ diff --git a/ArkUI/entry/src/main/resources/base/media/ic_banner01.png b/ArkUI/entry/src/main/resources/base/media/ic_banner01.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/ArkUI/entry/src/main/resources/base/media/ic_banner01.png differ diff --git a/ArkUI/entry/src/main/resources/base/media/ic_banner02.png b/ArkUI/entry/src/main/resources/base/media/ic_banner02.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/ArkUI/entry/src/main/resources/base/media/ic_banner02.png differ diff --git a/ArkUI/entry/src/main/resources/base/media/icon.png b/ArkUI/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/ArkUI/entry/src/main/resources/base/media/icon.png differ diff --git a/ArkUI/entry/src/main/resources/base/media/refreshing.png b/ArkUI/entry/src/main/resources/base/media/refreshing.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/ArkUI/entry/src/main/resources/base/media/refreshing.png differ diff --git a/ArkUI/entry/src/main/resources/base/media/xxx.png b/ArkUI/entry/src/main/resources/base/media/xxx.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/ArkUI/entry/src/main/resources/base/media/xxx.png differ diff --git a/ArkUI/entry/src/main/resources/en_US/element/string.json b/ArkUI/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..bb8992fc161d11ecf08130fdfed106d503c33cd5 --- /dev/null +++ b/ArkUI/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:ArkUI组件的字符串中如何实现字符串变量拼接 +*/ + +// [Start implementing_string_variable_concatenation_three] +{ + "string": [ + { + "name": "module_desc", + "value": "module description%d" + }, + { + "name": "EntryAbility_desc", + "value": "description%d" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} +// [End implementing_string_variable_concatenation_three] \ No newline at end of file diff --git a/ArkUI/entry/src/main/resources/rawfile/xxx.mp4 b/ArkUI/entry/src/main/resources/rawfile/xxx.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ArkUI/entry/src/main/resources/zh_CN/element/string.json b/ArkUI/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..5d385d52dc45b9e30c7efbf7184e2d8ca40aae29 --- /dev/null +++ b/ArkUI/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2024 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. +*/ + +/* +* FAQ:ArkUI组件的字符串中如何实现字符串变量拼接 +*/ + +// [Start implementing_string_variable_concatenation_two] +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述%d" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} +// [Start implementing_string_variable_concatenation_two] \ No newline at end of file