mirror of
https://gitee.com/openharmony/applications_app_samples
synced 2024-11-27 02:30:43 +00:00
!3474 【Sample】橘子购物sample添加动效代码
Merge pull request !3474 from haoxiaohui/master
This commit is contained in:
commit
303fcdc279
@ -15,13 +15,17 @@
|
||||
|
||||
{
|
||||
"app": {
|
||||
"compileSdkVersion": 10,
|
||||
"compatibleSdkVersion": 10,
|
||||
"products": [
|
||||
{
|
||||
"name": "default",
|
||||
"signingConfig": "default"
|
||||
"signingConfig": "default",
|
||||
"compileSdkVersion": 10,
|
||||
"compatibleSdkVersion": 10,
|
||||
"targetSdkVersion": 10,
|
||||
"runtimeOS": "OpenHarmony"
|
||||
}
|
||||
],
|
||||
"signingConfigs": [
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
|
@ -14,12 +14,12 @@
|
||||
*/
|
||||
|
||||
import AbilityStage from '@ohos.app.ability.AbilityStage';
|
||||
import { logger } from '@ohos/details-page-component'
|
||||
import { logger } from '@ohos/details-page-component';
|
||||
|
||||
const TAG: string = 'MyAbilityStage'
|
||||
const TAG: string = 'MyAbilityStage';
|
||||
|
||||
export default class MyAbilityStage extends AbilityStage {
|
||||
onCreate() {
|
||||
logger.info(TAG, 'onCreate')
|
||||
logger.info(TAG, 'onCreate');
|
||||
}
|
||||
}
|
@ -13,27 +13,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import UIAbility from '@ohos.app.ability.UIAbility'
|
||||
import { logger } from '@ohos/details-page-component'
|
||||
import { notificationUtil } from '@ohos/notification'
|
||||
import { QRCodeScanConst } from '@ohos/scan-component'
|
||||
import abilityAccessCtrl from '@ohos.abilityAccessCtrl'
|
||||
import UIAbility from '@ohos.app.ability.UIAbility';
|
||||
import { logger } from '@ohos/details-page-component';
|
||||
import { notificationUtil } from '@ohos/notification';
|
||||
import { QRCodeScanConst } from '@ohos/scan-component';
|
||||
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
|
||||
import Want from '@ohos.app.ability.Want';
|
||||
|
||||
const TAG: string = 'MainAbility'
|
||||
const TAG: string = 'MainAbility';
|
||||
|
||||
export default class MainAbility extends UIAbility {
|
||||
onCreate(want, launchParam) {
|
||||
logger.info(TAG, 'onCreate')
|
||||
const that = this
|
||||
onCreate(want: Want): void {
|
||||
logger.info(TAG, 'onCreate');
|
||||
const that = this;
|
||||
this.context.eventHub.on("getAbilityData", (data) => {
|
||||
data.context = that.context
|
||||
data.launchWant = want
|
||||
data.context = that.context;
|
||||
data.launchWant = want;
|
||||
})
|
||||
this.requestPermission()
|
||||
AppStorage.SetOrCreate('context', this.context)
|
||||
this.requestPermission();
|
||||
AppStorage.setOrCreate('context', this.context);
|
||||
}
|
||||
|
||||
requestPermission = async () => {
|
||||
async requestPermission(): Promise<void> {
|
||||
let permissionRequestResult = await abilityAccessCtrl.createAtManager().requestPermissionsFromUser(this.context,
|
||||
[
|
||||
'ohos.permission.CAMERA',
|
||||
@ -46,36 +47,35 @@ export default class MainAbility extends UIAbility {
|
||||
// 如果权限列表中有-1,说明用户拒绝了授权
|
||||
if (permissionRequestResult.authResults[0] === 0) {
|
||||
// 控制相机是否打开
|
||||
AppStorage.SetOrCreate(QRCodeScanConst.HAS_CAMERA_PERMISSION, true)
|
||||
logger.info('MainAbility permissionRequestResult success')
|
||||
AppStorage.setOrCreate(QRCodeScanConst.HAS_CAMERA_PERMISSION, true);
|
||||
logger.info('MainAbility permissionRequestResult success');
|
||||
}
|
||||
await notificationUtil.enableNotification()
|
||||
await notificationUtil.enableNotification();
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
logger.info(TAG, 'onDestroy')
|
||||
onDestroy(): void {
|
||||
logger.info(TAG, 'onDestroy');
|
||||
}
|
||||
|
||||
onWindowStageCreate(windowStage) {
|
||||
onWindowStageCreate(windowStage): void {
|
||||
// Main window is created, set main page for this ability
|
||||
logger.info(TAG, 'onWindowStageCreate')
|
||||
|
||||
windowStage.setUIContent(this.context, 'pages/Index', null)
|
||||
logger.info(TAG, 'onWindowStageCreate');
|
||||
windowStage.setUIContent(this.context, 'pages/Index', null);
|
||||
}
|
||||
|
||||
onWindowStageDestroy() {
|
||||
onWindowStageDestroy(): void {
|
||||
// Main window is destroyed, release UI related resources
|
||||
logger.info(TAG, 'onWindowStageDestroy')
|
||||
logger.info(TAG, 'onWindowStageDestroy');
|
||||
}
|
||||
|
||||
onForeground() {
|
||||
onForeground(): void {
|
||||
// Ability has brought to foreground
|
||||
logger.info(TAG, 'MainAbility onForeground')
|
||||
AppStorage.SetOrCreate('cameraStatus', !AppStorage.Get('cameraStatus'))
|
||||
logger.info(TAG, 'MainAbility onForeground');
|
||||
AppStorage.setOrCreate('cameraStatus',!AppStorage.Get('cameraStatus'));
|
||||
}
|
||||
|
||||
onBackground() {
|
||||
onBackground(): void {
|
||||
// Ability has back to background
|
||||
logger.info(TAG, 'onBackground')
|
||||
logger.info(TAG, 'onBackground');
|
||||
}
|
||||
}
|
@ -13,35 +13,36 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import WorkSchedulerExtensionAbility from '@ohos.WorkSchedulerExtensionAbility'
|
||||
import { notificationUtil, notificationContentUtil, notificationRequestUtil, wantAgentUtil } from '@ohos/notification'
|
||||
import { logger } from '@ohos/details-page-component'
|
||||
import WorkSchedulerExtensionAbility from '@ohos.WorkSchedulerExtensionAbility';
|
||||
import { notificationUtil, notificationContentUtil, notificationRequestUtil, wantAgentUtil } from '@ohos/notification';
|
||||
import { logger } from '@ohos/details-page-component';
|
||||
import workScheduler from '@ohos.resourceschedule.workScheduler';
|
||||
|
||||
const TAG: string = 'WorkAbility'
|
||||
const BUNDLE_NAME = 'ohos.samples.orangeshopping'
|
||||
const ABILITY_NAME = 'MainAbility'
|
||||
const NOTIFICATION_ID = 1 // 定义发送通知的id,默认1
|
||||
const TAG: string = 'WorkAbility';
|
||||
const BUNDLE_NAME: string = 'ohos.samples.orangeshopping';
|
||||
const ABILITY_NAME: string = 'MainAbility';
|
||||
const NOTIFICATION_ID: number = 1 // 定义发送通知的id,默认1
|
||||
|
||||
export default class WorkAbility extends WorkSchedulerExtensionAbility {
|
||||
onWorkStart(workInfo) {
|
||||
logger.info(TAG, `onWorkStart ${JSON.stringify(workInfo)}`)
|
||||
onWorkStart(workInfo: workScheduler.WorkInfo) {
|
||||
logger.info(TAG, `onWorkStart ${JSON.stringify(workInfo)}`);
|
||||
if (workInfo.parameters) {
|
||||
this.publishNotification(workInfo.parameters)
|
||||
this.publishNotification(workInfo.parameters);
|
||||
}
|
||||
}
|
||||
|
||||
onWorkStop(workInfo) {
|
||||
logger.info(TAG, `onWorkStop ${JSON.stringify(workInfo)}`)
|
||||
notificationUtil.cancelNotificationById(1)
|
||||
logger.info(TAG, `onWorkStop ${JSON.stringify(workInfo)}`);
|
||||
notificationUtil.cancelNotificationById(1);
|
||||
}
|
||||
|
||||
publishNotification = async (parameters: any) => {
|
||||
let parametersObject = JSON.parse(parameters)
|
||||
logger.info(TAG, `publishNotification parametersObject= ${parametersObject}`)
|
||||
async publishNotification(parameters: any): Promise<void> {
|
||||
let parametersObject = JSON.parse(parameters);
|
||||
logger.info(TAG, `publishNotification parametersObject= ${parametersObject}`);
|
||||
let basicContent = {
|
||||
title: parametersObject.title,
|
||||
text: ''
|
||||
}
|
||||
};
|
||||
let actionButtons = [
|
||||
{
|
||||
title: parametersObject.firstButton,
|
||||
@ -51,13 +52,13 @@ export default class WorkAbility extends WorkSchedulerExtensionAbility {
|
||||
title: parametersObject.secondButton,
|
||||
wantAgent: await wantAgentUtil.createWantAgentForStartAbility(BUNDLE_NAME, ABILITY_NAME)
|
||||
}
|
||||
]
|
||||
];
|
||||
try {
|
||||
let notificationContent = notificationContentUtil.initBasicNotificationContent(basicContent)
|
||||
let notificationRequest = notificationRequestUtil.initButtonNotificationRequest(notificationContent, actionButtons)
|
||||
notificationUtil.publishNotification(notificationRequest, NOTIFICATION_ID)
|
||||
let notificationContent = notificationContentUtil.initBasicNotificationContent(basicContent);
|
||||
let notificationRequest = notificationRequestUtil.initButtonNotificationRequest(notificationContent, actionButtons);
|
||||
notificationUtil.publishNotification(notificationRequest, NOTIFICATION_ID);
|
||||
} catch (error) {
|
||||
logger.info(TAG, `publish notification error ${JSON.stringify(error)}`)
|
||||
logger.info(TAG, `publish notification error ${JSON.stringify(error)}`);
|
||||
}
|
||||
}
|
||||
}
|
@ -13,14 +13,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DetailPage } from '@ohos/details-page-component'
|
||||
import { DetailPage } from '@ohos/details-page-component';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Detail {
|
||||
build() {
|
||||
Column() {
|
||||
DetailPage()
|
||||
DetailPage();
|
||||
}
|
||||
}
|
||||
}
|
@ -13,14 +13,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FullPage } from '@ohos/video-component'
|
||||
import { FullPage } from '@ohos/video-component';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Detail {
|
||||
build() {
|
||||
Column() {
|
||||
FullPage()
|
||||
FullPage();
|
||||
}
|
||||
}
|
||||
}
|
@ -13,30 +13,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import mediaquery from '@ohos.mediaquery'
|
||||
import window from '@ohos.window'
|
||||
import { NavigationHomePage } from '@ohos/navigation-component'
|
||||
import { UpdateDialog } from '@ohos/updatedialog'
|
||||
import { EventsDialog } from '@ohos/details-page-component'
|
||||
import { EmitterClass } from '@ohos/emitter'
|
||||
import mediaQuery from '@ohos.mediaquery';
|
||||
import window from '@ohos.window';
|
||||
import { NavigationHomePage } from '@ohos/navigation-component';
|
||||
import { UpdateDialog } from '@ohos/updatedialog';
|
||||
import { EventsDialog } from '@ohos/details-page-component';
|
||||
import { EmitterClass } from '@ohos/emitter';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct HomePage {
|
||||
@State url: string = ''
|
||||
@State option: object = undefined
|
||||
@State curBp: string = 'md' // curBp指当前窗口断点,sm代表小屏,md代表中屏,lg代表大屏
|
||||
private smListener: any
|
||||
private mdListener: any
|
||||
private lgListener: any
|
||||
@StorageLink('shoppingCartGoodsList') shoppingCartGoodsList: { data: { id: number } }[] = []
|
||||
private emitterClass: EmitterClass = new EmitterClass()
|
||||
|
||||
@State url: string = '';
|
||||
@State option: object = undefined;
|
||||
@State curBp: string = 'md'; // curBp指当前窗口断点,sm代表小屏,md代表中屏,lg代表大屏
|
||||
private smListener: mediaQuery.MediaQueryListener;
|
||||
private mdListener: mediaQuery.MediaQueryListener;
|
||||
private lgListener: mediaQuery.MediaQueryListener;
|
||||
@StorageLink('shoppingCartGoodsList') shoppingCartGoodsList: { data: { id: number } }[] = [];
|
||||
private emitterClass: EmitterClass = new EmitterClass();
|
||||
EventsDialogController: CustomDialogController = new CustomDialogController({
|
||||
builder: EventsDialog(),
|
||||
customStyle: true
|
||||
})
|
||||
|
||||
UpdateDialogController: CustomDialogController = new CustomDialogController({
|
||||
builder: UpdateDialog(),
|
||||
customStyle: true
|
||||
@ -44,35 +42,35 @@ struct HomePage {
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
NavigationHomePage({ url: this.url })
|
||||
NavigationHomePage({ url: this.url });
|
||||
}
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
if(AppStorage.Get('nowIndex') === undefined || AppStorage.Get('nowIndex') === 0){
|
||||
aboutToAppear(): void {
|
||||
if (AppStorage.get('nowIndex') === undefined || AppStorage.Get('nowIndex') === 0) {
|
||||
this.UpdateDialogController.open()
|
||||
}
|
||||
this.emitterClass.showEventsDialog(()=>{
|
||||
if(AppStorage.Get('nowIndex') === undefined || AppStorage.Get('nowIndex') === 0){
|
||||
this.emitterClass.showEventsDialog(() => {
|
||||
if (AppStorage.get('nowIndex') === undefined || AppStorage.Get('nowIndex') === 0) {
|
||||
this.EventsDialogController.open()
|
||||
}
|
||||
})
|
||||
this.emitterClass.setShoppingCartGoodsList((eventData)=>{
|
||||
this.emitterClass.setShoppingCartGoodsList((eventData) => {
|
||||
this.shoppingCartGoodsList.push(eventData.data.id)
|
||||
AppStorage.SetOrCreate('shoppingCartGoodsList', this.shoppingCartGoodsList)
|
||||
AppStorage.setOrCreate('shoppingCartGoodsList', this.shoppingCartGoodsList)
|
||||
})
|
||||
this.smListener = mediaquery.matchMediaSync('(320vp<=width<520vp)')
|
||||
this.smListener = mediaQuery.matchMediaSync('(320vp<=width<520vp)')
|
||||
this.smListener.on('change', this.isBreakpointSM)
|
||||
this.mdListener = mediaquery.matchMediaSync('(520vp<=width<840vp)')
|
||||
this.mdListener = mediaQuery.matchMediaSync('(520vp<=width<840vp)')
|
||||
this.mdListener.on('change', this.isBreakpointMD)
|
||||
this.lgListener = mediaquery.matchMediaSync('(840vp<=width)')
|
||||
this.lgListener = mediaQuery.matchMediaSync('(840vp<=width)')
|
||||
this.lgListener.on('change', this.isBreakpointLG)
|
||||
window.getTopWindow({ stageMode: true }).then(result => {
|
||||
window.getLastWindow({ stageMode: true }).then(result => {
|
||||
result.setFullScreen(false)
|
||||
})
|
||||
}
|
||||
|
||||
aboutToDisappear() {
|
||||
aboutToDisappear(): void {
|
||||
this.smListener.off('change', this.isBreakpointSM)
|
||||
this.mdListener.off('change', this.isBreakpointMD)
|
||||
this.lgListener.off('change', this.isBreakpointLG)
|
||||
@ -81,19 +79,19 @@ struct HomePage {
|
||||
isBreakpointSM = (mediaQueryResult) => {
|
||||
if (mediaQueryResult.matches) {
|
||||
this.curBp = 'sm'
|
||||
AppStorage.SetOrCreate('curBp', this.curBp)
|
||||
AppStorage.setOrCreate('curBp', this.curBp)
|
||||
}
|
||||
}
|
||||
isBreakpointMD = (mediaQueryResult) => {
|
||||
if (mediaQueryResult.matches) {
|
||||
this.curBp = 'md'
|
||||
AppStorage.SetOrCreate('curBp', this.curBp)
|
||||
AppStorage.setOrCreate('curBp', this.curBp)
|
||||
}
|
||||
}
|
||||
isBreakpointLG = (mediaQueryResult) => {
|
||||
if (mediaQueryResult.matches) {
|
||||
this.curBp = 'lg'
|
||||
AppStorage.SetOrCreate('curBp', this.curBp)
|
||||
AppStorage.setOrCreate('curBp', this.curBp)
|
||||
}
|
||||
}
|
||||
}
|
@ -13,8 +13,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import routerUtil from '../utils/RouterUtil'
|
||||
import { TransitionsAnimation } from '@ohos/enter-animation'
|
||||
import routerUtil from '../utils/RouterUtil';
|
||||
import { TransitionsAnimation } from '@ohos/enter-animation';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
@ -23,9 +23,9 @@ struct Index {
|
||||
Column() {
|
||||
TransitionsAnimation({
|
||||
gotoNav: () => {
|
||||
routerUtil.gotoHome()
|
||||
routerUtil.gotoHome();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -13,14 +13,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { LivePage } from '@ohos/video-component'
|
||||
import { LivePage } from '@ohos/video-component';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Live {
|
||||
build() {
|
||||
Column() {
|
||||
LivePage()
|
||||
LivePage();
|
||||
}
|
||||
}
|
||||
}
|
@ -13,14 +13,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { QRCodeScanComponent } from "@ohos/scan-component"
|
||||
import { QRCodeScanComponent } from "@ohos/scan-component";
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Scan {
|
||||
build() {
|
||||
Column() {
|
||||
QRCodeScanComponent()
|
||||
QRCodeScanComponent();
|
||||
}
|
||||
}
|
||||
}
|
@ -13,14 +13,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { setting } from '@ohos/http'
|
||||
import { setting } from '@ohos/http';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Index {
|
||||
build() {
|
||||
Column() {
|
||||
setting()
|
||||
setting();
|
||||
}
|
||||
}
|
||||
}
|
@ -13,21 +13,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import router from '@ohos.router'
|
||||
import router from '@ohos.router';
|
||||
|
||||
export default class RouterUtil {
|
||||
static gotoHome() {
|
||||
router.replace({
|
||||
router.replaceUrl({
|
||||
url: 'pages/Home'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
static gotoDetail() {
|
||||
router.push({
|
||||
router.pushUrl({
|
||||
url: 'pages/Detail',
|
||||
params: {
|
||||
id: 10
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
@ -15,10 +15,11 @@
|
||||
|
||||
@Component
|
||||
export struct AddressService {
|
||||
@Link isPanel: boolean
|
||||
@Link currentLocation: string
|
||||
@Link isPanel: boolean;
|
||||
@Link currentLocation: string;
|
||||
|
||||
@Builder Server(text: Resource, marginTop: number) {
|
||||
@Builder
|
||||
Server(text: Resource, marginTop: number) {
|
||||
Row() {
|
||||
Image($r('app.media.service'))
|
||||
.objectFit(ImageFit.Contain)
|
||||
@ -78,7 +79,7 @@ export struct AddressService {
|
||||
.alignItems(VerticalAlign.Top)
|
||||
.width('100%')
|
||||
.onClick(() => {
|
||||
this.isPanel = !this.isPanel
|
||||
this.isPanel = !this.isPanel;
|
||||
})
|
||||
|
||||
Row() {
|
||||
|
@ -13,16 +13,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import router from '@ohos.router'
|
||||
import prompt from '@ohos.prompt'
|
||||
import { EmitterClass } from '@ohos/emitter'
|
||||
import { ProductDataModel } from '../model/DetailMode'
|
||||
import router from '@ohos.router';
|
||||
import { EmitterClass } from '@ohos/emitter';
|
||||
import { ProductDataModel } from '../model/DetailMode';
|
||||
import curves from '@ohos.curves';
|
||||
|
||||
@Component
|
||||
export struct BottomNavigation {
|
||||
@StorageProp('curBp') curBp: string = 'md'
|
||||
@Link goodItemData: ProductDataModel
|
||||
private emitterClass: EmitterClass = new EmitterClass()
|
||||
@StorageProp('curBp') curBp: string = 'md';
|
||||
@Link goodItemData: ProductDataModel;
|
||||
private emitterClass: EmitterClass = new EmitterClass();
|
||||
@Link animateAppear: boolean; // 动画开始标识
|
||||
@Link animateScale: boolean; // 开始缩小动画标识
|
||||
@Link animatePath: boolean; // 开始路径动画标识
|
||||
@State animateSpring: boolean = false; // 开始弹簧动画标识
|
||||
@State productCount: number = 1;
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
@ -39,16 +44,30 @@ export struct BottomNavigation {
|
||||
}
|
||||
.width(74)
|
||||
.onClick(() => {
|
||||
AppStorage.SetOrCreate('nowIndex',0)
|
||||
router.push({
|
||||
AppStorage.SetOrCreate('nowIndex', 0)
|
||||
router.pushUrl({
|
||||
url: 'pages/Home'
|
||||
})
|
||||
});
|
||||
})
|
||||
|
||||
Column() {
|
||||
Image($r('app.media.cart'))
|
||||
.width(22)
|
||||
.height(22)
|
||||
Stack({ alignContent: Alignment.TopEnd }) {
|
||||
Image($r('app.media.cart'))
|
||||
.width(22)
|
||||
.height(22)
|
||||
.rotate(this.animateSpring ? { angle: 10 } : { angle: 0 })
|
||||
|
||||
Text(`${this.productCount}`)
|
||||
.borderRadius(10)
|
||||
.width(15)
|
||||
.height(15)
|
||||
.backgroundColor("#ea6055")
|
||||
.fontSize(10)
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontColor(Color.White)
|
||||
.margin({ top: -10, right: -10 })
|
||||
}
|
||||
|
||||
Text($r('app.string.shopping_cart'))
|
||||
.fontColor($r('app.color.blank'))
|
||||
.fontSize(10)
|
||||
@ -57,10 +76,10 @@ export struct BottomNavigation {
|
||||
}
|
||||
.width(74)
|
||||
.onClick(() => {
|
||||
AppStorage.SetOrCreate('nowIndex',2)
|
||||
router.push({
|
||||
AppStorage.setOrCreate('nowIndex', 2)
|
||||
router.pushUrl({
|
||||
url: 'pages/Home'
|
||||
})
|
||||
});
|
||||
})
|
||||
}
|
||||
.justifyContent(this.curBp === 'sm' ? FlexAlign.SpaceEvenly : FlexAlign.Start)
|
||||
@ -74,8 +93,44 @@ export struct BottomNavigation {
|
||||
}
|
||||
.alignItems(VerticalAlign.Center)
|
||||
.padding({ left: 20, right: 20 })
|
||||
.onClick(()=>{
|
||||
this.emitterClass.addGoods(this.goodItemData.id)
|
||||
.onClick(() => {
|
||||
// 添加商品到购物车
|
||||
this.emitterClass.addGoods(this.goodItemData.id);
|
||||
// this.emitterClass.shoppingCartGoodsList
|
||||
|
||||
// 准备显示动画
|
||||
this.animateAppear = !this.animateAppear;
|
||||
|
||||
// 用0.5秒实现动画缩小,曲线使用EaseOut,特点是开始快,结束慢
|
||||
animateTo({ duration: 500, curve: Curve.EaseOut,
|
||||
onFinish: () => {
|
||||
// 用1秒实现动画曲线,曲线使用EaseIn,特点是开始慢,结束快
|
||||
animateTo({ duration: 1000, curve: Curve.EaseIn,
|
||||
onFinish: () => {
|
||||
// 动画结束,将参数复原,及时移除动画视图
|
||||
this.animateAppear = !this.animateAppear;
|
||||
this.animatePath = !this.animatePath;
|
||||
this.animateScale = !this.animateScale;
|
||||
// 设置弹簧动画,初始速度100,质量1,刚度225,阻尼10,
|
||||
// 建议从初始速度0,质量1,刚度225,阻尼30,开始调参,这是临届阻尼的参数
|
||||
// 如果觉得曲线一开始太慢了,可以把初速度加大
|
||||
this.animateSpring = !this.animateSpring;
|
||||
// interpolatingSpring的参数需要调试,通过调试找到自己想要的效果
|
||||
animateTo({ duration: 1, curve: curves.interpolatingSpring(100, 1, 225, 10), iterations: 1 }, () => {
|
||||
// 开始弹簧动画
|
||||
this.animateSpring = !this.animateSpring;
|
||||
// 更改数字
|
||||
this.productCount = this.productCount + 1;
|
||||
})
|
||||
} }, () => {
|
||||
// 开始路径动画
|
||||
this.animatePath = !this.animatePath;
|
||||
})
|
||||
} }, () => {
|
||||
// 开始缩小动画
|
||||
this.animateScale = !this.animateScale;
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
Row() {
|
||||
@ -97,4 +152,5 @@ export struct BottomNavigation {
|
||||
.height(56)
|
||||
.backgroundColor($r('app.color.divider'))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,6 @@ export struct EventsDialog {
|
||||
.objectFit(ImageFit.Contain)
|
||||
.height(300)
|
||||
.aspectRatio(1.5)
|
||||
|
||||
Column() {
|
||||
Text($r('app.string.shopping'))
|
||||
.fontSize(24)
|
||||
@ -50,7 +49,7 @@ export struct EventsDialog {
|
||||
.backgroundColor('rgba(0,0,0,0.3)')
|
||||
.borderRadius('18vp')
|
||||
.onClick(() => {
|
||||
this.customDialogController.close()
|
||||
this.customDialogController.close();
|
||||
})
|
||||
}
|
||||
.backgroundColor('#F1F3F5')
|
||||
|
@ -13,31 +13,31 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import router from '@ohos.router'
|
||||
import prompt from '@ohos.promptAction'
|
||||
import workScheduler from '@ohos.resourceschedule.workScheduler'
|
||||
import { logger } from '../utils/Logger'
|
||||
import { ButtonDialogBuilder } from '@ohos/sharecomponent'
|
||||
import router from '@ohos.router';
|
||||
import prompt from '@ohos.promptAction';
|
||||
import workScheduler from '@ohos.resourceschedule.workScheduler';
|
||||
import { logger } from '../utils/Logger';
|
||||
import { ButtonDialogBuilder } from '@ohos/sharecomponent';
|
||||
|
||||
const SRC_IMG = 'https://res5.vmallres.com/pimages/uomcdn/CN/pms/202207/gbom/6941487270880/428_428_1142FAB7EA4DCBDD8C64BF54486A7D4Bmp.png'
|
||||
const TAG: string = 'Information'
|
||||
const SRC_IMG: string = 'https://res5.vmallres.com/pimages/uomcdn/CN/pms/202207/gbom/6941487270880/428_428_1142FAB7EA4DCBDD8C64BF54486A7D4Bmp.png';
|
||||
const TAG: string = 'Information';
|
||||
|
||||
@Component
|
||||
export struct Information {
|
||||
@State collected: boolean = false
|
||||
private data: any[] = router.getParams()['goodItem']
|
||||
@State recommend: string = ''
|
||||
@State commodity: string = ''
|
||||
@State collected: boolean = false;
|
||||
private data: any[] = router.getParams()['goodItem'];
|
||||
@State recommend: string = '';
|
||||
@State commodity: string = '';
|
||||
|
||||
aboutToAppear() {
|
||||
let context: Context = getContext(this)
|
||||
this.recommend = context.resourceManager.getStringSync($r('app.string.recommend').id)
|
||||
this.commodity = context.resourceManager.getStringSync($r('app.string.commodity').id)
|
||||
let context: Context = getContext(this);
|
||||
this.recommend = context.resourceManager.getStringSync($r('app.string.recommend').id);
|
||||
this.commodity = context.resourceManager.getStringSync($r('app.string.commodity').id);
|
||||
}
|
||||
|
||||
// 分享弹框
|
||||
controller: TabsController = new TabsController()
|
||||
shareDialog: CustomDialogController
|
||||
controller: TabsController = new TabsController();
|
||||
shareDialog: CustomDialogController;
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
@ -77,7 +77,7 @@ export struct Information {
|
||||
alignment: DialogAlignment.Bottom,
|
||||
customStyle: true,
|
||||
})
|
||||
this.shareDialog.open()
|
||||
this.shareDialog.open();
|
||||
})
|
||||
|
||||
Row() {
|
||||
@ -91,7 +91,7 @@ export struct Information {
|
||||
}
|
||||
.opacity(0.6)
|
||||
.onClick(() => {
|
||||
this.collected = !this.collected
|
||||
this.collected = !this.collected;
|
||||
})
|
||||
|
||||
Row({ space: 6 }) {
|
||||
@ -116,12 +116,12 @@ export struct Information {
|
||||
firstButton: getContext(this).resourceManager.getStringSync($r('app.string.close')),
|
||||
secondButton: getContext(this).resourceManager.getStringSync($r('app.string.go_to_view'))
|
||||
}
|
||||
}
|
||||
};
|
||||
try {
|
||||
workScheduler.startWork(workInfo)
|
||||
prompt.showToast({ message: $r('app.string.subscribe_notice') })
|
||||
workScheduler.startWork(workInfo);
|
||||
prompt.showToast({ message: $r('app.string.subscribe_notice') });
|
||||
} catch (error) {
|
||||
logger.info(TAG, `startWork error ${JSON.stringify(error)}`)
|
||||
logger.info(TAG, `startWork error ${JSON.stringify(error)}`);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -13,17 +13,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CITY_DATA, HOT_CITY, TAB_VALUE } from '../mock/DetailData'
|
||||
import { CITY_DATA, HOT_CITY, TAB_VALUE } from '../mock/DetailData';
|
||||
|
||||
@Component
|
||||
export struct Location {
|
||||
@Link isPanel: boolean
|
||||
private scroller: Scroller = new Scroller()
|
||||
@State stabIndex: number = 0
|
||||
@State location: boolean = true
|
||||
@Link currentLocation: string
|
||||
@Link isPanel: boolean;
|
||||
private scroller: Scroller = new Scroller();
|
||||
@State stabIndex: number = 0;
|
||||
@State location: boolean = true;
|
||||
@Link currentLocation: string;
|
||||
|
||||
@Builder cityList(city: any) {
|
||||
@Builder
|
||||
cityList(city: any) {
|
||||
if (this.currentLocation === city.name) {
|
||||
List() {
|
||||
ForEach(city.city, twoCity => {
|
||||
@ -34,7 +35,7 @@ export struct Location {
|
||||
.height(30)
|
||||
.fontSize(14)
|
||||
.onClick(() => {
|
||||
this.currentLocation = city.name + '/' + twoCity
|
||||
this.currentLocation = city.name + '/' + twoCity;
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -54,7 +55,7 @@ export struct Location {
|
||||
.height(6)
|
||||
.margin({ top: 10 })
|
||||
.onClick(() => {
|
||||
this.isPanel = !this.isPanel
|
||||
this.isPanel = !this.isPanel;
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
@ -118,7 +119,7 @@ export struct Location {
|
||||
.maxLines(3)
|
||||
.fontColor($r('app.color.blank'))
|
||||
.onClick(() => {
|
||||
this.currentLocation = item
|
||||
this.currentLocation = item;
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -141,9 +142,9 @@ export struct Location {
|
||||
.width('100%')
|
||||
.onClick(() => {
|
||||
if (item.name === undefined) {
|
||||
this.currentLocation = item
|
||||
this.currentLocation = item;
|
||||
} else {
|
||||
this.currentLocation = item.name
|
||||
this.currentLocation = item.name;
|
||||
}
|
||||
})
|
||||
this.cityList(item)
|
||||
@ -158,7 +159,7 @@ export struct Location {
|
||||
.divider({ strokeWidth: 2, color: $r('app.color.divider'), startMargin: 0, endMargin: 20 })
|
||||
.listDirection(Axis.Vertical)
|
||||
.onScrollIndex((firstIndex: number, lastIndex: number) => {
|
||||
this.stabIndex = firstIndex
|
||||
this.stabIndex = firstIndex;
|
||||
})
|
||||
}
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
@ -173,7 +174,7 @@ export struct Location {
|
||||
.selectedFont({ size: 16, weight: FontWeight.Bolder })
|
||||
.popupFont({ size: 30, weight: FontWeight.Bolder })
|
||||
.alignStyle(this.location ? IndexerAlign.Right : IndexerAlign.Left)
|
||||
.onSelected((tabIndex: number) => {
|
||||
.onSelect((tabIndex: number) => {
|
||||
this.scroller.scrollToIndex(tabIndex)
|
||||
})
|
||||
}
|
||||
|
@ -15,21 +15,21 @@
|
||||
|
||||
@Component
|
||||
export struct SmallVideo {
|
||||
@State smallVideoSrc: Resource = $r('app.media.videos')
|
||||
@Link @Watch("onChanged") isHidden: boolean
|
||||
@Link isCancel: boolean
|
||||
@Consume('playTime') updateTime: number
|
||||
smallVideoController: VideoController = new VideoController()
|
||||
@State smallVideoSrc: Resource = $r('app.media.videos');
|
||||
@Link @Watch("onChanged") isHidden: boolean;
|
||||
@Link isCancel: boolean;
|
||||
@Consume('playTime') updateTime: number;
|
||||
smallVideoController: VideoController = new VideoController();
|
||||
|
||||
onChanged(): void {
|
||||
if (this.isHidden) {
|
||||
this.smallVideoController.start();
|
||||
this.smallVideoController.setCurrentTime(this.updateTime)
|
||||
this.smallVideoController.setCurrentTime(this.updateTime);
|
||||
}
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
this.smallVideoController.setCurrentTime(this.updateTime)
|
||||
this.smallVideoController.setCurrentTime(this.updateTime);
|
||||
}
|
||||
|
||||
build() {
|
||||
@ -44,7 +44,7 @@ export struct SmallVideo {
|
||||
.muted(true)
|
||||
.id('smallVideo')
|
||||
.onFinish(() => {
|
||||
this.isHidden = false
|
||||
this.isHidden = false;
|
||||
})
|
||||
|
||||
// 视频小窗口的右上角X
|
||||
@ -54,8 +54,8 @@ export struct SmallVideo {
|
||||
.position({ x: '80%', y: '10%' })
|
||||
.id('closeBtn')
|
||||
.onClick(() => {
|
||||
this.isHidden = false
|
||||
this.isCancel = false
|
||||
this.isHidden = false;
|
||||
this.isCancel = false;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { COMMENT_DATA } from '../mock/DetailData'
|
||||
import { COMMENT_DATA } from '../mock/DetailData';
|
||||
|
||||
@Component
|
||||
export struct Valuation {
|
||||
|
@ -12,20 +12,21 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import router from '@ohos.router'
|
||||
import router from '@ohos.router';
|
||||
|
||||
@Component
|
||||
export struct VideoPage {
|
||||
@State videoSrc: Resource = $rawfile('video_4.mp4')
|
||||
@State controls: boolean = false
|
||||
@State isFull: boolean = false
|
||||
@State isPause: boolean = true
|
||||
@State isPlayClick: boolean = true
|
||||
@State firstClick: boolean = true
|
||||
@State isHidden: boolean = true
|
||||
@Link isStart: boolean
|
||||
@Consume('playTime') updateTime: number
|
||||
detailVideoController: VideoController = new VideoController()
|
||||
@State videoSrc: Resource = $rawfile('video_4.mp4');
|
||||
@State controls: boolean = false;
|
||||
@State isFull: boolean = false;
|
||||
@State isPause: boolean = true;
|
||||
@State isPlayClick: boolean = true;
|
||||
@State coverUrl: string = '';
|
||||
@State firstClick: boolean = true;
|
||||
@State isHidden: boolean = true;
|
||||
@Link isStart: boolean;
|
||||
@Consume('playTime') updateTime: number;
|
||||
detailVideoController: VideoController = new VideoController();
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
@ -40,7 +41,7 @@ export struct VideoPage {
|
||||
.controls(this.controls)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.onUpdate((e) => {
|
||||
this.updateTime = e.time
|
||||
this.updateTime = e.time;
|
||||
})
|
||||
.onPrepared((e) => {
|
||||
console.info('VideoPage_onPrepared:' + e.duration)
|
||||
@ -48,26 +49,32 @@ export struct VideoPage {
|
||||
.onClick(() => {
|
||||
if (this.isPlayClick) { // 判断play按钮是否用过,没有用过,进入这层
|
||||
if (this.firstClick) { // 第一次点击视频开始播放,再次点击进入全屏
|
||||
this.detailVideoController.start()
|
||||
this.isHidden = !this.isHidden
|
||||
this.isStart = true
|
||||
this.firstClick = !this.firstClick
|
||||
this.detailVideoController.start();
|
||||
this.isHidden = !this.isHidden;
|
||||
this.isStart = true;
|
||||
this.firstClick = !this.firstClick;
|
||||
} else {
|
||||
router.push({ url: 'pages/FullPage', params: { videoSrc: this.videoSrc, videoTime: this.updateTime } })
|
||||
router.pushUrl({
|
||||
url: 'pages/FullPage',
|
||||
params: { videoSrc: this.videoSrc, videoTime: this.updateTime }
|
||||
});
|
||||
}
|
||||
} else {
|
||||
router.push({ url: 'pages/FullPage', params: { videoSrc: this.videoSrc, videoTime: this.updateTime } })
|
||||
router.pushUrl({
|
||||
url: 'pages/FullPage',
|
||||
params: { videoSrc: this.videoSrc, videoTime: this.updateTime }
|
||||
});
|
||||
}
|
||||
})
|
||||
.onFinish(() => {
|
||||
this.isHidden = true
|
||||
this.isStart = false
|
||||
this.isHidden = true;
|
||||
this.isStart = false;
|
||||
})
|
||||
|
||||
// 空白层预览
|
||||
if(this.isHidden){
|
||||
if (this.isHidden) {
|
||||
Column() {
|
||||
Image($r('app.media.preview_Img'))
|
||||
Image(this.coverUrl)
|
||||
.id('previewImg')
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
@ -77,16 +84,16 @@ export struct VideoPage {
|
||||
}
|
||||
|
||||
// 视频上的play图标
|
||||
if(this.isHidden){
|
||||
if (this.isHidden) {
|
||||
Column() {
|
||||
Image($r('app.media.play'))
|
||||
.id('playBtn')
|
||||
.width(76).height(76)
|
||||
.onClick(() => {
|
||||
this.detailVideoController.start()
|
||||
this.isHidden = !this.isHidden
|
||||
this.isStart = true
|
||||
this.isPlayClick = false
|
||||
this.detailVideoController.start();
|
||||
this.isHidden = !this.isHidden;
|
||||
this.isStart = true;
|
||||
this.isPlayClick = false;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -13,191 +13,239 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import router from '@ohos.router'
|
||||
import { Location } from '../components/Location'
|
||||
import { Information } from '../components/Information'
|
||||
import { Choice } from '../components/Choice'
|
||||
import { AddressService } from '../components/AddressService'
|
||||
import { Valuation } from '../components/Valuation'
|
||||
import { BottomNavigation } from '../components/BottomNavigation'
|
||||
import { VideoPage } from '../components/VideoPage'
|
||||
import { SmallVideo } from '../components/SmallVideo'
|
||||
import { SWIPER_PICTURE_DATA } from '../mock/DetailData'
|
||||
import { ButtonDialogBuilder } from '@ohos/sharecomponent'
|
||||
import router from '@ohos.router';
|
||||
import { Location } from '../components/Location';
|
||||
import { Information } from '../components/Information';
|
||||
import { Choice } from '../components/Choice';
|
||||
import { AddressService } from '../components/AddressService';
|
||||
import { Valuation } from '../components/Valuation';
|
||||
import { BottomNavigation } from '../components/BottomNavigation';
|
||||
import { VideoPage } from '../components/VideoPage';
|
||||
import { SmallVideo } from '../components/SmallVideo';
|
||||
import { SWIPER_PICTURE_DATA } from '../mock/DetailData';
|
||||
import { ButtonDialogBuilder } from '@ohos/sharecomponent';
|
||||
|
||||
const SRC_IMG = 'https://res5.vmallres.com/pimages/uomcdn/CN/pms/202207/gbom/6941487270880/428_428_1142FAB7EA4DCBDD8C64BF54486A7D4Bmp.png'
|
||||
const SRC_IMG: string = 'https://res5.vmallres.com/pimages/uomcdn/CN/pms/202207/gbom/6941487270880/428_428_1142FAB7EA4DCBDD8C64BF54486A7D4Bmp.png';
|
||||
|
||||
@Component
|
||||
export struct DetailPage {
|
||||
@State sOpacity: number = 1
|
||||
@State isPanel: boolean = false
|
||||
@State goodDetailData: any[] = router.getParams()['goodItem']
|
||||
@State currentLocation: string = ''
|
||||
@State recommend: string = ''
|
||||
@State commodity: string = ''
|
||||
@State swiperIndex: number = 0
|
||||
@State sOpacity: number = 1;
|
||||
@State isPanel: boolean = false;
|
||||
@State goodDetailData: any[] = router.getParams()['goodItem'];
|
||||
@State currentLocation: string = '';
|
||||
@State recommend: string = '';
|
||||
@State commodity: string = '';
|
||||
@State swiperIndex: number = 0;
|
||||
// Video组件
|
||||
@State isHidden: boolean = false
|
||||
@State isState: boolean = true
|
||||
@State isCancel: boolean = true
|
||||
@State activeVideo: number = 0
|
||||
@State openFirst: boolean = false
|
||||
@Provide('playTime') playNum: number = 20
|
||||
@StorageProp('curBp') curBp: string = 'md'
|
||||
private shareDialog: CustomDialogController
|
||||
private scroller: Scroller = new Scroller()
|
||||
@State isHidden: boolean = false;
|
||||
@State isState: boolean = true;
|
||||
@State isCancel: boolean = true;
|
||||
@State activeVideo: number = 0;
|
||||
@State openFirst: boolean = false;
|
||||
@Provide('playTime') playNum: number = 20;
|
||||
@StorageProp('curBp') curBp: string = 'md';
|
||||
private shareDialog: CustomDialogController;
|
||||
private scroller: Scroller = new Scroller();
|
||||
@State isShowImage: boolean = true;
|
||||
@State animateAppear: boolean = false;
|
||||
@State animateScale: boolean = false;
|
||||
@State animatePath: boolean = false;
|
||||
|
||||
build() {
|
||||
Stack() {
|
||||
Scroll(this.scroller) {
|
||||
Column({ space: 12 }) {
|
||||
Stack({ alignContent: Alignment.BottomEnd }) {
|
||||
Swiper() {
|
||||
VideoPage({ isStart: $openFirst })
|
||||
.id('VideoPage')
|
||||
ForEach(SWIPER_PICTURE_DATA, item => {
|
||||
Column() {
|
||||
Image(this.goodDetailData['uri'])
|
||||
.width('100%')
|
||||
.aspectRatio(1)
|
||||
}
|
||||
.width('100%')
|
||||
Stack({ alignContent: Alignment.Top }) {
|
||||
Stack() {
|
||||
Scroll(this.scroller) {
|
||||
Column({ space: 12 }) {
|
||||
Stack({ alignContent: Alignment.BottomEnd }) {
|
||||
Swiper() {
|
||||
VideoPage({ isStart: $openFirst, coverUrl: this.goodDetailData['uri'] })
|
||||
.id('VideoPage')
|
||||
ForEach(SWIPER_PICTURE_DATA, () => {
|
||||
Column() {
|
||||
Image(this.goodDetailData['uri'])
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
.aspectRatio(1.12)
|
||||
.backgroundColor('#ffffff')
|
||||
.width('100%')
|
||||
})
|
||||
}
|
||||
.height(300)
|
||||
.index(this.swiperIndex)
|
||||
.indicator(false)
|
||||
.onChange((index: number) => {
|
||||
this.swiperIndex = index;
|
||||
})
|
||||
|
||||
Row() {
|
||||
Text(`${this.swiperIndex + 1}/${SWIPER_PICTURE_DATA.length + 1}`)
|
||||
.fontSize(12)
|
||||
.fontColor($r('app.color.white'))
|
||||
}
|
||||
.width(46)
|
||||
.height(24)
|
||||
.borderRadius(12)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.backgroundColor($r('app.color.bg3'))
|
||||
.margin({ right: 16, bottom: 16 })
|
||||
}
|
||||
.width('100%')
|
||||
.height(300)
|
||||
.index(this.swiperIndex)
|
||||
.indicator(false)
|
||||
.onChange((index: number) => {
|
||||
this.swiperIndex = index
|
||||
})
|
||||
.backgroundColor($r('app.color.white'))
|
||||
|
||||
Row() {
|
||||
Text(`${this.swiperIndex + 1}/${SWIPER_PICTURE_DATA.length + 1}`)
|
||||
.fontSize(12)
|
||||
.fontColor($r('app.color.white'))
|
||||
Column() {
|
||||
Information()
|
||||
.margin({ top: 12 })
|
||||
Choice()
|
||||
.margin({ top: 12 })
|
||||
AddressService({ currentLocation: $currentLocation, isPanel: $isPanel })
|
||||
.margin({ top: 12 })
|
||||
Valuation()
|
||||
.margin({ top: 12 })
|
||||
}
|
||||
.width(46)
|
||||
.height(24)
|
||||
.borderRadius(12)
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.backgroundColor($r('app.color.bg3'))
|
||||
.margin({ right: 16, bottom: 16 })
|
||||
.padding({ left: 12, right: 12 })
|
||||
}
|
||||
.id('goodsDetail' + this.goodDetailData['id'])
|
||||
.width('100%')
|
||||
.height(300)
|
||||
.backgroundColor($r('app.color.white'))
|
||||
|
||||
Column() {
|
||||
Information()
|
||||
.margin({ top: 12 })
|
||||
Choice()
|
||||
.margin({ top: 12 })
|
||||
AddressService({ currentLocation: $currentLocation, isPanel: $isPanel })
|
||||
.margin({ top: 12 })
|
||||
Valuation()
|
||||
.margin({ top: 12 })
|
||||
}
|
||||
.padding({ left: 12, right: 12 })
|
||||
}
|
||||
.id('goodsDetail' + this.goodDetailData['id'])
|
||||
.width('100%')
|
||||
}
|
||||
.width('100%')
|
||||
.align(Alignment.Top)
|
||||
.scrollBar(BarState.Off)
|
||||
.padding({ bottom: this.curBp === 'sm' ? 86 : 106 })
|
||||
.onScroll(() => {
|
||||
if (this.activeVideo === 0 && this.openFirst) {
|
||||
if (this.scroller.currentOffset().yOffset > 450) {
|
||||
if (this.isState) {
|
||||
this.isHidden = true
|
||||
this.isState = false
|
||||
.align(Alignment.Top)
|
||||
.scrollBar(BarState.Off)
|
||||
.padding({ bottom: this.curBp === 'sm' ? 86 : 106 })
|
||||
.onScroll(() => {
|
||||
if (this.activeVideo === 0 && this.openFirst) {
|
||||
if (this.scroller.currentOffset().yOffset > 450) {
|
||||
if (this.isState) {
|
||||
this.isHidden = true;
|
||||
this.isState = false;
|
||||
}
|
||||
} else {
|
||||
this.isHidden = false;
|
||||
this.isState = true;
|
||||
}
|
||||
} else {
|
||||
this.isHidden = false
|
||||
this.isState = true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Image($r('app.media.back'))
|
||||
.width(32)
|
||||
.aspectRatio(1)
|
||||
.position({ x: 20, y: 20 })
|
||||
.onClick(() => {
|
||||
router.back()
|
||||
})
|
||||
Image($r("app.media.share"))
|
||||
.width(32)
|
||||
.aspectRatio(1)
|
||||
.position({ x: '100%', y: 20 })
|
||||
.translate({ x: -62, y: 0 })
|
||||
.onClick(() => {
|
||||
this.shareDialog = new CustomDialogController({
|
||||
builder: ButtonDialogBuilder({
|
||||
controller: this.shareDialog,
|
||||
detailTitleText: this.recommend,
|
||||
detailPriceText: '9800',
|
||||
title: this.commodity,
|
||||
srcImage: SRC_IMG
|
||||
}),
|
||||
cancel: undefined,
|
||||
autoCancel: true,
|
||||
alignment: DialogAlignment.Bottom,
|
||||
customStyle: true
|
||||
})
|
||||
this.shareDialog.open()
|
||||
})
|
||||
|
||||
Column({ space: 12 }) {
|
||||
Image($r('app.media.broadcast'))
|
||||
Image($r('app.media.back'))
|
||||
.width(32)
|
||||
.height(32)
|
||||
.aspectRatio(1)
|
||||
.position({ x: 20, y: 20 })
|
||||
.onClick(() => {
|
||||
router.back();
|
||||
})
|
||||
|
||||
Text($r('app.string.broadcast'))
|
||||
.fontSize(14)
|
||||
.fontColor($r('app.color.blank'))
|
||||
}
|
||||
.id('directVideo')
|
||||
.width(62)
|
||||
.height(78)
|
||||
.borderWidth(0.5)
|
||||
.borderColor($r('app.color.border'))
|
||||
.borderRadius(16)
|
||||
.padding(6)
|
||||
.backgroundColor($r('app.color.light_white'))
|
||||
.position({ x: '100%', y: 160 })
|
||||
.translate({ x: -82, y: 0 })
|
||||
.onClick(() => {
|
||||
router.push({ url: 'pages/LivePage' })
|
||||
})
|
||||
Image($r("app.media.share"))
|
||||
.width(32)
|
||||
.aspectRatio(1)
|
||||
.position({ x: '100%', y: 20 })
|
||||
.translate({ x: -62, y: 0 })
|
||||
.onClick(() => {
|
||||
this.shareDialog = new CustomDialogController({
|
||||
builder: ButtonDialogBuilder({
|
||||
controller: this.shareDialog,
|
||||
detailTitleText: this.recommend,
|
||||
detailPriceText: '9800',
|
||||
title: this.commodity,
|
||||
srcImage: SRC_IMG
|
||||
}),
|
||||
cancel: undefined,
|
||||
autoCancel: true,
|
||||
alignment: DialogAlignment.Bottom,
|
||||
customStyle: true
|
||||
})
|
||||
this.shareDialog.open()
|
||||
})
|
||||
|
||||
BottomNavigation({ goodItemData: $goodDetailData })
|
||||
.position({ x: 0, y: '100%' })
|
||||
.translate({ x: 0, y: -56 })
|
||||
SmallVideo({ isHidden: $isHidden, isCancel: $isCancel })
|
||||
.position({ x: '100%', y: '60%' })
|
||||
.translate({ x: -180, y: 0 })
|
||||
Panel(this.isPanel) {
|
||||
Location({ isPanel: $isPanel, currentLocation: $currentLocation })
|
||||
Column({ space: 12 }) {
|
||||
Image($r('app.media.broadcast'))
|
||||
.width(32)
|
||||
.height(32)
|
||||
|
||||
Text($r('app.string.broadcast'))
|
||||
.fontSize(14)
|
||||
.fontColor($r('app.color.blank'))
|
||||
}
|
||||
.id('directVideo')
|
||||
.width(62)
|
||||
.height(78)
|
||||
.borderWidth(0.5)
|
||||
.borderColor($r('app.color.border'))
|
||||
.borderRadius(16)
|
||||
.padding(6)
|
||||
.backgroundColor($r('app.color.light_white'))
|
||||
.position({ x: '100%', y: 160 })
|
||||
.translate({ x: -82, y: 0 })
|
||||
.onClick(() => {
|
||||
router.pushUrl({ url: 'pages/LivePage' });
|
||||
})
|
||||
|
||||
BottomNavigation({
|
||||
goodItemData: $goodDetailData,
|
||||
animateAppear: $animateAppear,
|
||||
animateScale: $animateAppear,
|
||||
animatePath: $animatePath
|
||||
})
|
||||
.position({ x: 0, y: '100%' })
|
||||
.translate({ x: 0, y: -56 })
|
||||
SmallVideo({ isHidden: $isHidden, isCancel: $isCancel })
|
||||
.position({ x: '100%', y: '60%' })
|
||||
.translate({ x: -180, y: 0 })
|
||||
Panel(this.isPanel) {
|
||||
Location({ isPanel: $isPanel, currentLocation: $currentLocation })
|
||||
}
|
||||
.mode(PanelMode.Half)
|
||||
.dragBar(false)
|
||||
.halfHeight(this.curBp === 'sm' ? 650 : 530)
|
||||
.miniHeight(0)
|
||||
.onChange(() => {
|
||||
this.isPanel = false
|
||||
})
|
||||
|
||||
Column() {
|
||||
Image(this.goodDetailData['uri'])
|
||||
.borderRadius(this.animateScale ? 1000 : 0)
|
||||
.transition(TransitionEffect.OPACITY)
|
||||
}
|
||||
.width('100%')
|
||||
.height(300)
|
||||
.enabled(this.animatePath)
|
||||
.visibility(this.animateAppear ? 0 : 1)
|
||||
.scale(this.animateScale ? (this.animatePath ? { x: 0.1, y: 0.1, centerY: '50%' } : {
|
||||
x: 0.2,
|
||||
y: 0.2,
|
||||
centerY: '50%'
|
||||
}) : { x: 1, y: 1, centerY: '100%' })
|
||||
.opacity(this.animatePath ? 0.3 : 1)
|
||||
.translate(this.animatePath ? { x: -80, y: 100 } : { x: 0 })
|
||||
.motionPath({ path: 'Mstart.x start.y C -200 50, -150 200, end.x end.y', from: 0.0, to: 1.0, rotatable: false })
|
||||
}
|
||||
.height('100%')
|
||||
.width('100%')
|
||||
.backgroundColor($r('app.color.divider'))
|
||||
|
||||
// 通过isShowImage变量开关控制页面跳转动效,默认为true
|
||||
if (this.isShowImage) {
|
||||
Column() {
|
||||
Image(this.goodDetailData['uri'])
|
||||
.objectFit(ImageFit.Contain)
|
||||
.sharedTransition('goods' + this.goodDetailData['id'], { duration: 600, curve: Curve.Linear, delay: 100 })
|
||||
.onComplete(() => {
|
||||
setTimeout(() => {
|
||||
this.isShowImage = false;
|
||||
}, 800)
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.aspectRatio(1.12)
|
||||
.backgroundColor('#ffffff')
|
||||
}
|
||||
.mode(PanelMode.Half)
|
||||
.dragBar(false)
|
||||
.halfHeight(this.curBp === 'sm' ? 650 : 530)
|
||||
.miniHeight(0)
|
||||
.onChange(() => {
|
||||
this.isPanel = false
|
||||
})
|
||||
}
|
||||
.height('100%')
|
||||
.width('100%')
|
||||
.backgroundColor($r('app.color.divider'))
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
let context: Context = getContext(this)
|
||||
this.currentLocation = context.resourceManager.getStringSync($r('app.string.address').id)
|
||||
this.recommend = context.resourceManager.getStringSync($r('app.string.recommend').id)
|
||||
this.commodity = context.resourceManager.getStringSync($r('app.string.commodity').id)
|
||||
let context: Context = getContext(this);
|
||||
this.currentLocation = context.resourceManager.getStringSync($r('app.string.address').id);
|
||||
this.recommend = context.resourceManager.getStringSync($r('app.string.recommend').id);
|
||||
this.commodity = context.resourceManager.getStringSync($r('app.string.commodity').id);
|
||||
}
|
||||
}
|
@ -13,14 +13,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { SwiperPicturesModel, CommentModel } from '../model/DetailMode'
|
||||
import { SwiperPicturesModel, CommentModel } from '../model/DetailMode';
|
||||
|
||||
export const SWIPER_PICTURE_DATA: Array<SwiperPicturesModel> = [
|
||||
{ src: $r('app.media.swiper1') },
|
||||
{ src: $r('app.media.swiper2') },
|
||||
{ src: $r('app.media.swiper3') },
|
||||
{ src: $r('app.media.swiper4') }
|
||||
]
|
||||
];
|
||||
|
||||
export const COMMENT_DATA: Array<CommentModel> = [
|
||||
{
|
||||
@ -53,7 +53,7 @@ export const COMMENT_DATA: Array<CommentModel> = [
|
||||
img: $r('app.media.star'),
|
||||
text: '和描述相符很喜欢,做工细致,颜色好看,原装正品'
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
export const CITY_DATA = [
|
||||
{ name: 'A', city: [{ name: '安徽', city: ['亳州', '安庆'] }] },
|
||||
@ -71,8 +71,8 @@ export const CITY_DATA = [
|
||||
{ name: 'X', city: ['西藏', '新疆'] },
|
||||
{ name: 'Y', city: ['云南'] },
|
||||
{ name: 'Z', city: [{ name: '浙江', city: ['宁波', '杭州'] }] }
|
||||
]
|
||||
];
|
||||
|
||||
export const HOT_CITY = ['北京', '上海', '广州', '深圳', '杭州', '南京', '苏州', '天津', '武汉', '长沙', '重庆', '成都']
|
||||
export const HOT_CITY = ['北京', '上海', '广州', '深圳', '杭州', '南京', '苏州', '天津', '武汉', '长沙', '重庆', '成都'];
|
||||
|
||||
export const TAB_VALUE = ['A', 'B', 'C', 'F', 'G', 'H', 'J', 'L', 'N', 'Q', 'S', 'T', 'X', 'Y', 'Z']
|
||||
export const TAB_VALUE = ['A', 'B', 'C', 'F', 'G', 'H', 'J', 'L', 'N', 'Q', 'S', 'T', 'X', 'Y', 'Z'];
|
@ -15,26 +15,26 @@
|
||||
|
||||
export class SwiperPicturesModel {
|
||||
constructor(public src: Resource) {
|
||||
this.src = src
|
||||
this.src = src;
|
||||
}
|
||||
}
|
||||
|
||||
export class CommentModel {
|
||||
constructor(public url: Resource, public user: string, public img: Resource, public text: string) {
|
||||
this.url = url
|
||||
this.user = user
|
||||
this.img = img
|
||||
this.text = text
|
||||
this.url = url;
|
||||
this.user = user;
|
||||
this.img = img;
|
||||
this.text = text;
|
||||
}
|
||||
}
|
||||
|
||||
export class ProductDataModel {
|
||||
constructor(public id: number, public uri: Resource, public title: Resource, public info: Resource, public labels: Resource, public price: Resource) {
|
||||
this.id = id
|
||||
this.uri = uri
|
||||
this.info = info
|
||||
this.title = title
|
||||
this.labels = labels
|
||||
this.price = price
|
||||
this.id = id;
|
||||
this.uri = uri;
|
||||
this.info = info;
|
||||
this.title = title;
|
||||
this.labels = labels;
|
||||
this.price = price;
|
||||
}
|
||||
}
|
@ -13,33 +13,33 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import hilog from '@ohos.hilog'
|
||||
import hilog from '@ohos.hilog';
|
||||
|
||||
class Logger {
|
||||
private domain: number
|
||||
private prefix: string
|
||||
private format: string = '%{public}s, %{public}s'
|
||||
private domain: number;
|
||||
private prefix: string;
|
||||
private format: string = '%{public}s, %{public}s';
|
||||
|
||||
constructor(prefix: string) {
|
||||
this.prefix = prefix
|
||||
this.domain = 0xFF00
|
||||
this.format.toUpperCase()
|
||||
this.prefix = prefix;
|
||||
this.domain = 0xFF00;
|
||||
this.format.toUpperCase();
|
||||
}
|
||||
|
||||
debug(...args: any[]) {
|
||||
hilog.debug(this.domain, this.prefix, this.format, args)
|
||||
hilog.debug(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
|
||||
info(...args: any[]) {
|
||||
hilog.info(this.domain, this.prefix, this.format, args)
|
||||
hilog.info(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
|
||||
warn(...args: any[]) {
|
||||
hilog.warn(this.domain, this.prefix, this.format, args)
|
||||
hilog.warn(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
|
||||
error(...args: any[]) {
|
||||
hilog.error(this.domain, this.prefix, this.format, args)
|
||||
hilog.error(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,6 @@
|
||||
*/
|
||||
|
||||
export class EmitterConst {
|
||||
static readonly DIALOG_EVENT_ID = 1001
|
||||
static readonly ADD_EVENT_ID = 1025
|
||||
static readonly DIALOG_EVENT_ID: number = 1001;
|
||||
static readonly ADD_EVENT_ID: number = 1025;
|
||||
}
|
@ -13,50 +13,60 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import emitter from '@ohos.events.emitter'
|
||||
import { EmitterConst } from '../../common/EmitterConst'
|
||||
import emitter from '@ohos.events.emitter';
|
||||
import { EmitterConst } from '../../common/EmitterConst';
|
||||
|
||||
class EventsId {
|
||||
eventId: number;
|
||||
|
||||
constructor(eventId: number) {
|
||||
this.eventId = eventId;
|
||||
}
|
||||
}
|
||||
|
||||
class EventsData {
|
||||
data: Data;
|
||||
|
||||
constructor(data: Data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
class Data {
|
||||
id: number
|
||||
|
||||
constructor(id: number) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
export class EmitterClass {
|
||||
shoppingCartGoodsList: { data: { id: number } }[] = []
|
||||
shoppingCartGoodsList: EventsData[] = [];
|
||||
|
||||
// 单次订阅回调
|
||||
public showEventsDialog(callback) {
|
||||
let dialogShowEventsId = {
|
||||
eventId: EmitterConst.DIALOG_EVENT_ID
|
||||
}
|
||||
let dialogShowEventsData = {
|
||||
data: {
|
||||
id: EmitterConst.DIALOG_EVENT_ID
|
||||
}
|
||||
}
|
||||
public showEventsDialog(callback: () => void): void {
|
||||
let dialogShowEventsId: EventsId = new EventsId(EmitterConst.DIALOG_EVENT_ID);
|
||||
let dialogShowEventsData: EventsData = new EventsData(new Data(EmitterConst.DIALOG_EVENT_ID));
|
||||
// 单次订阅事件--广告
|
||||
emitter.once(dialogShowEventsId, callback)
|
||||
emitter.once(dialogShowEventsId, callback);
|
||||
// 事件发布
|
||||
emitter.emit(dialogShowEventsId, dialogShowEventsData)
|
||||
emitter.emit(dialogShowEventsId, dialogShowEventsData);
|
||||
}
|
||||
|
||||
// 持久化订阅的事件回调
|
||||
public setShoppingCartGoodsList(callback: (eventData) => void) {
|
||||
let addGoodDataId = {
|
||||
eventId: EmitterConst.ADD_EVENT_ID
|
||||
}
|
||||
public setShoppingCartGoodsList(callback): void {
|
||||
let addGoodDataId: EventsId = new EventsId(EmitterConst.ADD_EVENT_ID);
|
||||
// 以持久化方式订阅购物车添加事件并接收事件回调
|
||||
emitter.off(EmitterConst.ADD_EVENT_ID)
|
||||
emitter.on(addGoodDataId, (eventData) => {
|
||||
callback(eventData)
|
||||
})
|
||||
emitter.off(EmitterConst.ADD_EVENT_ID);
|
||||
emitter.on(addGoodDataId, (eventData: EventsData) => {
|
||||
callback(eventData);
|
||||
});
|
||||
}
|
||||
|
||||
public addGoods(goodId) {
|
||||
let addToShoppingCartId = {
|
||||
eventId: EmitterConst.ADD_EVENT_ID
|
||||
}
|
||||
let shoppingCartData = {
|
||||
data: {
|
||||
id: goodId
|
||||
}
|
||||
}
|
||||
public addGoods(goodId: number): void {
|
||||
let addToShoppingCartId: EventsId = new EventsId(EmitterConst.ADD_EVENT_ID);
|
||||
let shoppingCartData: EventsData = new EventsData(new Data(goodId));
|
||||
// 持续订阅发布事件
|
||||
emitter.emit(addToShoppingCartId, shoppingCartData)
|
||||
emitter.emit(addToShoppingCartId, shoppingCartData);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export class EmitterConst {
|
||||
static readonly DIALOG_EVENT_ID: number = 1001;
|
||||
static readonly ADD_EVENT_ID: number = 1025;
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import emitter from '@ohos.events.emitter';
|
||||
import { EmitterConst } from '../../common/EmitterConst';
|
||||
|
||||
class EventsId {
|
||||
eventId: number;
|
||||
|
||||
constructor(eventId: number) {
|
||||
this.eventId = eventId;
|
||||
}
|
||||
}
|
||||
|
||||
class EventsData {
|
||||
data: Data;
|
||||
|
||||
constructor(data: Data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
class Data {
|
||||
id: number
|
||||
|
||||
constructor(id: number) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
export class EmitterClass {
|
||||
shoppingCartGoodsList: EventsData[] = [];
|
||||
|
||||
// 单次订阅回调
|
||||
public showEventsDialog(callback: () => void): void {
|
||||
let dialogShowEventsId: EventsId = new EventsId(EmitterConst.DIALOG_EVENT_ID);
|
||||
let dialogShowEventsData: EventsData = new EventsData(new Data(EmitterConst.DIALOG_EVENT_ID));
|
||||
// 单次订阅事件--广告
|
||||
emitter.once(dialogShowEventsId, callback);
|
||||
// 事件发布
|
||||
emitter.emit(dialogShowEventsId, dialogShowEventsData);
|
||||
}
|
||||
|
||||
// 持久化订阅的事件回调
|
||||
public setShoppingCartGoodsList(callback): void {
|
||||
let addGoodDataId: EventsId = new EventsId(EmitterConst.ADD_EVENT_ID);
|
||||
// 以持久化方式订阅购物车添加事件并接收事件回调
|
||||
emitter.off(EmitterConst.ADD_EVENT_ID);
|
||||
emitter.on(addGoodDataId, (eventData: EventsData) => {
|
||||
callback(eventData);
|
||||
});
|
||||
}
|
||||
|
||||
public addGoods(goodId: number): void {
|
||||
let addToShoppingCartId: EventsId = new EventsId(EmitterConst.ADD_EVENT_ID);
|
||||
let shoppingCartData: EventsData = new EventsData(new Data(goodId));
|
||||
// 持续订阅发布事件
|
||||
emitter.emit(addToShoppingCartId, shoppingCartData);
|
||||
}
|
||||
}
|
@ -13,42 +13,57 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import router from '@ohos.router'
|
||||
import Http from '@ohos/http'
|
||||
import { PRODUCT_DATA } from '../../mock/ProductsData'
|
||||
import { GoodResponse } from '../../model/GoodsModel'
|
||||
import { Products_Data } from '../../mock/ProductsData'
|
||||
import Http from '@ohos/http';
|
||||
import { PRODUCT_DATA } from '../../mock/ProductsData';
|
||||
import { GoodResponse } from '../../model/GoodsModel';
|
||||
import { Products_Data } from '../../mock/ProductsData';
|
||||
import router from '@ohos.router';
|
||||
|
||||
@Component
|
||||
export struct GoodsList {
|
||||
@State getDataFromHttp: boolean = false
|
||||
private url: string
|
||||
private option: object
|
||||
@State productsData: GoodResponse = Products_Data
|
||||
@State getDataFromHttp: boolean = false;
|
||||
private url: string;
|
||||
private option: object;
|
||||
@State productsData: GoodResponse = Products_Data;
|
||||
@State active: boolean = false;
|
||||
|
||||
async aboutToAppear() {
|
||||
Http.setUrl(this.url)
|
||||
Http.setOptions(this.option)
|
||||
this.getDataFromHttp = false
|
||||
let info = await Http.request()
|
||||
Http.setUrl(this.url);
|
||||
Http.setOptions(this.option);
|
||||
this.getDataFromHttp = false;
|
||||
let info = await Http.request();
|
||||
if (info.responseCode === 200 && info.result !== undefined) {
|
||||
this.getDataFromHttp = true
|
||||
this.productsData = JSON.parse(info.result.toString())
|
||||
this.getDataFromHttp = true;
|
||||
this.productsData = JSON.parse(info.result.toString());
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
GridRow({ gutter: { x: vp2px(8), y: vp2px(8) }, }) {
|
||||
GridRow({
|
||||
gutter: {
|
||||
x: vp2px(8),
|
||||
y: vp2px(8)
|
||||
},
|
||||
}) {
|
||||
ForEach(this.getDataFromHttp ? this.productsData.data.records : PRODUCT_DATA, item => {
|
||||
GridCol({ span: { sm: 6, md: 6, lg: 4 } }) {
|
||||
GridCol({
|
||||
span: {
|
||||
sm: 6,
|
||||
md: 6,
|
||||
lg: 4
|
||||
}
|
||||
}) {
|
||||
Column() {
|
||||
// 此处的商品图片需要根据父组件的宽度而变化,这里使用65%
|
||||
|
||||
// 方案二:使用router跳转页面,配合共享元素动画
|
||||
Image(item.uri)
|
||||
.id('goods' + item.id)
|
||||
.width('70%')
|
||||
.aspectRatio(1)
|
||||
.clip(true)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ bottom: 12 })
|
||||
.sharedTransition('goods' + item.id, { duration: 600, curve: Curve.Linear, delay: 100 })
|
||||
|
||||
Column() {
|
||||
Text(item.title)
|
||||
@ -57,14 +72,21 @@ export struct GoodsList {
|
||||
|
||||
Text(item.info)
|
||||
.width('100%')
|
||||
.fontSize(14)
|
||||
.margin({ top: 6 })
|
||||
.fontSize(12)
|
||||
.fontColor("#858184")
|
||||
.margin({
|
||||
top: 6
|
||||
})
|
||||
|
||||
Text(item.price)
|
||||
.fontColor($r('app.color.pink'))
|
||||
.fontSize(16)
|
||||
.margin({ top: 6 })
|
||||
.offset({ x: -3 }) // 因为¥是中文字符,上面的xx是中文字符,占的宽度不一样,所以需要对齐,添加offset
|
||||
.margin({
|
||||
top: 6
|
||||
})
|
||||
.offset({
|
||||
x: -3
|
||||
}) // 因为¥是中文字符,上面的xx是中文字符,占的宽度不一样,所以需要对齐,添加offset
|
||||
|
||||
Column() {
|
||||
Text(item.labels)
|
||||
@ -72,17 +94,27 @@ export struct GoodsList {
|
||||
.fontColor($r('app.color.white'))
|
||||
}
|
||||
.borderRadius(6)
|
||||
.padding({ left: 6, right: 6, top: 4, bottom: 4 })
|
||||
.padding({
|
||||
left: 6,
|
||||
right: 6,
|
||||
top: 4,
|
||||
bottom: 4
|
||||
})
|
||||
.backgroundColor($r('app.color.pink'))
|
||||
.margin({ top: 6 })
|
||||
.margin({
|
||||
top: 6
|
||||
})
|
||||
}
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
}
|
||||
.borderRadius(10)
|
||||
.padding(12)
|
||||
.backgroundColor($r('app.color.white'))
|
||||
|
||||
// 方案二:使用正常router跳转,配合共享元素动画
|
||||
.onClick(() => {
|
||||
router.push({
|
||||
this.active = true;
|
||||
router.pushUrl({
|
||||
url: 'pages/Detail',
|
||||
params: { goodId: item.id, goodItem: item }
|
||||
})
|
||||
@ -90,9 +122,12 @@ export struct GoodsList {
|
||||
}
|
||||
}, item => item.id.toString())
|
||||
}
|
||||
.padding({ left: 12, right: 12 })
|
||||
.onAreaChange((oldArea: Area, newArea: Area) => {
|
||||
AppStorage.SetOrCreate('listHeight', newArea.height as number)
|
||||
.padding({
|
||||
left: 12,
|
||||
right: 12
|
||||
})
|
||||
.onAreaChange((newArea: Area) => {
|
||||
AppStorage.setOrCreate('listHeight', newArea.height as number);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,26 +12,29 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TITLE_BAR_DATA } from '../../mock/ProductsData'
|
||||
import { GoodsList } from '../good/GoodsList'
|
||||
import { SwiperComponent } from './Swiper'
|
||||
import { Url } from '../../main/NavigationHomePage';
|
||||
import { TITLE_BAR_DATA } from '../../mock/ProductsData';
|
||||
import { TitleBarModel } from '../../model/GoodsModel';
|
||||
import { GoodsList } from '../good/GoodsList';
|
||||
import { SwiperComponent } from './Swiper';
|
||||
|
||||
@Component
|
||||
export struct HomePageContent {
|
||||
@State tabsIndex: number = 0
|
||||
private url: string
|
||||
private controller: TabsController = new TabsController()
|
||||
@StorageLink('listHeight') listHeight: number = 100
|
||||
@StorageLink('curBp') curBp: string = 'sm'
|
||||
@State tabsIndex: number = 0;
|
||||
private url: string;
|
||||
private controller: TabsController = new TabsController();
|
||||
@StorageLink('listHeight') listHeight: number = 100;
|
||||
@StorageLink('curBp') curBp: string = 'sm';
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
SwiperComponent()
|
||||
.width('100%')
|
||||
Row() {
|
||||
ForEach(TITLE_BAR_DATA, item => {
|
||||
Column({ space: 6 }) {
|
||||
ForEach(TITLE_BAR_DATA, (item: TitleBarModel) => {
|
||||
Column({
|
||||
space: 6
|
||||
}) {
|
||||
Text(item.title)
|
||||
.fontSize(16)
|
||||
.fontWeight(400)
|
||||
@ -43,31 +46,36 @@ export struct HomePageContent {
|
||||
.fontColor(this.tabsIndex === item.id ? $r('app.color.pink') : Color.Black)
|
||||
}
|
||||
.onClick(() => {
|
||||
this.tabsIndex = item.id
|
||||
this.controller.changeIndex(item.id)
|
||||
this.tabsIndex = item.id;
|
||||
this.controller.changeIndex(item.id);
|
||||
})
|
||||
}, item => item.id.toString())
|
||||
}, (item: TitleBarModel) => item.id.toString())
|
||||
}
|
||||
.width('100%')
|
||||
.padding({ top: 12, bottom: 12, left: 20, right: 20 })
|
||||
.padding({
|
||||
top: 12,
|
||||
bottom: 12,
|
||||
left: 20,
|
||||
right: 20
|
||||
})
|
||||
.justifyContent(FlexAlign.SpaceBetween)
|
||||
|
||||
// 主页下半部分商品展示--全部、精选、新品、实惠
|
||||
Tabs({ controller: this.controller }) {
|
||||
TabContent() {
|
||||
GoodsList({ url: this.url })
|
||||
GoodsList(new Url(this.url));
|
||||
}
|
||||
|
||||
TabContent() {
|
||||
GoodsList({ url: this.url })
|
||||
GoodsList(new Url(this.url));
|
||||
}
|
||||
|
||||
TabContent() {
|
||||
GoodsList({ url: this.url })
|
||||
GoodsList(new Url(this.url));
|
||||
}
|
||||
|
||||
TabContent() {
|
||||
GoodsList({ url: this.url })
|
||||
GoodsList(new Url(this.url));
|
||||
}
|
||||
}
|
||||
.height(this.listHeight + 12)
|
||||
|
@ -13,26 +13,31 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NAV_DATA } from '../../mock/ProductsData'
|
||||
import { TitleBarComponent } from '../../components/home/TitleBar'
|
||||
import { HomePageContent } from '../../components/home/HomePageContent'
|
||||
import { NAV_DATA } from '../../mock/ProductsData';
|
||||
import { TitleBarComponent } from '../../components/home/TitleBar';
|
||||
import { HomePageContent } from '../../components/home/HomePageContent';
|
||||
import { NavDataModel } from '../../model/GoodsModel';
|
||||
import { Url } from '../../main/NavigationHomePage';
|
||||
|
||||
@Component
|
||||
export struct MainPage {
|
||||
@State navTabsIndex: number = 0
|
||||
private url: string
|
||||
private navController: TabsController = new TabsController()
|
||||
@StorageProp('curBp') curBp: string = 'sm'
|
||||
@State navTabsIndex: number = 0;
|
||||
private url: string;
|
||||
private navController: TabsController = new TabsController();
|
||||
@StorageProp('curBp') curBp: string = 'sm';
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
TitleBarComponent()
|
||||
.backgroundImageSize({ width: '100%', height: '100%' })
|
||||
.backgroundImageSize({
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
})
|
||||
.backgroundImage($r('app.media.title_bar'), ImageRepeat.NoRepeat)
|
||||
Scroll() {
|
||||
Column() {
|
||||
Row() {
|
||||
ForEach(NAV_DATA, item => {
|
||||
ForEach(NAV_DATA, (item: NavDataModel) => {
|
||||
Row() {
|
||||
Text(item.navData)
|
||||
.fontSize(16)
|
||||
@ -42,10 +47,10 @@ export struct MainPage {
|
||||
}
|
||||
.align(Alignment.Center)
|
||||
.onClick(() => {
|
||||
this.navTabsIndex = item.id
|
||||
this.navController.changeIndex(item.id)
|
||||
this.navTabsIndex = item.id;
|
||||
this.navController.changeIndex(item.id);
|
||||
})
|
||||
}, item => item.id.toString())
|
||||
}, (item: NavDataModel) => item.id.toString())
|
||||
|
||||
Row() {
|
||||
Divider()
|
||||
@ -57,24 +62,31 @@ export struct MainPage {
|
||||
.width(16)
|
||||
.height(16)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 4 })
|
||||
.margin({
|
||||
left: 4
|
||||
})
|
||||
Text($r('app.string.classification'))
|
||||
.fontSize(16)
|
||||
.opacity(0.8)
|
||||
.fontColor($r('app.color.white'))
|
||||
.margin({ left: 2 })
|
||||
.margin({
|
||||
left: 2
|
||||
})
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.justifyContent(FlexAlign.SpaceBetween)
|
||||
.padding(12)
|
||||
|
||||
HomePageContent({ url: this.url })
|
||||
HomePageContent(new Url(this.url));
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundImageSize({ width: '100%', height: 200 })
|
||||
.backgroundImageSize({
|
||||
width: '100%',
|
||||
height: 200
|
||||
})
|
||||
.backgroundImage($r('app.media.home_background'), ImageRepeat.NoRepeat)
|
||||
.scrollBar(BarState.Off)
|
||||
.flexGrow(1)
|
||||
|
@ -13,29 +13,36 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { GoodsList } from '../good/GoodsList'
|
||||
import { NEW_PRODUCT_TITLE_BAR_DATA, SWIPER_DATA } from '../../mock/ProductsData'
|
||||
import { GoodsList } from '../good/GoodsList';
|
||||
import { NEW_PRODUCT_TITLE_BAR_DATA, SWIPER_DATA } from '../../mock/ProductsData';
|
||||
import { NewProductTitleBarModel, SwiperModel } from '../../model/GoodsModel';
|
||||
import { Url } from '../../main/NavigationHomePage';
|
||||
|
||||
@Component
|
||||
export struct NewProduct {
|
||||
@State tabsIndex: number = 0
|
||||
@StorageProp('curBp') curBp: string = 'md'
|
||||
private url: string
|
||||
private controller: TabsController = new TabsController()
|
||||
@State tabsIndex: number = 0;
|
||||
@StorageProp('curBp') curBp: string = 'md';
|
||||
private url: string;
|
||||
private controller: TabsController = new TabsController();
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Scroll() {
|
||||
Column() {
|
||||
Swiper() {
|
||||
ForEach(SWIPER_DATA, item => {
|
||||
ForEach(SWIPER_DATA, (item: SwiperModel) => {
|
||||
Navigator({ target: 'pages/detail' }) {
|
||||
Image(item.img)
|
||||
.objectFit(ImageFit.Cover)
|
||||
.width('100%')
|
||||
.borderRadius({ bottomLeft: 12, bottomRight: 12, topLeft: 0, topRight: 0 })
|
||||
.borderRadius({
|
||||
bottomLeft: 12,
|
||||
bottomRight: 12,
|
||||
topLeft: 0,
|
||||
topRight: 0
|
||||
})
|
||||
}
|
||||
}, item => item.id.toString())
|
||||
}, (item: SwiperModel) => item.id.toString())
|
||||
}
|
||||
.width('100%')
|
||||
.height(186)
|
||||
@ -43,10 +50,17 @@ export struct NewProduct {
|
||||
.itemSpace(10)
|
||||
.displayCount(this.curBp === 'sm' ? 1 : this.curBp === 'md' ? 2 : 3)
|
||||
// 这里的导航点需要位于swiper的右下角,此处使用right:24
|
||||
.indicatorStyle({ right: 24, selectedColor: $r('app.color.point'), color: $r('app.color.point_selected') })
|
||||
.indicator(
|
||||
Indicator
|
||||
.dot()
|
||||
.selectedItemWidth(10)
|
||||
.right(24)
|
||||
.color($r('app.color.point_selected'))
|
||||
.selectedColor($r('app.color.point'))
|
||||
)
|
||||
|
||||
Row() {
|
||||
ForEach(NEW_PRODUCT_TITLE_BAR_DATA, item => {
|
||||
ForEach(NEW_PRODUCT_TITLE_BAR_DATA, (item: NewProductTitleBarModel) => {
|
||||
Column() {
|
||||
Text(item.title)
|
||||
.fontSize(16)
|
||||
@ -57,10 +71,10 @@ export struct NewProduct {
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.align(Alignment.Center)
|
||||
.onClick(() => {
|
||||
this.tabsIndex = item.id
|
||||
this.controller.changeIndex(item.id)
|
||||
this.tabsIndex = item.id;
|
||||
this.controller.changeIndex(item.id);
|
||||
})
|
||||
}, item => item.id.toString())
|
||||
}, (item: NewProductTitleBarModel) => item.id.toString())
|
||||
|
||||
Row() {
|
||||
Image($r('app.media.line_navclass'))
|
||||
@ -71,21 +85,32 @@ export struct NewProduct {
|
||||
.width(16)
|
||||
.height(16)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 4 })
|
||||
.margin({
|
||||
left: 4
|
||||
})
|
||||
Text($r('app.string.classification'))
|
||||
.fontSize(16)
|
||||
.opacity(0.6)
|
||||
.fontColor($r('app.color.blank'))
|
||||
.margin({ left: 2 })
|
||||
.margin({
|
||||
left: 2
|
||||
})
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.padding({ left: 12, right: 12, bottom: 16, top: 16 })
|
||||
.padding({
|
||||
left: 12,
|
||||
right: 12,
|
||||
bottom: 16,
|
||||
top: 16
|
||||
})
|
||||
.justifyContent(FlexAlign.SpaceBetween)
|
||||
|
||||
GoodsList({ url: this.url })
|
||||
GoodsList(new Url(this.url));
|
||||
}
|
||||
.padding({ bottom: 12 })
|
||||
.padding({
|
||||
bottom: 12
|
||||
})
|
||||
}
|
||||
.layoutWeight(1)
|
||||
.scrollBar(BarState.Off)
|
||||
|
@ -13,16 +13,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Cart } from '../shoppingCart/Cart'
|
||||
import { FavorGoodList } from '../shoppingCart/FavorGoodlist'
|
||||
import { ProductDataModel } from '../../model/GoodsModel'
|
||||
import { Cart } from '../shoppingCart/Cart';
|
||||
import { FavorGoodList } from '../shoppingCart/FavorGoodlist';
|
||||
import { ProductDataModel } from '../../model/GoodsModel';
|
||||
import { Url } from '../../main/NavigationHomePage';
|
||||
|
||||
@Preview
|
||||
@Component
|
||||
export struct ShopCart {
|
||||
private url: string
|
||||
@StorageLink('goodsListHeight') goodsListHeight: number = 100
|
||||
@State shoppingCartGoodsList: ProductDataModel[] = AppStorage.Get('shoppingCartGoodsList')
|
||||
private url: string;
|
||||
@StorageLink('goodsListHeight') goodsListHeight: number = 100;
|
||||
@State shoppingCartGoodsList: ProductDataModel[] = AppStorage.get('shoppingCartGoodsList');
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
@ -43,25 +44,39 @@ export struct ShopCart {
|
||||
.opacity(0.6)
|
||||
}
|
||||
.width('100%')
|
||||
.margin({ top: 16, bottom: 12 })
|
||||
.margin({
|
||||
top: 16,
|
||||
bottom: 12
|
||||
})
|
||||
|
||||
Cart({ shoppingCartGoodsListToCart: $shoppingCartGoodsList })
|
||||
Cart({ shoppingCartGoodsListToCart: $shoppingCartGoodsList });
|
||||
}
|
||||
.width('100%')
|
||||
.padding({ right: 12 })
|
||||
.padding({
|
||||
right: 12
|
||||
})
|
||||
.backgroundColor($r('app.color.divider'))
|
||||
|
||||
Text($r('app.string.guess_you_like'))
|
||||
.fontSize(20)
|
||||
.fontColor($r('app.color.blank'))
|
||||
.padding({ top: 24, bottom: 20, left: 12 })
|
||||
FavorGoodList({ url: this.url })
|
||||
.padding({
|
||||
top: 24,
|
||||
bottom: 20,
|
||||
left: 12
|
||||
})
|
||||
FavorGoodList(new Url(this.url));
|
||||
}
|
||||
.padding({ bottom: 12 })
|
||||
.padding({
|
||||
bottom: 12
|
||||
})
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
}
|
||||
.layoutWeight(1)
|
||||
.padding({ left: 12, right: 12 })
|
||||
.padding({
|
||||
left: 12,
|
||||
right: 12
|
||||
})
|
||||
.scrollBar(BarState.Off)
|
||||
.align(Alignment.Top)
|
||||
|
||||
|
@ -13,30 +13,124 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { INDEX_DATA } from '../../mock/ProductsData'
|
||||
import { INDEX_DATA } from '../../mock/ProductsData';
|
||||
import { SwiperModel } from '../../model/GoodsModel';
|
||||
|
||||
const isNewSlide: boolean = true;
|
||||
|
||||
@Component
|
||||
export struct SwiperComponent {
|
||||
@StorageProp('curBp') curBp: string = 'md'
|
||||
@StorageProp('curBp') curBp: string = 'md';
|
||||
@State currentIndex: number = 2;
|
||||
|
||||
build() {
|
||||
Swiper() {
|
||||
ForEach(INDEX_DATA, item => {
|
||||
Image(item.img)
|
||||
.objectFit(ImageFit.Cover)
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.borderRadius(16)
|
||||
})
|
||||
/**
|
||||
* Get the image offset coefficients.
|
||||
*
|
||||
* @param index
|
||||
* @returns offset coefficients
|
||||
*/
|
||||
getImgCoefficients(index: number): number {
|
||||
let coefficient: number = this.currentIndex - index;
|
||||
let tempCoefficient: number = Math.abs(coefficient);
|
||||
if (tempCoefficient <= 2) {
|
||||
return coefficient;
|
||||
}
|
||||
.padding({ left: 12, right: 12 })
|
||||
.height(170)
|
||||
.autoPlay(true)
|
||||
.itemSpace(20)
|
||||
.displayCount(this.curBp === 'sm' ? 1 : this.curBp === 'md' ? 2 : 3)
|
||||
.indicatorStyle({
|
||||
selectedColor: $r('app.color.red'),
|
||||
color: $r('app.color.white')
|
||||
let dataLength: number = INDEX_DATA.length;
|
||||
let tempOffset: number = dataLength - tempCoefficient;
|
||||
if (tempOffset <= 2) {
|
||||
if (coefficient > 0) {
|
||||
return -tempOffset;
|
||||
}
|
||||
return tempOffset;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image offset.
|
||||
*
|
||||
* @param index
|
||||
* @returns offset
|
||||
*/
|
||||
getOffSetX(index: number): number {
|
||||
let offsetIndex: number = this.getImgCoefficients(index);
|
||||
let tempOffset: number = Math.abs(offsetIndex);
|
||||
let offsetX: number = 0;
|
||||
if (tempOffset === 1) {
|
||||
offsetX = -40 * offsetIndex;
|
||||
}
|
||||
return offsetX;
|
||||
}
|
||||
|
||||
startAnimation(isLeft: boolean): void {
|
||||
animateTo({
|
||||
duration: 300,
|
||||
}, () => {
|
||||
let dataLength: number = INDEX_DATA.length;
|
||||
let tempIndex: number = isLeft ? this.currentIndex + 1 : this.currentIndex - 1 + dataLength;
|
||||
this.currentIndex = tempIndex % dataLength;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
if (!isNewSlide) {
|
||||
Swiper() {
|
||||
ForEach(INDEX_DATA, (item: SwiperModel) => {
|
||||
Image(item.img)
|
||||
.objectFit(ImageFit.Cover)
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.borderRadius(16)
|
||||
})
|
||||
}
|
||||
.padding({
|
||||
left: 12,
|
||||
right: 12
|
||||
})
|
||||
.height(170)
|
||||
.autoPlay(true)
|
||||
.itemSpace(20)
|
||||
.displayCount(this.curBp === 'sm' ? 1 : this.curBp === 'md' ? 2 : 3)
|
||||
.indicator(
|
||||
Indicator
|
||||
.dot()
|
||||
.selectedColor($r('app.color.red'))
|
||||
.color($r('app.color.white'))
|
||||
)
|
||||
} else {
|
||||
Column() {
|
||||
Stack() {
|
||||
ForEach(INDEX_DATA, (item: SwiperModel, index: number) => {
|
||||
Row() {
|
||||
Image(item.img)
|
||||
.objectFit(ImageFit.Fill)
|
||||
.borderRadius(8)
|
||||
.aspectRatio(48 / 25)
|
||||
.opacity(1 - 0.2 * Math.min(2, Math.abs(this.getImgCoefficients(index))))
|
||||
}
|
||||
.borderRadius(8)
|
||||
.offset({
|
||||
x: this.getOffSetX(index),
|
||||
y: 0
|
||||
})
|
||||
.blur(10 * Math.abs(this.getImgCoefficients(index)))
|
||||
.zIndex(index !== this.currentIndex && this.getImgCoefficients(index) === 0 ?
|
||||
0 : 2 - Math.abs(this.getImgCoefficients(index)))
|
||||
.height(index !== this.currentIndex && this.getImgCoefficients(index) === 0 ?
|
||||
"78%" : `${100 - 14 * Math.abs(this.getImgCoefficients(index))}%`)
|
||||
}, (item: SwiperModel) => JSON.stringify(item))
|
||||
}
|
||||
.height(157)
|
||||
.alignContent(Alignment.Center)
|
||||
.gesture(
|
||||
PanGesture({ direction: PanDirection.Horizontal })
|
||||
.onActionStart((event: GestureEvent) => {
|
||||
this.startAnimation(event.offsetX < 0);
|
||||
})
|
||||
)
|
||||
}
|
||||
.width('100%')
|
||||
.height('25%')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,15 +13,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import router from '@ohos.router'
|
||||
import { FIND_SEARCH_TEXT_DATA } from '../../mock/ProductsData'
|
||||
import router from '@ohos.router';
|
||||
import { FIND_SEARCH_TEXT_DATA } from '../../mock/ProductsData';
|
||||
import { SearchTextModel } from '../../model/GoodsModel';
|
||||
|
||||
@Component
|
||||
export struct TitleBarComponent {
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Flex({ justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center, wrap: FlexWrap.Wrap }) {
|
||||
Flex({
|
||||
justifyContent: FlexAlign.SpaceAround,
|
||||
alignItems: ItemAlign.Center,
|
||||
wrap: FlexWrap.Wrap
|
||||
}) {
|
||||
Row() {
|
||||
Image($r('app.media.logo'))
|
||||
.width(24)
|
||||
@ -32,9 +36,9 @@ export struct TitleBarComponent {
|
||||
.aspectRatio(1)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.onClick(() => {
|
||||
router.push({
|
||||
router.pushUrl({
|
||||
url: 'pages/ScanPage'
|
||||
})
|
||||
});
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
@ -46,7 +50,7 @@ export struct TitleBarComponent {
|
||||
.width(20)
|
||||
.aspectRatio(1)
|
||||
Swiper() {
|
||||
ForEach(FIND_SEARCH_TEXT_DATA, item => {
|
||||
ForEach(FIND_SEARCH_TEXT_DATA, (item: SearchTextModel) => {
|
||||
Column() {
|
||||
Text(item.searchText)
|
||||
.opacity(0.6)
|
||||
@ -56,7 +60,7 @@ export struct TitleBarComponent {
|
||||
}
|
||||
.width('100%')
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
}, item => item.id.toString())
|
||||
}, (item: SearchTextModel) => item.id.toString())
|
||||
}
|
||||
.loop(true)
|
||||
.autoPlay(true)
|
||||
@ -68,13 +72,28 @@ export struct TitleBarComponent {
|
||||
.zIndex(2)
|
||||
.width('100%')
|
||||
.justifyContent(FlexAlign.Start)
|
||||
.margin({ top: 8, bottom: 12 })
|
||||
.padding({left: 12, right: 12})
|
||||
.margin({
|
||||
top: 8,
|
||||
bottom: 12
|
||||
})
|
||||
.padding({
|
||||
left: 12,
|
||||
right: 12
|
||||
})
|
||||
.backgroundColor($r('app.color.white'))
|
||||
.border({ width: 2, color: $r('app.color.white'), radius: 40 })
|
||||
.border({
|
||||
width: 2,
|
||||
color: $r('app.color.white'),
|
||||
radius: 40
|
||||
})
|
||||
}
|
||||
.margin({ top: 12 })
|
||||
.padding({ left: 12, right: 12 })
|
||||
.margin({
|
||||
top: 12
|
||||
})
|
||||
.padding({
|
||||
left: 12,
|
||||
right: 12
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
|
@ -13,13 +13,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ProductDataModel } from '../../model/GoodsModel'
|
||||
import { PRODUCT_DATA } from '../../mock/ProductsData'
|
||||
import { ProductDataModel } from '../../model/GoodsModel';
|
||||
import { PRODUCT_DATA } from '../../mock/ProductsData';
|
||||
|
||||
@Component
|
||||
export struct Cart {
|
||||
@StorageProp('curBp') curBp: string = 'sm'
|
||||
@Link shoppingCartGoodsListToCart: ProductDataModel[]
|
||||
@StorageProp('curBp') curBp: string = 'sm';
|
||||
@Link shoppingCartGoodsListToCart: ProductDataModel[];
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
@ -33,7 +33,10 @@ export struct Cart {
|
||||
.width(24)
|
||||
.aspectRatio(1)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 12, right: 8 })
|
||||
.margin({
|
||||
left: 12,
|
||||
right: 8
|
||||
})
|
||||
Text($r('app.string.shopping_self_support'))
|
||||
.fontSize(14)
|
||||
.fontWeight(400)
|
||||
@ -52,7 +55,10 @@ export struct Cart {
|
||||
.width(70)
|
||||
.height(80)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ left: 12, right: 16 })
|
||||
.margin({
|
||||
left: 12,
|
||||
right: 16
|
||||
})
|
||||
|
||||
Column() {
|
||||
Text(PRODUCT_DATA[item].title)
|
||||
@ -64,7 +70,9 @@ export struct Cart {
|
||||
.width('100%')
|
||||
.fontSize(12)
|
||||
.opacity(0.6)
|
||||
.margin({ top: 12 })
|
||||
.margin({
|
||||
top: 12
|
||||
})
|
||||
|
||||
Row() {
|
||||
Text(PRODUCT_DATA[item].price)
|
||||
@ -78,21 +86,30 @@ export struct Cart {
|
||||
.height(24)
|
||||
.objectFit(ImageFit.Contain)
|
||||
Text(`${1}`)
|
||||
.margin({ left: 10, right: 10 })
|
||||
.margin({
|
||||
left: 10,
|
||||
right: 10
|
||||
})
|
||||
.fontSize(12)
|
||||
Image($r('app.media.add'))
|
||||
.width(24)
|
||||
.height(24)
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
.margin({ right: 12 })
|
||||
.margin({
|
||||
right: 12
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.margin({ top: 12 })
|
||||
.margin({
|
||||
top: 12
|
||||
})
|
||||
}
|
||||
.flexGrow(1)
|
||||
.flexShrink(1)
|
||||
.margin({ top: 20 })
|
||||
.margin({
|
||||
top: 20
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
}, item => item.toString())
|
||||
@ -100,6 +117,9 @@ export struct Cart {
|
||||
.width('100%')
|
||||
.backgroundColor($r('app.color.white'))
|
||||
.borderRadius(16)
|
||||
.padding({ top: 12, bottom: 12 })
|
||||
.padding({
|
||||
top: 12,
|
||||
bottom: 12
|
||||
})
|
||||
}
|
||||
}
|
@ -13,38 +13,40 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import emitter from '@ohos.events.emitter'
|
||||
import router from '@ohos.router'
|
||||
import Http from '@ohos/http'
|
||||
import { GoodResponse, ShopCartItemDataModel } from '../../model/GoodsModel'
|
||||
import { Products_Data, SHOP_CART_ITEM_DATA } from '../../mock/ProductsData'
|
||||
import router from '@ohos.router';
|
||||
import Http from '@ohos/http';
|
||||
import { GoodResponse, ShopCartItemDataModel } from '../../model/GoodsModel';
|
||||
import { Products_Data, SHOP_CART_ITEM_DATA } from '../../mock/ProductsData';
|
||||
|
||||
@Component
|
||||
export struct FavorGoodList {
|
||||
@State flag: boolean = false
|
||||
private url: string
|
||||
private option: object
|
||||
@State productsData: GoodResponse = Products_Data
|
||||
@State flag: boolean = false;
|
||||
private url: string;
|
||||
private option: object;
|
||||
@State productsData: GoodResponse = Products_Data;
|
||||
|
||||
async aboutToAppear() {
|
||||
Http.setUrl(this.url)
|
||||
Http.setOptions(this.option)
|
||||
this.flag = false
|
||||
let info = await Http.request()
|
||||
Http.setUrl(this.url);
|
||||
Http.setOptions(this.option);
|
||||
this.flag = false;
|
||||
let info = await Http.request();
|
||||
if (info.responseCode === 200) {
|
||||
this.flag = true
|
||||
this.productsData = JSON.parse(info.result.toString())
|
||||
this.flag = true;
|
||||
this.productsData = JSON.parse(info.result.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Builder GoodItem(shopItem: ShopCartItemDataModel) {
|
||||
@Builder
|
||||
GoodItem(shopItem: ShopCartItemDataModel) {
|
||||
Column() {
|
||||
// 这里的图片需要根据父组件宽度自适应,此处使用70%
|
||||
Image(shopItem.uri)
|
||||
.width('70%')
|
||||
.aspectRatio(1)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ bottom: 12 })
|
||||
.margin({
|
||||
bottom: 12
|
||||
})
|
||||
Column() {
|
||||
Text(shopItem.title)
|
||||
.width('100%')
|
||||
@ -52,16 +54,27 @@ export struct FavorGoodList {
|
||||
Text(shopItem.price)
|
||||
.fontColor($r('app.color.red'))
|
||||
.fontSize(16)
|
||||
.margin({ top: 6 })
|
||||
.offset({ x: -3 }) // 因为¥是中文字符,上面的xx是中文字符,占的宽度不一样,所以需要对齐,添加offset
|
||||
.margin({
|
||||
top: 6
|
||||
})
|
||||
.offset({
|
||||
x: -3
|
||||
}) // 因为¥是中文字符,上面的xx是中文字符,占的宽度不一样,所以需要对齐,添加offset
|
||||
Column() {
|
||||
Text(shopItem.labels)
|
||||
.fontSize(10)
|
||||
.fontColor($r('app.color.white'))
|
||||
}
|
||||
.borderRadius(5)
|
||||
.margin({ top: 6 })
|
||||
.padding({ left: 6, right: 6, top: 4, bottom: 4 })
|
||||
.margin({
|
||||
top: 6
|
||||
})
|
||||
.padding({
|
||||
left: 6,
|
||||
right: 6,
|
||||
top: 4,
|
||||
bottom: 4
|
||||
})
|
||||
.backgroundColor($r('app.color.red'))
|
||||
}
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
@ -71,24 +84,37 @@ export struct FavorGoodList {
|
||||
.padding(12)
|
||||
.backgroundColor($r('app.color.white'))
|
||||
.onClick(() => {
|
||||
router.push({
|
||||
router.pushUrl({
|
||||
url: 'pages/Detail',
|
||||
params: { goodId: shopItem.id, goodItem: shopItem }
|
||||
params: {
|
||||
goodId: shopItem.id,
|
||||
goodItem: shopItem
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
build() {
|
||||
GridRow({ gutter: { x: vp2px(8), y: vp2px(8) } }) {
|
||||
GridRow({
|
||||
gutter: {
|
||||
x: vp2px(8),
|
||||
y: vp2px(8)
|
||||
}
|
||||
}) {
|
||||
ForEach(this.flag ? this.productsData.data.records : SHOP_CART_ITEM_DATA, item => {
|
||||
GridCol({ span: { sm: 6, md: 6, lg: 4 } }) {
|
||||
this.GoodItem(item)
|
||||
GridCol({
|
||||
span: {
|
||||
sm: 6,
|
||||
md: 6,
|
||||
lg: 4 }
|
||||
}) {
|
||||
this.GoodItem(item);
|
||||
}
|
||||
}, item => item.id.toString())
|
||||
}
|
||||
.onAreaChange((oldArea: Area, newArea: Area) => {
|
||||
console.info(`LSQ: newArea is ${newArea.height}`)
|
||||
AppStorage.SetOrCreate('goodsListHeight', newArea.height as number)
|
||||
.onAreaChange((newArea: Area) => {
|
||||
console.info(`LSQ: newArea is ${newArea.height}`);
|
||||
AppStorage.setOrCreate('goodsListHeight', newArea.height as number);
|
||||
})
|
||||
}
|
||||
}
|
@ -13,11 +13,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ORDER_DATA } from '../../mock/ProductsData'
|
||||
import { ORDER_DATA } from '../../mock/ProductsData';
|
||||
import { OrderModel } from '../../model/GoodsModel';
|
||||
|
||||
@Component
|
||||
export struct MyOrderComponent {
|
||||
@StorageProp('curBp') curBp: string = 'sm'
|
||||
@StorageProp('curBp') curBp: string = 'sm';
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
@ -35,29 +36,45 @@ export struct MyOrderComponent {
|
||||
.objectFit(ImageFit.Contain)
|
||||
}
|
||||
}
|
||||
.padding({ left: 12, right: 12 })
|
||||
.padding({
|
||||
left: 12,
|
||||
right: 12
|
||||
})
|
||||
.width('100%')
|
||||
|
||||
Row() {
|
||||
ForEach(ORDER_DATA, item => {
|
||||
ForEach(ORDER_DATA, (item: OrderModel) => {
|
||||
Column() {
|
||||
Image(item.img)
|
||||
.aspectRatio(1)
|
||||
.width(28)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ bottom: 12 })
|
||||
.margin({
|
||||
bottom: 12
|
||||
})
|
||||
Text(item.title)
|
||||
.fontSize(12)
|
||||
}
|
||||
.layoutWeight(1)
|
||||
}, item => item.id.toString())
|
||||
}, (item: OrderModel) => item.id.toString())
|
||||
}
|
||||
.width('100%')
|
||||
.margin({ top: 14 })
|
||||
.margin({
|
||||
top: 14
|
||||
})
|
||||
}
|
||||
.padding({ left: 12, right: 12, top: 16, bottom: 16 })
|
||||
.border({ radius: 16 })
|
||||
.padding({
|
||||
left: 12,
|
||||
right: 12,
|
||||
top: 16,
|
||||
bottom: 16
|
||||
})
|
||||
.border({
|
||||
radius: 16
|
||||
})
|
||||
.backgroundColor($r('app.color.white'))
|
||||
.margin({ top: 12 })
|
||||
.margin({
|
||||
top: 12
|
||||
})
|
||||
}
|
||||
}
|
@ -15,15 +15,17 @@
|
||||
|
||||
@Component
|
||||
export struct RewardSectionComponent {
|
||||
|
||||
@Builder options(img: Resource, label: Resource) {
|
||||
@Builder
|
||||
options(img: Resource, label: Resource) {
|
||||
Column() {
|
||||
Image(img)
|
||||
.aspectRatio(1)
|
||||
.width(40)
|
||||
.objectFit(ImageFit.Contain)
|
||||
Text(label)
|
||||
.margin({ top: 12 })
|
||||
.margin({
|
||||
top: 12
|
||||
})
|
||||
.fontSize(12)
|
||||
}
|
||||
.width('25%')
|
||||
@ -32,14 +34,19 @@ export struct RewardSectionComponent {
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
this.options($r('app.media.vip_channel'), $r('app.string.point_reward'))
|
||||
this.options($r('app.media.point_reward'), $r('app.string.interaction'))
|
||||
this.options($r('app.media.interaction'), $r('app.string.interaction'))
|
||||
this.options($r('app.media.card_volumn'), $r('app.string.card_volume'))
|
||||
this.options($r('app.media.vip_channel'), $r('app.string.point_reward'));
|
||||
this.options($r('app.media.point_reward'), $r('app.string.interaction'));
|
||||
this.options($r('app.media.interaction'), $r('app.string.interaction'));
|
||||
this.options($r('app.media.card_volumn'), $r('app.string.card_volume'));
|
||||
}
|
||||
.width('100%')
|
||||
.padding({ top: 16, bottom: 16})
|
||||
.padding({
|
||||
top: 16,
|
||||
bottom: 16
|
||||
})
|
||||
.backgroundColor($r('app.color.white'))
|
||||
.border({ radius: 16 })
|
||||
.border({
|
||||
radius: 16
|
||||
})
|
||||
}
|
||||
}
|
@ -15,8 +15,8 @@
|
||||
|
||||
@Component
|
||||
export struct ServiceSectionComponent {
|
||||
|
||||
@Builder serverSection(img: Resource, label: Resource) {
|
||||
@Builder
|
||||
serverSection(img: Resource, label: Resource) {
|
||||
Column() {
|
||||
Image(img)
|
||||
.width(40)
|
||||
@ -24,7 +24,9 @@ export struct ServiceSectionComponent {
|
||||
.objectFit(ImageFit.Contain)
|
||||
Text(label)
|
||||
.fontSize(12)
|
||||
.margin({ top: 12 })
|
||||
.margin({
|
||||
top: 12
|
||||
})
|
||||
}
|
||||
.width('25%')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
@ -39,8 +41,13 @@ export struct ServiceSectionComponent {
|
||||
}
|
||||
.width('100%')
|
||||
.justifyContent(FlexAlign.SpaceBetween)
|
||||
.padding({ top: 16, bottom: 16})
|
||||
.padding({
|
||||
top: 16,
|
||||
bottom: 16
|
||||
})
|
||||
.backgroundColor($r('app.color.white'))
|
||||
.border({ radius: 16 })
|
||||
.border({
|
||||
radius: 16
|
||||
})
|
||||
}
|
||||
}
|
@ -13,30 +13,49 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import router from '@ohos.router'
|
||||
import { FAVOR_LIVE_LIST_DATA } from '../../mock/ProductsData'
|
||||
import { MyOrderComponent } from '../user/MyOrders'
|
||||
import { RewardSectionComponent } from '../user/RrewardSection'
|
||||
import { ServiceSectionComponent } from '../user/ServiceSection'
|
||||
import router from '@ohos.router';
|
||||
import { FAVOR_LIVE_LIST_DATA } from '../../mock/ProductsData';
|
||||
import { FavorLiveListsModel } from '../../model/GoodsModel';
|
||||
import { MyOrderComponent } from '../user/MyOrders';
|
||||
import { RewardSectionComponent } from '../user/RrewardSection';
|
||||
import { ServiceSectionComponent } from '../user/ServiceSection';
|
||||
|
||||
@Component
|
||||
export struct User {
|
||||
@StorageProp('curBp') curBp: string = 'sm'
|
||||
@StorageProp('curBp') curBp: string = 'sm';
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Scroll() {
|
||||
GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: { x: vp2px(8), y: vp2px(12) } }) {
|
||||
GridCol({ span: { sm: 4, md: 8, lg: 12 } }) {
|
||||
GridRow({
|
||||
columns: {
|
||||
sm: 4,
|
||||
md: 8,
|
||||
lg: 12
|
||||
},
|
||||
gutter: {
|
||||
x: vp2px(8),
|
||||
y: vp2px(12)
|
||||
}
|
||||
}) {
|
||||
GridCol({
|
||||
span: {
|
||||
sm: 4,
|
||||
md: 8,
|
||||
lg: 12
|
||||
}
|
||||
}) {
|
||||
Column() {
|
||||
Row() {
|
||||
Image($r('app.media.setting'))
|
||||
.width(24)
|
||||
.aspectRatio(1)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({ right: 16 })
|
||||
.margin({
|
||||
right: 16
|
||||
})
|
||||
.onClick(() => {
|
||||
router.replace({
|
||||
router.replaceUrl({
|
||||
url: 'pages/Setting'
|
||||
})
|
||||
})
|
||||
@ -59,7 +78,9 @@ export struct User {
|
||||
.fontSize(16)
|
||||
.fontWeight(500)
|
||||
.fontColor($r('app.color.white'))
|
||||
.margin({ bottom: 12 })
|
||||
.margin({
|
||||
bottom: 12
|
||||
})
|
||||
Row() {
|
||||
Row() {
|
||||
Text($r('app.string.sign_Info'))
|
||||
@ -78,33 +99,59 @@ export struct User {
|
||||
.padding(4)
|
||||
.borderRadius(10)
|
||||
.backgroundColor($r('app.color.point_selected'))
|
||||
.margin({ left: 4 })
|
||||
.margin({
|
||||
left: 4
|
||||
})
|
||||
}
|
||||
}
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
.padding({ left: 12 })
|
||||
.padding({
|
||||
left: 12
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.padding({ left: 12 })
|
||||
.padding({
|
||||
left: 12
|
||||
})
|
||||
|
||||
MyOrderComponent()
|
||||
MyOrderComponent();
|
||||
}
|
||||
}
|
||||
|
||||
GridCol({ span: { sm: 4, md: 4, lg: 6 } }) {
|
||||
RewardSectionComponent()
|
||||
GridCol({
|
||||
span: {
|
||||
sm: 4,
|
||||
md: 4,
|
||||
lg: 6
|
||||
}
|
||||
}) {
|
||||
RewardSectionComponent();
|
||||
}
|
||||
|
||||
GridCol({ span: { sm: 4, md: 4, lg: 6 } }) {
|
||||
ServiceSectionComponent()
|
||||
GridCol({
|
||||
span: {
|
||||
sm: 4,
|
||||
md: 4,
|
||||
lg: 6
|
||||
}
|
||||
}) {
|
||||
ServiceSectionComponent();
|
||||
}
|
||||
|
||||
GridCol({ span: { sm: 4, md: 8, lg: 12 } }) {
|
||||
GridCol({
|
||||
span: {
|
||||
sm: 4,
|
||||
md: 8,
|
||||
lg: 12
|
||||
}
|
||||
}) {
|
||||
Row() {
|
||||
Text($r('app.string.often_see_live'))
|
||||
.fontSize(16)
|
||||
.fontWeight(500)
|
||||
.margin({ left: 12 })
|
||||
.margin({
|
||||
left: 12
|
||||
})
|
||||
Blank()
|
||||
Row() {
|
||||
Text($r('app.string.read_more'))
|
||||
@ -117,11 +164,19 @@ export struct User {
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.padding({ top: 4 })
|
||||
.padding({
|
||||
top: 4
|
||||
})
|
||||
}
|
||||
|
||||
ForEach(FAVOR_LIVE_LIST_DATA, item => {
|
||||
GridCol({ span: { sm: 2, md: 4, lg: 4 } }) {
|
||||
ForEach(FAVOR_LIVE_LIST_DATA, (item: FavorLiveListsModel) => {
|
||||
GridCol({
|
||||
span: {
|
||||
sm: 2,
|
||||
md: 4,
|
||||
lg: 4
|
||||
}
|
||||
}) {
|
||||
Stack({ alignContent: Alignment.TopStart }) {
|
||||
Image(item.imgSrc)
|
||||
.objectFit(ImageFit.Cover)
|
||||
@ -133,27 +188,46 @@ export struct User {
|
||||
}
|
||||
.backgroundColor($r('app.color.red'))
|
||||
.borderRadius(10)
|
||||
.padding({ left: 6, right: 6, bottom: 2, top: 2 })
|
||||
.padding({
|
||||
left: 6,
|
||||
right: 6,
|
||||
bottom: 2,
|
||||
top: 2
|
||||
})
|
||||
|
||||
Text(item.viewsInfo)
|
||||
.fontSize(10)
|
||||
.fontColor($r('app.color.white'))
|
||||
.margin({ left: 6 })
|
||||
.margin({
|
||||
left: 6
|
||||
})
|
||||
}
|
||||
.borderRadius(10)
|
||||
.padding({ right: 6 })
|
||||
.padding({
|
||||
right: 6
|
||||
})
|
||||
.backgroundColor($r('app.color.point'))
|
||||
.margin({ left: 12, top: 12 })
|
||||
.margin({
|
||||
left: 12,
|
||||
top: 12
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
}, item => item.id.toString())
|
||||
}, (item: FavorLiveListsModel) => item.id.toString())
|
||||
}
|
||||
.padding({ left: 12, right: 12, bottom: 12 })
|
||||
.padding({
|
||||
left: 12,
|
||||
right: 12,
|
||||
bottom: 12
|
||||
})
|
||||
}
|
||||
.layoutWeight(1)
|
||||
.scrollBar(BarState.Off)
|
||||
.backgroundImageSize({ width: '100%', height: '25%' })
|
||||
.backgroundImageSize({
|
||||
width: '100%',
|
||||
height: '25%'
|
||||
})
|
||||
.backgroundImage($r('app.media.home_mask'), ImageRepeat.NoRepeat)
|
||||
|
||||
Divider()
|
||||
|
@ -13,23 +13,32 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TAB_TITLE_DATA } from '../mock/ProductsData'
|
||||
import { MainPage } from '../components/home/MainPage'
|
||||
import { NewProduct } from '../components/home/NewProduct'
|
||||
import { ShopCart } from '../components/home/ShopCart'
|
||||
import { User } from '../components/user/User'
|
||||
import { TAB_TITLE_DATA } from '../mock/ProductsData';
|
||||
import { MainPage } from '../components/home/MainPage';
|
||||
import { NewProduct } from '../components/home/NewProduct';
|
||||
import { ShopCart } from '../components/home/ShopCart';
|
||||
import { User } from '../components/user/User';
|
||||
|
||||
AppStorage.Link('isUpdateDialogOpen') || AppStorage.SetOrCreate('isUpdateDialogOpen', false)
|
||||
AppStorage.link('isUpdateDialogOpen') || AppStorage.setOrCreate('isUpdateDialogOpen', false);
|
||||
|
||||
export class Url {
|
||||
url: string;
|
||||
|
||||
constructor(url: string) {
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
export struct NavigationHomePage {
|
||||
@State tabsIndex: number = AppStorage.Get('nowIndex') || 0
|
||||
@StorageProp('curBp') curBp: string = 'sm'
|
||||
private url: string
|
||||
private controller: TabsController = new TabsController()
|
||||
@State tabsIndex: number = AppStorage.get('nowIndex') || 0;
|
||||
@StorageProp('curBp') curBp: string = 'sm';
|
||||
private url: string;
|
||||
private controller: TabsController = new TabsController();
|
||||
|
||||
@Builder TabBarBuilder(index: number) {
|
||||
@Builder
|
||||
TabBarBuilder(index: number) {
|
||||
Column() {
|
||||
Image(this.getTabBarImage(index))
|
||||
.id('homeTab' + index)
|
||||
@ -39,7 +48,9 @@ export struct NavigationHomePage {
|
||||
Text(TAB_TITLE_DATA[index].title)
|
||||
.fontSize(10)
|
||||
.fontWeight(500)
|
||||
.margin({ top: 4 })
|
||||
.margin({
|
||||
top: 4
|
||||
})
|
||||
.opacity(this.tabsIndex === index ? 1 : 0.6)
|
||||
.fontWeight(this.tabsIndex === index ? 500 : 400)
|
||||
.fontColor(this.tabsIndex === index ? $r('app.color.pink') : Color.Black)
|
||||
@ -48,7 +59,7 @@ export struct NavigationHomePage {
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.onClick(() => {
|
||||
this.controller.changeIndex(index)
|
||||
this.controller.changeIndex(index);
|
||||
})
|
||||
}
|
||||
|
||||
@ -60,20 +71,28 @@ export struct NavigationHomePage {
|
||||
controller: this.controller
|
||||
}) {
|
||||
TabContent() {
|
||||
MainPage({ url: this.url })
|
||||
}.tabBar(this.TabBarBuilder(0))
|
||||
MainPage(new Url(this.url));
|
||||
}.tabBar(
|
||||
this.TabBarBuilder(0)
|
||||
)
|
||||
|
||||
TabContent() {
|
||||
NewProduct({ url: this.url })
|
||||
}.tabBar(this.TabBarBuilder(1))
|
||||
NewProduct(new Url(this.url));
|
||||
}.tabBar(
|
||||
this.TabBarBuilder(1)
|
||||
)
|
||||
|
||||
TabContent() {
|
||||
ShopCart({ url: this.url })
|
||||
}.tabBar(this.TabBarBuilder(2))
|
||||
ShopCart(new Url(this.url));
|
||||
}.tabBar(
|
||||
this.TabBarBuilder(2)
|
||||
)
|
||||
|
||||
TabContent() {
|
||||
User()
|
||||
}.tabBar(this.TabBarBuilder(3))
|
||||
User();
|
||||
}.tabBar(
|
||||
this.TabBarBuilder(3)
|
||||
)
|
||||
}
|
||||
.scrollable(false)
|
||||
.vertical(this.curBp === 'sm' ? false : true)
|
||||
@ -81,16 +100,16 @@ export struct NavigationHomePage {
|
||||
.barWidth(this.curBp === 'sm' ? '100%' : 56)
|
||||
.barHeight(this.curBp === 'sm' ? 56 : '100%')
|
||||
.onChange((index: number) => {
|
||||
this.tabsIndex = index
|
||||
this.tabsIndex = index;
|
||||
})
|
||||
}
|
||||
.backgroundColor($r('app.color.divider'))
|
||||
}
|
||||
|
||||
getTabBarImage(index: number) {
|
||||
getTabBarImage(index: number): Resource {
|
||||
if (this.tabsIndex === index) {
|
||||
return TAB_TITLE_DATA[index].selectedUri
|
||||
return TAB_TITLE_DATA[index].selectedUri;
|
||||
}
|
||||
return TAB_TITLE_DATA[index].uri
|
||||
return TAB_TITLE_DATA[index].uri;
|
||||
}
|
||||
}
|
@ -244,129 +244,129 @@ export const PRODUCT_DATA: Array<ProductDataModel> = [
|
||||
{
|
||||
id: 0,
|
||||
uri: $r('app.media.product001'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: $r('app.string.product_data_title_device'),
|
||||
title: $r('app.string.product_data_title_device0'),
|
||||
info: $r('app.string.product_data_info_device0'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price0')
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
uri: $r('app.media.product002'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: $r('app.string.product_data_title_device'),
|
||||
title: $r('app.string.product_data_title_device1'),
|
||||
info: $r('app.string.product_data_info_device1'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price1')
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
uri: $r('app.media.product003'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: $r('app.string.product_data_title_device'),
|
||||
title: $r('app.string.product_data_title_device2'),
|
||||
info: $r('app.string.product_data_info_device2'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price2')
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
uri: $r('app.media.product004'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: undefined,
|
||||
title: $r('app.string.product_data_title_device3'),
|
||||
info: $r('app.string.product_data_info_device3'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price3')
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
uri: $r('app.media.product005'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: $r('app.string.product_data_title_device'),
|
||||
title: $r('app.string.product_data_title_device4'),
|
||||
info: $r('app.string.product_data_info_device4'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price4')
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
uri: $r('app.media.product006'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: undefined,
|
||||
title: $r('app.string.product_data_title_device5'),
|
||||
info: $r('app.string.product_data_info_device5'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price5')
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
uri: $r('app.media.product007'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: undefined,
|
||||
title: $r('app.string.product_data_title_device5'),
|
||||
info: $r('app.string.product_data_info_device5'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price5')
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
uri: $r('app.media.product008'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: undefined,
|
||||
title: $r('app.string.product_data_title_device7'),
|
||||
info: $r('app.string.product_data_info_device7'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price7')
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
uri: $r('app.media.product001'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: undefined,
|
||||
title: $r('app.string.product_data_title_device0'),
|
||||
info: $r('app.string.product_data_info_device0'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price0')
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
uri: $r('app.media.product002'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: undefined,
|
||||
title: $r('app.string.product_data_title_device1'),
|
||||
info: $r('app.string.product_data_info_device1'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price1')
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
uri: $r('app.media.product003'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: undefined,
|
||||
title: $r('app.string.product_data_title_device2'),
|
||||
info: $r('app.string.product_data_info_device2'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price2')
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
uri: $r('app.media.product004'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: undefined,
|
||||
title: $r('app.string.product_data_title_device3'),
|
||||
info: $r('app.string.product_data_info_device3'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price3')
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
uri: $r('app.media.product005'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: undefined,
|
||||
title: $r('app.string.product_data_title_device4'),
|
||||
info: $r('app.string.product_data_info_device4'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price4')
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
uri: $r('app.media.product006'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: undefined,
|
||||
title: $r('app.string.product_data_title_device5'),
|
||||
info: $r('app.string.product_data_info_device5'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price5')
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
uri: $r('app.media.product007'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: undefined,
|
||||
title: $r('app.string.product_data_title_device5'),
|
||||
info: $r('app.string.product_data_info_device5'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price5')
|
||||
},
|
||||
{
|
||||
id: 15,
|
||||
uri: $r('app.media.product008'),
|
||||
title: $r('app.string.product_data_title_device'),
|
||||
info: undefined,
|
||||
title: $r('app.string.product_data_title_device7'),
|
||||
info: $r('app.string.product_data_info_device7'),
|
||||
labels: $r('app.string.product_data_labels_new_product'),
|
||||
price: $r('app.string.product_data_price')
|
||||
price: $r('app.string.product_data_price7')
|
||||
}
|
||||
]
|
||||
|
@ -212,14 +212,102 @@
|
||||
"name": "product_data_title_device",
|
||||
"value": "XX equipment new product discount!"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device4",
|
||||
"value": "华为电脑包"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device4",
|
||||
"value": "保时捷联名款 | 多层内胆"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price4",
|
||||
"value": "¥699"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device5",
|
||||
"value": "华为P50"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device5",
|
||||
"value": "4800像素 | 120W快充"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price5",
|
||||
"value": "¥6999"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device0",
|
||||
"value": "battery"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device",
|
||||
"value": "XX equipment new product discount!"
|
||||
},
|
||||
{
|
||||
"name": "product_data_labels_new_product",
|
||||
"value": "new"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device0",
|
||||
"value": "20000mA USB-C18W"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device2",
|
||||
"value": "华为畅享 50z"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device2",
|
||||
"value": "高清三摄 | 超能续航"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device1",
|
||||
"value": "HUAWEI MateBook"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device1",
|
||||
"value": "32GB 16英寸触屏"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device3",
|
||||
"value": "华为按摩椅"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device3",
|
||||
"value": "AI智能芯片 | 语音声控"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device7",
|
||||
"value": "华为畅享 50z"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device7",
|
||||
"value": "高清三摄 | 超能续航"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price7",
|
||||
"value": "¥6999"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price3",
|
||||
"value": "¥8999"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price",
|
||||
"value": "¥4999"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price1",
|
||||
"value": "¥4122"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price0",
|
||||
"value": "¥138"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price2",
|
||||
"value": "¥1388"
|
||||
},
|
||||
{
|
||||
"name": "order_data_title_obligation",
|
||||
"value": "Pending payment"
|
||||
|
@ -28,6 +28,42 @@
|
||||
"name": "shopping_self_support",
|
||||
"value": "mall self-operated"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device4",
|
||||
"value": "华为电脑包"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device4",
|
||||
"value": "保时捷联名款 | 多层内胆"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price4",
|
||||
"value": "¥699"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device7",
|
||||
"value": "华为畅享 50z"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device7",
|
||||
"value": "高清三摄 | 超能续航"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price7",
|
||||
"value": "¥6999"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device5",
|
||||
"value": "华为P50"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device5",
|
||||
"value": "4800像素 | 120W快充"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price5",
|
||||
"value": "¥6999"
|
||||
},
|
||||
{
|
||||
"name": "phone_name",
|
||||
"value": "Feature Phone 5G Network Speed"
|
||||
@ -212,12 +248,64 @@
|
||||
"name": "product_data_title_device",
|
||||
"value": "XX equipment new product discount!"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device0",
|
||||
"value": "20000mA USB-C18W"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device1",
|
||||
"value": "HUAWEI MateBook"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device1",
|
||||
"value": "32GB 16英寸触屏"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device2",
|
||||
"value": "华为畅享 50z"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device2",
|
||||
"value": "高清三摄 | 超能续航"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device3",
|
||||
"value": "华为按摩椅"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device3",
|
||||
"value": "AI智能芯片 | 语音声控"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price3",
|
||||
"value": "¥8999"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device",
|
||||
"value": "20000mA"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price",
|
||||
"value": "¥4999"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price0",
|
||||
"value": "¥138"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price2",
|
||||
"value": "¥1388"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device0",
|
||||
"value": "battery"
|
||||
},
|
||||
{
|
||||
"name": "product_data_labels_new_product",
|
||||
"value": "new"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price",
|
||||
"name": "product_data_price1",
|
||||
"value": "¥4122"
|
||||
},
|
||||
{
|
||||
|
@ -12,6 +12,42 @@
|
||||
"name": "classification",
|
||||
"value": "分类"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device4",
|
||||
"value": "华为电脑包"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device4",
|
||||
"value": "保时捷联名款 | 多层内胆"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price4",
|
||||
"value": "¥699"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device7",
|
||||
"value": "华为畅享 50z"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device7",
|
||||
"value": "高清三摄 | 超能续航"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price7",
|
||||
"value": "¥6999"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device5",
|
||||
"value": "华为P50"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device5",
|
||||
"value": "4800像素 | 120W快充"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price5",
|
||||
"value": "¥6999"
|
||||
},
|
||||
{
|
||||
"name": "guess_you_like",
|
||||
"value": "猜你喜欢"
|
||||
@ -108,6 +144,10 @@
|
||||
"name": "favor_live_lists_data_viewsInfo",
|
||||
"value": "45.6万人观看"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price0",
|
||||
"value": "¥138"
|
||||
},
|
||||
{
|
||||
"name": "tab_title_data_home",
|
||||
"value": "首页"
|
||||
@ -210,16 +250,64 @@
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device",
|
||||
"value": "XX设备 新品优惠!"
|
||||
"value": "xx设备 新品优惠!"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device",
|
||||
"value": "xx设备 新品优惠!"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device0",
|
||||
"value": "HUAWEI移动电源"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device0",
|
||||
"value": "20000毫安 USB-C18W"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device1",
|
||||
"value": "HUAWEI MateBook"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device1",
|
||||
"value": "32GB 16英寸触屏"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device2",
|
||||
"value": "华为畅享 50z"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device2",
|
||||
"value": "高清三摄 | 超能续航"
|
||||
},
|
||||
{
|
||||
"name": "product_data_labels_new_product",
|
||||
"value": "新品"
|
||||
},
|
||||
{
|
||||
"name": "product_data_title_device3",
|
||||
"value": "华为按摩椅"
|
||||
},
|
||||
{
|
||||
"name": "product_data_info_device3",
|
||||
"value": "AI智能芯片 | 语音声控"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price3",
|
||||
"value": "¥8999"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price",
|
||||
"value": "¥4999"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price1",
|
||||
"value": "¥4122"
|
||||
},
|
||||
{
|
||||
"name": "product_data_price2",
|
||||
"value": "¥1388"
|
||||
},
|
||||
{
|
||||
"name": "order_data_title_obligation",
|
||||
"value": "待付款"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"hvigorVersion": "2.0.0",
|
||||
"hvigorVersion": "3.0.2",
|
||||
"dependencies": {
|
||||
"@ohos/hvigor-ohos-plugin": "2.0.0"
|
||||
"@ohos/hvigor-ohos-plugin": "3.0.2"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user