diff --git a/ComponentReuse/README.md b/ComponentReuse/README.md index b523843fee6d42ce690f3e59633551c824b4e1cd..5206576ec74491b165c090af6c0e69fd83b3b0cc 100644 --- a/ComponentReuse/README.md +++ b/ComponentReuse/README.md @@ -28,7 +28,6 @@ HarmonyOS应用框架提供了组件复用能力:可复用组件树上移除 ``` ├──entry/src/main/ets │ ├──common -│ │ ├──CommonConstants.ets // 组件复用DataSource类 │ │ ├──Constants.ets // 公共常量 │ │ └──GlobalBuilderContext.ets // 缓存全局@Builder │ ├──entryability @@ -38,12 +37,11 @@ HarmonyOS应用框架提供了组件复用能力:可复用组件树上移除 │ ├──model │ │ ├──BasicDataSource.ets // 数据适配器基类 │ │ ├──ColorData.ets // 二级页面“文字列表”的数据适配器 -│ │ └──FriendMomentData.ets // 二级页面“附近的人”/“图文列表”/“网名列表”的数据适配器 +│ │ ├──FriendMomentData.ets // 二级页面“附近的人”/“图文列表”/“网名列表”的数据适配器 +│ │ ├──ItemData.ets // 组件复用问题诊断分析场景的数据类 +│ │ └──ItemDataSource.ets // 组件复用问题诊断分析场景的数据适配器 │ ├──pages.ets -│ │ ├──ImproveReuseHitRate.ets // 提升复用命中率 -│ │ ├──Index.ets // 首页 -│ │ ├──ReuseNested.ets // 复用嵌套 -│ │ └──UseComponentReuse.ets // 使用组件复用 +│ │ └──Index.ets // 首页 │ └──view │ ├──OneMoment.ets // 二级页面“附近的人”中列表的每条item UI │ ├──PageListSlideToHistory.ets // 二级页面“附近的人”UI diff --git a/ComponentReuse/README_EN.md b/ComponentReuse/README_EN.md index 07403082a46f32b66022be100a116409e8242f3e..525d3591124da1bd6ba5a1544e173bd542edeabf 100644 --- a/ComponentReuse/README_EN.md +++ b/ComponentReuse/README_EN.md @@ -2,33 +2,38 @@ ### Overview -The HarmonyOS application framework provides the component reuse capability. When a reusable component is removed from the component tree, it enters a recycling buffer. When a new component node is created, the node in the buffer is reused, saving the time for recreating the component. -This sample is used with the [Best Practices for Component Reuse](https://developer.huawei.com/consumer/en/doc/best-practices/bpta-component-reuse). +The HarmonyOS application framework provides the component reuse capability. When a reusable component is removed from +the component tree, it enters a recycling buffer. When a new component node is created, the node in the buffer is +reused, saving the time for recreating the component. +This sample is used with +the [Best Practices for Component Reuse](https://developer.huawei.com/consumer/en/doc/best-practices/bpta-component-reuse). The practices describe how to use the component reuse mechanism to improve the application frame rate. ### Preview -| Reducing Component Reuse Nesting | Precisely Controlling the Component Update Scope | -|-----------------------------------------|-----------------------------------------| -| ![image](screenshots/device/mode_1_EN.gif)| ![image](screenshots/device/mode_2_EN.gif)| +| Reducing Component Reuse Nesting | Precisely Controlling the Component Update Scope | +|--------------------------------------------|--------------------------------------------------| +| ![image](screenshots/device/mode_1_EN.gif) | ![image](screenshots/device/mode_2_EN.gif) | -| Using reuseId to Mark Different Components | Using @State as Input Parameter for Reusable Components | -|-----------------------------------------|-----------------------------------------| -| ![image](screenshots/device/mode_3_EN.gif)| ![image](screenshots/device/mode_4_EN.gif)| +| Using reuseId to Mark Different Components | Using @State as Input Parameter for Reusable Components | +|--------------------------------------------|---------------------------------------------------------| +| ![image](screenshots/device/mode_3_EN.gif) | ![image](screenshots/device/mode_4_EN.gif) | #### How to Use 1. Tap **Reducing component reuse nesting** to enter **Nearby people** on the level-2 page, and slide the list. -2. Tap **Precisely controlling the component update scope** to enter **Text list** on the level-2 page, and slide the list. -3. Tap **Using reuseId to mark different components** to enter **Image-text list** on the level-2 page, and slide the list. -4. Tap **Using @State as input parameter for reusable components** to enter **Username list** on the level-2 page, and slide the list. +2. Tap **Precisely controlling the component update scope** to enter **Text list** on the level-2 page, and slide the + list. +3. Tap **Using reuseId to mark different components** to enter **Image-text list** on the level-2 page, and slide the + list. +4. Tap **Using @State as input parameter for reusable components** to enter **Username list** on the level-2 page, and + slide the list. ## Project Directory ``` ├──entry/src/main/ets │ ├──common -│ │ ├──CommonConstants.ets // Component reuse DataSource class │ │ ├──Constants.ets // Common constants │ │ └──GlobalBuilderContext.ets // Caching the global @Builder │ ├──entryability @@ -38,12 +43,11 @@ The practices describe how to use the component reuse mechanism to improve the a │ ├──model │ │ ├──BasicDataSource.ets // Basic data adapter │ │ ├──ColorData.ets // Data adapter of Text list on the level-2 page -│ │ └──FriendMomentData.ets // Data adapter of Nearby people, Image-text list, and Username list on the level-2 page +│ │ ├──FriendMomentData.ets // Data adapter of Nearby people, Image-text list, and Username list on the level-2 page +│ │ ├──ItemData.ets // Data classes for diagnosing and analyzing component reuse issues in scenarios +│ │ └──ItemDataSource.ets // Data adapter for diagnosing and analyzing component reuse issues in scenarios │ ├──pages.ets -│ │ ├──ImproveReuseHitRate.ets // Improve reuse HitRate -│ │ ├──Index.ets // Home page -│ │ ├──ReuseNested.ets // Reuse nested -│ │ └──UseComponentReuse.ets // Use component reuse +│ │ └──Index.ets // Home page │ └──view │ ├──OneMoment.ets // Each item UI in Nearby people on the level-2 page │ ├──PageListSlideToHistory.ets // Nearby people UI on the level-2 page diff --git a/ComponentReuse/entry/src/main/ets/pages/UseComponentReuse.ets b/ComponentReuse/entry/src/main/ets/model/ItemData.ets similarity index 59% rename from ComponentReuse/entry/src/main/ets/pages/UseComponentReuse.ets rename to ComponentReuse/entry/src/main/ets/model/ItemData.ets index 4b27fb5a926436d6b0746fe09796d8b9b8d85953..313d871f343d0f3ab383041b8f3f0807af9a6da6 100644 --- a/ComponentReuse/entry/src/main/ets/pages/UseComponentReuse.ets +++ b/ComponentReuse/entry/src/main/ets/model/ItemData.ets @@ -13,25 +13,21 @@ * limitations under the License. */ -// [Start ReusableComponent] -// Add Reusable decorator. -@Reusable -@Component -struct ReusableComponent { - @State item: string = ''; +@Observed +export class ItemData { + id: string = ''; + title: string | Resource = ''; + content: string = ''; + from: string | Resource = ''; + tail: string | Resource = ''; + type: number = 0; + pics: Resource[] = []; + preview: Resource | string = ''; + duration: string = ''; + isShowTitle?: Visibility = Visibility.Hidden; - aboutToReuse(params: ESObject): void { - this.item = params.item; // Trigger the aboutToReuse lifecycle callback. + constructor(id: string, type: number) { + this.id = id; + this.type = type; } - - build() { - ListItem() { - Row() { - Text(this.item).fontSize(50) - } - .margin({ left: 10, right: 10 }) - } - } -} - -// [Start ReusableComponent] \ No newline at end of file +} \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/common/CommonConstants.ets b/ComponentReuse/entry/src/main/ets/model/ItemDataSource.ets similarity index 58% rename from ComponentReuse/entry/src/main/ets/common/CommonConstants.ets rename to ComponentReuse/entry/src/main/ets/model/ItemDataSource.ets index 4911674398955fc013125cacace2d590a7bca178..0056109375c97c16fa7075b877c94013a6d7fa4a 100644 --- a/ComponentReuse/entry/src/main/ets/common/CommonConstants.ets +++ b/ComponentReuse/entry/src/main/ets/model/ItemDataSource.ets @@ -12,23 +12,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { cloudStorage } from '@kit.CloudFoundationKit'; -class BasicDataSource implements IDataSource { +import { ItemData } from './ItemData'; + +export class ItemDataSource implements IDataSource { private listeners: DataChangeListener[] = []; - private originDataArray: string[] = []; + private originDataArray: ItemData[] = []; public totalCount(): number { return this.originDataArray.length; } - public getData(index: number): string { + public getData(index: number): ItemData { return this.originDataArray[index]; } registerDataChangeListener(listener: DataChangeListener): void { if (this.listeners.indexOf(listener) < 0) { - console.info('add listener'); this.listeners.push(listener); } } @@ -36,7 +36,6 @@ class BasicDataSource implements IDataSource { unregisterDataChangeListener(listener: DataChangeListener): void { const pos = this.listeners.indexOf(listener); if (pos >= 0) { - console.info('remove listener'); this.listeners.splice(pos, 1); } } @@ -44,53 +43,82 @@ class BasicDataSource implements IDataSource { notifyDataReload(): void { this.listeners.forEach(listener => { listener.onDataReloaded(); - }) + }); } notifyDataAdd(index: number): void { this.listeners.forEach(listener => { listener.onDataAdd(index); - }) + }); } notifyDataChange(index: number): void { this.listeners.forEach(listener => { listener.onDataChange(index); - }) + }); } notifyDataDelete(index: number): void { this.listeners.forEach(listener => { listener.onDataDelete(index); - }) + }); } notifyDataMove(from: number, to: number): void { this.listeners.forEach(listener => { listener.onDataMove(from, to); - }) + }); } notifyDatasetChange(operations: DataOperation[]): void { this.listeners.forEach(listener => { listener.onDatasetChange(operations); - }) + }); } -} -export class MyDataSource extends BasicDataSource { - private dataArray: string[] = []; + public pushArray(newData: ItemData[]): void { + this.originDataArray.push(...newData); + this.notifyDataReload(); + } - public totalCount(): number { - return this.dataArray.length; + public addItems(items: ItemData[]) { + this.originDataArray.push(...items); + this.notifyDataReload(); + } + + public add1stItem(item: ItemData): void { + this.originDataArray.splice(0, 0, item); + this.notifyDataAdd(0); + } + + public addLastItem(item: ItemData): void { + this.originDataArray.splice(this.originDataArray.length, 0, item); + this.notifyDataAdd(this.originDataArray.length - 1); + } + + public addItem(index: number, item: ItemData): void { + this.originDataArray.splice(index, 0, item); + this.notifyDataAdd(index); + } + + public delete1stItem(): void { + this.originDataArray.splice(0, 1); + this.notifyDataDelete(0); + } + + public delete2ndItem(): void { + this.originDataArray.splice(1, 1); + this.notifyDataDelete(1); } - public getData(index: number): string { - return this.dataArray[index]; + public deleteLastItem(): void { + this.originDataArray.splice(-1, 1); + this.notifyDataDelete(this.originDataArray.length); } - public pushData(data: string): void { - this.dataArray.push(data); - this.notifyDataAdd(this.dataArray.length - 1); + public reload() { + this.originDataArray.splice(1, 1); + this.originDataArray.splice(3, 2); + this.reload(); } } \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/pages/ImproveReuseHitRate.ets b/ComponentReuse/entry/src/main/ets/pages/ImproveReuseHitRate.ets deleted file mode 100644 index 5ce51b8be6a89cb507409a84252111d477fd6fbd..0000000000000000000000000000000000000000 --- a/ComponentReuse/entry/src/main/ets/pages/ImproveReuseHitRate.ets +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// [Start ImproveReuseHitRate] -import { MyDataSource } from '../common/CommonConstants'; - -@Observed -class Class1 { - public typeValue: string = ''; - public id: string = ''; -} - -@Entry -@Component -struct ImproveReuseHitRate { - private data: MyDataSource = new MyDataSource(); - - aboutToAppear(): void { - // Init Data. - } - - build() { - List({ space: 3 }) { - LazyForEach(this.data, (item: Class1) => { - ReusableComponent({ value1: item }).reuseId(item.typeValue) - }, (item: Class1) => item.id) - }.cachedCount(5) - } -} - -@Reusable -@Component -struct ReusableComponent { - @ObjectLink value1: Class1; - - aboutToAppear(): void { - // Do some init. - } - - build() { - ListItem() { - ContentBuilder({ value1: this.value1 }) - } - } -} - -interface ContentParamType { - value1: Class1 -} - -@Builder -function ContentBuilder($$: ContentParamType) { - if ($$.value1.typeValue === 'A') { - // BuildTypeA - } else if ($$.value1.typeValue === 'C') { - // BuildTypeC - } else if ($$.value1.typeValue === 'D') { - // BuildTypeD - } else if ($$.value1.typeValue === 'E') { - // BuildTypeE - } else if ($$.value1.typeValue === 'F') { - // BuildTypeF - } else if ($$.value1.typeValue === 'G') { - // BuildTypeG - } else if ($$.value1.typeValue === 'H') { - // BuildTypeH - } else if ($$.value1.typeValue === 'I') { - // BuildTypeI - } else if ($$.value1.typeValue === 'J') { - // BuildTypeJ - } else if ($$.value1.typeValue === 'K') { - // BuildTypeK - } -} - -@Builder -function TypeA($$: ContentParamType) { - - Column() { - Title() - .visibility(Visibility.Visible) // Control the display or concealment of components. - Row() { - Column() { - Image($r('app.media.startIcon')) - Text() - Text() - Text() - } - } - } -} - -@Builder -function TypeC($$: ContentParamType) { - Column() { - Title() - Grid() { - // ... - } - } -} - - -@Component -struct Title { - build() { - Column() { - Text('title') - } - } -} - -// [End ImproveReuseHitRate] - - diff --git a/ComponentReuse/entry/src/main/ets/pages/ReuseNested.ets b/ComponentReuse/entry/src/main/ets/pages/ReuseNested.ets deleted file mode 100644 index 69f1d63f6a563908a6ce56c467c4eb1a1efb45ba..0000000000000000000000000000000000000000 --- a/ComponentReuse/entry/src/main/ets/pages/ReuseNested.ets +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// [Start ReuseNested] -import { MyDataSource } from '../common/CommonConstants'; - -@Entry -@Component -struct ReuseNested { - private data: MyDataSource = new MyDataSource(); - - aboutToAppear(): void { - for (let i = 0; i < 1000; i++) { - this.data.pushData(i.toString()); - } - } - - build() { - List({ space: 40 }) { - LazyForEach(this.data, (item: string, index: number) => { - ListItem() { - if (index % 3 === 0) { - ReusableComponentOne({ item: item }) - } else if (index % 5 === 0) { - ReusableComponentTwo({ item: item }) - } else { - ReusableComponentThree({ item: item }) - } - } - .backgroundColor('#cccccc') - .width('100%') - .onAppear(() => { - console.info(`ListItem ${index} onAppear`); - }) - }) - } - .width('100%') - .height('100%') - .cachedCount(0) - } -} - -@Builder -function ReusableComponentOne($$: ESObject) { - Column() { - ChildComponentA({ item: $$.item }) - ChildComponentB({ item: $$.item }) - ChildComponentC({ item: $$.item }) - } -} - -@Builder -function ReusableComponentTwo($$: ESObject) { - Column() { - ChildComponentA({ item: $$.item }) - ChildComponentC({ item: $$.item }) - ChildComponentD({ item: $$.item }) - } -} - -@Builder -function ReusableComponentThree($$: ESObject) { - Column() { - ChildComponentA({ item: $$.item }) - ChildComponentB({ item: $$.item }) - ChildComponentD({ item: $$.item }) - } -} - -@Reusable -@Component -struct ChildComponentA { - @State item: string = ''; - - aboutToReuse(params: ESObject): void { - console.info(`ChildComponentA ${params.item} Reuse ${this.item}`); - this.item = params.item; - } - - aboutToRecycle(): void { - console.info(`ChildComponentA ${this.item} Recycle`); - } - - build() { - Column() { - Text(`Item ${this.item} Child Component A`) - .fontSize(20) - .margin({ left: 10 }) - .fontColor(Color.Blue) - Grid() { - ForEach((new Array(20)).fill(''), (item: string, index: number) => { - GridItem() { - Image($r('app.media.startIcon')) - .height(20) - } - }) - - } - } - .margin({ left: 10, right: 10 }) - .backgroundColor(0xFAEEE0) - } -} - -@Reusable -@Component -struct ChildComponentB { - @State item: string = ''; - - aboutToReuse(params: ESObject): void { - this.item = params.item; - } - - build() { - Row() { - Text(`Item ${this.item} Child Component B`) - .fontSize(20) - .margin({ left: 10 }) - .fontColor(Color.Red) - } - .margin({ left: 10, right: 10 }) - } -} - -@Reusable -@Component -struct ChildComponentC { - @State item: string = ''; - - aboutToReuse(params: ESObject): void { - this.item = params.item; - } - - build() { - Row() { - Text(`Item ${this.item} Child Component C`) - .fontSize(20) - .margin({ left: 10 }) - .fontColor(Color.Green) - } - .margin({ left: 10, right: 10 }) - } -} - -@Reusable -@Component -struct ChildComponentD { - @State item: string = ''; - - aboutToReuse(params: ESObject): void { - this.item = params.item; - } - - build() { - Row() { - Text(`Item ${this.item} Child Component D`) - .fontSize(20) - .margin({ left: 10 }) - .fontColor(Color.Orange) - } - .margin({ left: 10, right: 10 }) - } -} - -// [End ReuseNested] diff --git a/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneOnePositiveExample.ets b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneOnePositiveExample.ets new file mode 100644 index 0000000000000000000000000000000000000000..56596d9e5ff91ac152ca7e3adc6710bb4c5c282a --- /dev/null +++ b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneOnePositiveExample.ets @@ -0,0 +1,86 @@ +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; + +@Entry +@Component +struct NoComponentReuseSceneOnePositiveExample { + private dataSource: ItemDataSource = new ItemDataSource(); + + build() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }) + } + }, (item: ItemData) => item.id.toString()) + } + } + } +} + +// [Start NoComponentReuseSceneOnePositiveExample] +@Reusable +@Component +struct NewsContent { + // [StartExclude NoComponentReuseSceneOnePositiveExample] + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + + // ... + } + + // [EndExclude NoComponentReuseSceneOnePositiveExample] +} + +// [End NoComponentReuseSceneOnePositiveExample] + +// [Start ComponentReuseImproperUseSceneTwoPositiveExample] +@Component +struct TopView { + // [StartExclude ComponentReuseImproperUseSceneTwoPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude ComponentReuseImproperUseSceneTwoPositiveExample] +} + +@Component +struct BottomView { + // [StartExclude ComponentReuseImproperUseSceneTwoPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude ComponentReuseImproperUseSceneTwoPositiveExample] +} + +@Component +struct MiddleSingleImageView { + // [StartExclude ComponentReuseImproperUseSceneTwoPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude ComponentReuseImproperUseSceneTwoPositiveExample] +} + +// [End ComponentReuseImproperUseSceneTwoPositiveExample] \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneThreePositiveExample.ets b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneThreePositiveExample.ets new file mode 100644 index 0000000000000000000000000000000000000000..10b5b5bf45896addd454fdfd06b24eb775b90d90 --- /dev/null +++ b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneThreePositiveExample.ets @@ -0,0 +1,121 @@ +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; + +@Entry +@Component +struct NoComponentReuseSceneThreePositiveExample { + private dataSource: ItemDataSource = new ItemDataSource(); + + @Builder + itemBuilderSingleImage(item: ItemData) { + Column() { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + } + + @Builder + itemBuilderThreeImage(item: ItemData) { + Column() { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + } + + @Builder + itemBuilderVideo(item: ItemData) { + Column() { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + } + + build() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + if (item.type === 0) { + this.itemBuilderSingleImage(item) + } else if (item.type === 1) { + this.itemBuilderThreeImage(item) + } else { + this.itemBuilderVideo(item) + } + } + }, (item: ItemData) => item.id.toString()) + } + } + } +} + +// [Start NoComponentReuseSceneTwoSubPositiveExample] +@Reusable +@Component +struct TopView { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +@Reusable +@Component +struct BottomView { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +@Reusable +@Component +struct MiddleSingleImageView { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +@Reusable +@Component +struct MiddleThreeImageView { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +@Reusable +@Component +struct MiddleVideoView { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + build() { + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +// [End NoComponentReuseSceneTwoSubPositiveExample] \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneTwoPositiveExample.ets b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneTwoPositiveExample.ets new file mode 100644 index 0000000000000000000000000000000000000000..71d7554eab96423346d32660d1cf60cabd2793ef --- /dev/null +++ b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneTwoPositiveExample.ets @@ -0,0 +1,101 @@ +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; + +@Entry +@Component +struct NoComponentReuseSceneTwoPositiveExample { + private dataSource: ItemDataSource = new ItemDataSource(); + + build() { + Column() { + // [Start NoComponentReuseSceneTwoPositiveExample01] + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }).reuseId(`${item.type}`) + } + }, (item: ItemData) => item.id.toString()) + } + + // [Start NoComponentReuseSceneTwoPositiveExample01] + } + } +} + +// [Start NoComponentReuseSceneTwoPositiveExample02] +@Reusable +@Component +struct NewsContent { + // [StartExclude NoComponentReuseSceneTwoPositiveExample02] + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + if (item.type === 0) { + MiddleSingleImageView({ item: item }) + } else if (item.type === 1) { + MiddleThreeImageView({ item: item }) + } else { + MiddleVideoView({ item: item }) + } + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + + // ... + } + + // [EndExclude NoComponentReuseSceneTwoPositiveExample02] +} + +// [End NoComponentReuseSceneTwoPositiveExample02] + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleThreeImageView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleVideoView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneTwoSubPositiveExample.ets b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneTwoSubPositiveExample.ets new file mode 100644 index 0000000000000000000000000000000000000000..43f9a1b39cf43b183daa2c15edb696e0386ad491 --- /dev/null +++ b/ComponentReuse/entry/src/main/ets/view/NoComponentReuseSceneTwoSubPositiveExample.ets @@ -0,0 +1,146 @@ +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; + +@Entry +@Component +struct NoComponentReuseSceneTwoSubPositiveExample { + private dataSource: ItemDataSource = new ItemDataSource(); + + build() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + if (item.type === 0) { + SingleImageNewsContent({ item: item }) + } else if (item.type === 1) { + ThreeImageNewsContent({ item: item }) + } else { + VideoNewsContent({ item: item }) + } + } + }, (item: ItemData) => item.id.toString()) + } + } + } +} + +// [Start NoComponentReuseSceneTwoSubPositiveExample] +@Reusable +@Component +struct SingleImageNewsContent { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleSingleImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +@Reusable +@Component +struct ThreeImageNewsContent { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleThreeImageView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +@Reusable +@Component +struct VideoNewsContent { + // [StartExclude NoComponentReuseSceneTwoSubPositiveExample] + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + MiddleVideoView({ item: item }) + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + + // ... + } + + // [EndExclude NoComponentReuseSceneTwoSubPositiveExample] +} + +// [End NoComponentReuseSceneTwoSubPositiveExample] + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleThreeImageView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleVideoView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} \ No newline at end of file diff --git a/ComponentReuse/entry/src/main/ets/view/ReuseIdClassificationIsTooDetailedScenePositiveExample.ets b/ComponentReuse/entry/src/main/ets/view/ReuseIdClassificationIsTooDetailedScenePositiveExample.ets new file mode 100644 index 0000000000000000000000000000000000000000..184843e204f1e42aed0c5acbc38edc89515bf35e --- /dev/null +++ b/ComponentReuse/entry/src/main/ets/view/ReuseIdClassificationIsTooDetailedScenePositiveExample.ets @@ -0,0 +1,127 @@ +import { ItemDataSource } from '../model/ItemDataSource'; +import { ItemData } from '../model/ItemData'; + +@Entry +@Component +struct NoComponentReuseSceneTwoPositiveExample { + private dataSource: ItemDataSource = new ItemDataSource(); + + build() { + Column() { + List() { + LazyForEach(this.dataSource, (item: ItemData) => { + ListItem() { + NewsContent({ item: item }).reuseId(`${item.type}`) + } + }, (item: ItemData) => item.id.toString()) + } + } + } +} + +@Reusable +@Component +struct NewsContent { + @ObjectLink item: ItemData; + + @Builder + myBuilder(item: ItemData) { + TopView({ item: item }) + if (item.type === 0) { + MiddleTextView({ item: item }) + } else if (item.type === 1) { + MiddleTextNoTitleView({ item: item }) + } else if (item.type === 2) { + MiddleSingleImageView({ item: item }) + } else if (item.type === 3) { + MiddleThreeImageView({ item: item }) + } else if (item.type === 4) { + MiddleVideoView({ item: item }) + } else if (item.type === 5) { + // ... + } else { + // ... + } + BottomView({ item: item }) + } + + build() { + Column() { + this.myBuilder(this.item) + } + + // ... + } +} + +@Component +struct TopView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct BottomView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleSingleImageView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleThreeImageView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +@Component +struct MiddleVideoView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} + +// [Start ReuseIdClassificationIsTooDetailedScenePositiveExample] +@Component +struct MiddleTextView { + @ObjectLink item: ItemData; + + build() { + Column() { + Text('title') + .visibility(this.item.isShowTitle) // Switch effects through the visibility property. + Text() + } + + // ... + } +} + +// [Start ReuseIdClassificationIsTooDetailedScenePositiveExample] + +@Component +struct MiddleTextNoTitleView { + @ObjectLink item: ItemData; + + build() { + // ... + } +} \ No newline at end of file