1/* 2 * Copyright (c) 2022-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import Http from '@ohos/http'; 17import { PRODUCT_DATA } from '../../mock/ProductsData'; 18import { GoodResponse, Info, ProductDataModel } from '../../model/GoodsModel'; 19import { Products_Data } from '../../mock/ProductsData'; 20import { DynamicLoader } from '../../common/DynamicLoader'; 21 22@Component 23export struct GoodsList { 24 @State getDataFromHttp: boolean = false; 25 @Consume('pageStack') pageStack: NavPathStack; 26 private url: string = ''; 27 private option: Object = new Object(); 28 @State productsData: GoodResponse = Products_Data; 29 @State active: boolean = false; 30 31 async aboutToAppear() { 32 Http.setUrl(this.url); 33 Http.setOptions(this.option); 34 this.getDataFromHttp = false; 35 let info = await Http.request(); 36 if (info.responseCode === 200 && info.result !== undefined) { 37 this.getDataFromHttp = true; 38 this.productsData = JSON.parse(info.result.toString()); 39 } 40 } 41 42 build() { 43 GridRow({ 44 gutter: { 45 x: vp2px(8), 46 y: vp2px(8) 47 }, 48 }) { 49 ForEach(this.getDataFromHttp ? this.productsData.data.records : PRODUCT_DATA, (item: Info | ProductDataModel) => { 50 GridCol({ 51 span: { 52 sm: 6, 53 md: 6, 54 lg: 4 55 } 56 }) { 57 Column() { 58 59 // 方案二:使用nav跳转页面,配合共享元素动画 60 Image(item.uri) 61 .id('goods' + item.id) 62 .width('70%') 63 .aspectRatio(1) 64 .clip(true) 65 .objectFit(ImageFit.Contain) 66 .margin({ bottom: 12 }) 67 .geometryTransition('goods' + item.id, { follow: true }) 68 69 Column() { 70 Text(item.title) 71 .width('100%') 72 .fontSize(14) 73 74 Text(item.info) 75 .width('100%') 76 .fontSize(12) 77 .fontColor("#858184") 78 .margin({ 79 top: 6 80 }) 81 82 Text(item.price as Resource) 83 .fontColor($r('app.color.pink')) 84 .fontSize(16) 85 .margin({ 86 top: 6 87 }) 88 .offset({ 89 x: -3 90 }) // 因为¥是中文字符,上面的xx是中文字符,占的宽度不一样,所以需要对齐,添加offset 91 92 Column() { 93 Text(item.labels) 94 .fontSize(10) 95 .fontColor($r('app.color.white')) 96 } 97 .borderRadius(6) 98 .padding({ 99 left: 6, 100 right: 6, 101 top: 4, 102 bottom: 4 103 }) 104 .backgroundColor($r('app.color.pink')) 105 .margin({ 106 top: 6 107 }) 108 } 109 .alignItems(HorizontalAlign.Start) 110 } 111 .borderRadius(10) 112 .padding(12) 113 .backgroundColor($r('app.color.white')) 114 115 // 方案二:使用nav跳转,配合共享元素动画 116 .onClick(() => { 117 // 动态加载组件 118 this.getUIContext()?.animateTo({ duration: 600, curve: Curve.Linear }, () => { 119 DynamicLoader.getInstance().fire('DetailPage').then(() => { 120 this.active = true; 121 this.pageStack.pushPathByName('DetailPage', item, false); 122 }) 123 }); 124 }) 125 } 126 }, (item: Info | ProductDataModel): string => item.id.toString()) 127 } 128 .padding({ 129 left: 12, 130 right: 12 131 }) 132 .onAreaChange((oldValue: Area, newArea: Area) => { 133 AppStorage.setOrCreate('listHeight', newArea.height as number); 134 }) 135 } 136} 137