首页 > 其他分享 >HarmonyOS实现仿造小米商城

HarmonyOS实现仿造小米商城

时间:2024-12-18 17:32:36浏览次数:13  
标签:string color app float CommonConstants HarmonyOS 小米 top 仿造

项目简介

以下代码实现了小米商城的仿造编写,可以实现用户登录和注册,以及小米系列商品的展示和个人信息的展示。app尚不完全后续会加入更多功能。编程软件DevEco Studio

工程目录 

└─main
    ├─ets
    │  ├─common
    │  │  ├─constants
    │  │  └─utils
    │  ├─entryability
    │  ├─entrybackupability
    │  ├─model
    │  ├─pages
    │  ├─view
    │  └─viewmodel
    └─resources
        ├─base
        │  ├─element
        │  ├─media
        │  └─profile
        ├─en_US
        │  └─element
        └─zh_CN
            └─element

代码实现

以下为主要代码。

以下代码利用HUKS实现密钥管理操作。

import { huks } from '@kit.UniversalKeystoreKit';
import CommonConstants from '../common/constants/CommonConstants';
import Logger from '../common/utils/Logger';
import { BusinessError } from '@kit.BasicServicesKit';
import { util } from '@kit.ArkTS';

class HuksModel {
  /**
   * Key vector.
   */
  private IV: string = '0000000000000000';

  /**
   * Data size.
   */
  private static readonly MAX_LENGTH: number = 100*1024 / 2;

  generateKeyItem(keyAlias: string) {
    if (!keyAlias || keyAlias.length === 0) {
      return;
    }
    let properties = this.getProperties();
    let option: huks.HuksOptions = {
      properties: properties
    };
    huks.generateKeyItem(keyAlias, option).then(() => {
      Logger.info(CommonConstants.TAG, 'generateKeyItem success');
    }).catch((error: BusinessError) => {
      Logger.error(CommonConstants.TAG, `generateKeyItem failed, cause ${error.code} ${error.message}`);
    })
  }

  /**
   * Get default properties.
   */
  private getProperties() {
    let properties: Array<huks.HuksParam> = [];
    properties[0] = {
      tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
      value: huks.HuksKeyAlg.HUKS_ALG_AES
    };
    properties[1] = {
      tag: huks.HuksTag.HUKS_TAG_PURPOSE,
      value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT
    };
    properties[2] = {
      tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
      value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128
    };
    properties[3] = {
      tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
      value: huks.HuksCipherMode.HUKS_MODE_CBC
    };
    properties[4] = {
      tag: huks.HuksTag.HUKS_TAG_PADDING,
      value: huks.HuksKeyPadding.HUKS_PADDING_PKCS7
    };
    return properties;
  }

  /**
   * huks handing process
   *
   * @param keyAlias keyAlias key alias
   * @param option huks required operation parameters
   */
  async huksProcess(keyAlias: string, option: huks.HuksOptions): Promise<Uint8Array> {
    if (!keyAlias || !option || keyAlias.length === 0) {
      return new Uint8Array([]);
    }
    let result: Uint8Array = new Uint8Array();
    let handle: number = 0;

    await huks.initSession(keyAlias, option).then((sessionHandle) => {
      handle = sessionHandle.handle;
    }).catch((error: BusinessError) => {
      Logger.error(CommonConstants.TAG, `updateSession failed, cause ${error.code} ${error.message}`);
    })

    if (option.inData && option.inData.length > HuksModel.MAX_LENGTH) {
      await huks.updateSession(handle, option).then((value: huks.HuksReturnResult) => {
        if (value.outData) {
          result = value.outData;
        }
      }).catch((error: BusinessError) => {
        Logger.error(CommonConstants.TAG, `updateSession failed, cause ${error.code} ${error.message}`);
      })
    }
    await huks.finishSession(handle, option).then((value: huks.HuksReturnResult) => {
      if (value.outData) {
        result = new Uint8Array(Array.from(result).concat(Array.from(value.outData)));
      }
    }).catch((error: BusinessError) => {
      Logger.error(CommonConstants.TAG, `finishSession failed, cause ${error.code} ${error.message}`);
    })
    return new Uint8Array(result);
  }

  /**
   * Encrypt option.
   *
   * @param keyAlias key alias.
   * @param data Data to be encrypted.
   */
  async encrypt(keyAlias: string, data: string) {
    if (!keyAlias || keyAlias.length === 0 || !data || data.length === 0) {
      return;
    }
    let encryptData: Uint8Array = new Uint8Array();
    let properties = this.getProperties();
    properties[1].value = huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT;
    properties.push({
      tag: huks.HuksTag.HUKS_TAG_IV,
      value: this.StringToUint8Array(this.IV)
    } as huks.HuksParam);
    let options: huks.HuksOptions = {
      properties: properties,
      inData: this.StringToUint8Array(data)
    };
    await this.huksProcess(keyAlias, options).then((result) => {
      encryptData = result;
    }).catch((error: BusinessError) => {
      Logger.error(CommonConstants.TAG, `finishSession failed, cause ${error.code} ${error.message}`);
    })
    return encryptData;
  }

  /**
   * Decrypt option.
   *
   * @param keyAlias key alias.
   * @param data Data to be decrypted.
   */
  async decrypt(keyAlias: string, data: Array<number>) {
    if (!keyAlias || keyAlias.length === 0 || !data) {
      return;
    }
    let decryptData: Uint8Array = new Uint8Array();
    let properties = this.getProperties();
    properties[1].value = huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT;
    properties.push({
      tag: huks.HuksTag.HUKS_TAG_IV,
      value: this.StringToUint8Array(this.IV)
    } as huks.HuksParam);
    let options: huks.HuksOptions = {
      properties: properties,
      inData: new Uint8Array(data)
    };
    await this.huksProcess(keyAlias, options).then((result) => {
      decryptData = result;
    }).catch((error: BusinessError) => {
      Logger.error(CommonConstants.TAG, `finishSession failed, cause ${error.code} ${error.message}`);
    })
    let result = this.Uint8ArrayToString(decryptData);
    return result;
  }

  /**
   * Converting Strings to Arrays
   *
   * @param str string
   */
  StringToUint8Array(str: string) {
    let textEncoder = util.TextEncoder.create('utf-8');
    return textEncoder.encodeInto(str);
  }

  /**
   * Converting Arrays to Strings
   *
   * @param fileData arrays
   */
  Uint8ArrayToString(data: Uint8Array) {
    let textDecoder = util.TextDecoder.create('utf-8');
    return textDecoder.decodeWithStream(data);
  }

  /**
   * check whether a key exists
   *
   * @param keyAlias
   */
  isKeyItemExist(keyAlias: string) {
    let emptyOptions: huks.HuksOptions = {
      properties: []
    };
    return huks.isKeyItemExist(keyAlias, emptyOptions);
  }
}

export default new HuksModel();

以下代码实现用户登录

import CommonConstants from '../common/constants/CommonConstants';
import { router, window } from '@kit.ArkUI';
import PreferenceModel from '../model/PreferenceModel';
import PromptUtil from '../common/utils/PromptUtil';
import { util } from '@kit.ArkTS';
import HuksModel from '../model/HuksModel';
import { BusinessError } from '@kit.BasicServicesKit';
import UserAuthModel from '../model/xiaomi-on-line-shop';
import Logger from '../common/utils/Logger';
import { RegisterPage } from '../view/RegisterPage';

@Extend(TextInput)
function inputStyle() {
  .placeholderColor($r('app.color.placeholder_color'))
  .height($r('app.float.login_input_height'))
  .fontSize($r('app.float.big_text_size'))
  .backgroundColor(Color.White)
  .width(CommonConstants.FULL_PARENT)
  .padding({ left: CommonConstants.INPUT_PADDING_LEFT })
  .margin({ top: $r('app.float.input_margin_top') })
}

@Extend(Line)
function lineStyle() {
  .width(CommonConstants.FULL_PARENT)
  .height($r('app.float.line_height'))
  .backgroundColor($r('app.color.line_color'))
}

@Extend(Text)
function blueTextStyle() {
  .fontColor($r('app.color.login_blue_color'))
  .fontSize($r('app.float.small_text_size'))
  .fontWeight(FontWeight.Medium)
}

/**
 * Login Page.
 */
@Entry
@Component
struct LoginPage {
  @State account: string = '';
  @State password: string = '';
  @Provide('isFace') isFace: boolean = false;
  @Provide('isFingerprint') isFingerprint: boolean = false;
  @State isLogin: boolean = false;
  @Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack();
  @StorageLink('userLogin') userLogin: boolean = false;
  private keyAlias: string = CommonConstants.LOGIN_KEYS;

  onPageShow() {
    window.getLastWindow(getContext(this)).then((windowStage: window.Window) => {
      windowStage.setWindowPrivacyMode(true);
    });
    this.isFace = PreferenceModel.getPreference(CommonConstants.IS_SHOW_FACE, false) as boolean;
    this.isFingerprint = PreferenceModel.getPreference(CommonConstants.IS_SHOW_FINGERPRINT, false) as boolean;
  }

  onPageHide(): void {
    window.getLastWindow(getContext(this)).then((windowStage: window.Window) => {
      windowStage.setWindowPrivacyMode(false);
    });
  }

  @Builder
  PagesMap(name: string) {
    if (name === 'register') {
      RegisterPage()
    }
  }

  /**
   * Check whether the login button can be clicked
   */
  isLoginAvailable() {
    this.isLogin = false;
    if (this.account.length > 0 && this.password.length > 0) {
      this.isLogin = true;
    }
  }

  /**
   * Process the login process
   */
  async login() {
    if (this.account === '' || this.password === '') {
      PromptUtil.promptMessage($r('app.string.input_empty_tips'), CommonConstants.PROMPT_DURATION);
      return;
    }
    let userName = PreferenceModel.getPreference(CommonConstants.USER_NAME, '') as string;

    Logger.info('username' + userName)
    if (this.account !== userName) {
      PromptUtil.promptMessage($r('app.string.message_login_prompt'), CommonConstants.PROMPT_DURATION);
      return;
    }
    let cryptoPassword = PreferenceModel.getPreference(CommonConstants.CRYPTO_PASSWORD, '') as string;

    let base64Helper = new util.Base64Helper();
    let result = base64Helper.decodeSync(cryptoPassword);
    Logger.info('username' + JSON.stringify(result))
    await HuksModel.decrypt(this.keyAlias, Array.from(result)).then((cryptoData?: string) => {
      Logger.info('username' + cryptoData + '   ' + this.password)
      if (cryptoData && cryptoData === this.password) {
        this.userLogin = true;
        router.replaceUrl({
          url: 'pages/MainPage'
        });
      } else {
        PromptUtil.promptMessage($r('app.string.message_login_prompt'), CommonConstants.PROMPT_DURATION);
      }
    }).catch((error: BusinessError) => {
      Logger.error(`huks decode failed cause ${error.code} ${error.message}`);
      PromptUtil.promptMessage($r('app.string.message_login_prompt'), CommonConstants.PROMPT_DURATION);
    })
  }

  /**
   * Operations After a User Is Successfully Authenticated.
   *
   * @param Whether the user authentication is successful.
   */
  userAuthResult: (isSuccess: boolean) => void = (isSuccess: boolean) => {
    if (isSuccess) {
      this.userLogin = true;
      router.replaceUrl({
        url: 'pages/MainPage'
      });
    }
  }

  build() {
    Navigation(this.pageInfos) {
      Column() {
        Image($r("app.media.app_icon"))
          .width($r('app.float.logo_image_size'))
          .height($r('app.float.logo_image_size'))
          .margin({
            top: $r('app.float.logo_margin_top'),
            bottom: $r('app.float.logo_margin_bottom')
          })
        Text($r('app.string.login_page'))
          .fontSize($r('app.float.title_text_size'))
          .fontWeight(FontWeight.Medium)
          .fontColor($r('app.color.title_text_color'))
        Text($r('app.string.login_more'))
          .fontSize($r('app.float.normal_text_size'))
          .fontColor($r('app.color.login_text_color'))
          .margin({
            bottom: $r('app.float.login_bottom'),
            top: $r('app.float.login_top')
          })

        Column() {
          TextInput({ placeholder: $r('app.string.account') })
            .maxLength(CommonConstants.INPUT_ACCOUNT_LENGTH)
            .type(InputType.USER_NAME)
            .inputStyle()
            .onChange((value: string) => {
              this.account = value;
              this.isLoginAvailable();
            })

          Line().lineStyle()

          TextInput({ placeholder: $r('app.string.password') })
            .maxLength(CommonConstants.INPUT_PASSWORD_LENGTH)
            .type(InputType.Password)
            .inputStyle()
            .onChange((value: string) => {
              this.password = value;
              this.isLoginAvailable();
            })
        }
        .backgroundColor(Color.White)
        .borderRadius($r('app.float.input_border_radius'))
        .padding({
          top: $r('app.float.input_padding_top'),
          bottom: $r('app.float.input_padding_top'),
          left: $r('app.float.input_padding_left'),
          right: $r('app.float.input_padding_left')
        })

        Row() {
          Text($r('app.string.message_login')).blueTextStyle()
          Text($r('app.string.forgot_password')).blueTextStyle()
        }
        .justifyContent(FlexAlign.SpaceBetween)
        .width(CommonConstants.FULL_PARENT)
        .padding({
          top: $r('app.float.forgot_margin_top'),
          left: $r('app.float.forgot_margin_left'),
          right: $r('app.float.forgot_margin_right')
        })

        Button($r('app.string.login'), { type: ButtonType.Capsule })
          .width(CommonConstants.BUTTON_WIDTH)
          .height($r('app.float.login_button_height'))
          .fontSize($r('app.float.normal_text_size'))
          .fontWeight(FontWeight.Medium)
          .backgroundColor(this.isLogin ? $r('app.color.login_button_color') : $r('app.color.button_color_unavailable'))
          .margin({
            top: $r('app.float.button_top'),
            bottom: $r('app.float.button_bottom')
          })
          .enabled(this.isLogin)
          .onClick(() => {
            this.login();
          })
        Text($r('app.string.register_account'))
          .fontColor($r('app.color.login_blue_color'))
          .fontSize($r('app.float.normal_text_size'))
          .fontWeight(FontWeight.Medium)
          .onClick(() => {
            this.pageInfos.pushPathByName('register', null);
          })

        Blank()

        if (this.isFace || this.isFingerprint) {
          Text($r('app.string.other_login_method'))
            .fontColor($r('app.color.other_login_color'))
            .fontSize($r('app.float.little_text_size'))
            .fontWeight(FontWeight.Medium)
            .margin({
              top: $r('app.float.other_margin_top'),
              bottom: $r('app.float.other_margin_bottom')
            })
          Row({ space: CommonConstants.LOGIN_METHODS_SPACE }) {
            if (this.isFace) {
              Button({ type: ButtonType.Circle, stateEffect: true }) {
                Image($r('app.media.face'))
              }
              .height($r('app.float.other_image_size'))
              .width($r('app.float.other_image_size'))
              .backgroundColor($r('app.color.background'))
              .onClick(() => {
                UserAuthModel.getFaceAuth(this.userAuthResult);
                UserAuthModel.start();
              })
            }

            if (this.isFingerprint) {
              Button({ type: ButtonType.Circle, stateEffect: true }) {
                Image($r('app.media.touchid'))
              }
              .height($r('app.float.other_image_size'))
              .width($r('app.float.other_image_size'))
              .backgroundColor($r('app.color.background'))
              .onClick(() => {
                UserAuthModel.getFingerprintAuth(this.userAuthResult);
                UserAuthModel.start();
              })
            }
          }
        }
      }
      .backgroundColor($r('app.color.background'))
      .height(CommonConstants.FULL_PARENT)
      .width(CommonConstants.FULL_PARENT)
      .padding({
        left: $r('app.float.page_padding_hor'),
        right: $r('app.float.page_padding_hor'),
        bottom: $r('app.float.login_page_bottom')
      })
    }
    .navDestination(this.PagesMap)
    .hideTitleBar(true)
    .hideToolBar(true)
    .mode(NavigationMode.Stack)
    .backgroundColor($r('app.color.background'))
  }
}

以下代码实现注册功能。


import CommonConstants from '../common/constants/CommonConstants';
import PromptUtil from '../common/utils/PromptUtil';
import HuksModel from '../model/HuksModel';
import { BusinessError } from '@kit.BasicServicesKit';
import Logger from '../common/utils/Logger';
import { util } from '@kit.ArkTS';
import PreferenceModel from '../model/PreferenceModel';
import UserAuthModel from '../model/xiaomi-on-line-shop';

@Extend(TextInput)
function inputStyle() {
  .placeholderColor($r('app.color.placeholder_color'))
  .height($r('app.float.login_input_height'))
  .fontSize($r('app.float.big_text_size'))
  .backgroundColor(Color.White)
  .width(CommonConstants.FULL_PARENT)
  .padding({ left: CommonConstants.INPUT_PADDING_LEFT })
  .margin({ top: $r('app.float.input_margin_top') })
}

@Extend(Line)
function lineStyle() {
  .width(CommonConstants.FULL_PARENT)
  .height($r('app.float.line_height'))
  .backgroundColor($r('app.color.line_color'))
}

@Component
export struct RegisterPage {
  @State isShowFace: boolean = false;
  @State isShowFingerprint: boolean = false;
  @State isRegisterAvailable: boolean = false;
  @Consume('pageInfos') pageInfos: NavPathStack;
  private name: string = '';
  private passWord: string = '';
  private confirmPassWord: string = '';
  @Consume('isFace') isFace : boolean;
  @Consume('isFingerprint') isFingerprint: boolean;
  private keyAlias: string = CommonConstants.LOGIN_KEYS;

  /**
   * Check whether the registration button can be clicked.
   */
  isRegister() {
    this.isRegisterAvailable = false;
    if (this.name.length > 0 && this.passWord.length > 0 && this.confirmPassWord.length > 0) {
      this.isRegisterAvailable = true;
    }
  }

  /**
   * Process the registration process.
   */
  async register() {
    if (!this.name) {
      PromptUtil.promptMessage($r('app.string.message_user_name'), CommonConstants.PROMPT_DURATION);
      return;
    }
    if (!this.passWord || this.passWord !== this.confirmPassWord) {
      PromptUtil.promptMessage($r('app.string.message_password_prompt'), CommonConstants.PROMPT_DURATION);
      return;
    }
    let isExist = false;
    await HuksModel.isKeyItemExist(this.keyAlias)
      .then((value: boolean) => {
        isExist = value;
      })
      .catch((error: BusinessError) => {
        Logger.error(CommonConstants.TAG, `huks keys not generate cause ${error.code} ${error.message}`);
      })
    if (!isExist) {
      PromptUtil.promptMessage($r('app.string.message_application_prompt'), CommonConstants.PROMPT_DURATION);
      return;
    }
    await HuksModel.encrypt(this.keyAlias, this.passWord).then((value?: Uint8Array) => {
      if (value) {
        let base64Helper = new util.Base64Helper();
        let password = base64Helper.encodeToStringSync(value);
        PreferenceModel.putPreference(CommonConstants.CRYPTO_PASSWORD, password);
        PreferenceModel.putPreference(CommonConstants.USER_NAME, this.name);
        PreferenceModel.putPreference(CommonConstants.IS_SHOW_FACE, this.isFace);
        PreferenceModel.putPreference(CommonConstants.IS_SHOW_FINGERPRINT, this.isFingerprint);
        this.pageInfos.pop();
      }
    })
  }

  build() {
    NavDestination() {
      Row() {
        Column() {
          Image($r("app.media.app_icon"))
            .width($r('app.float.logo_image_size'))
            .height($r('app.float.logo_image_size'))
            .margin({
              top: $r('app.float.logo_margin_top'),
              bottom: $r('app.float.logo_margin_bottom')
            })
          Text($r('app.string.register_page'))
            .fontSize($r('app.float.title_text_size'))
            .fontWeight(FontWeight.Medium)
            .fontColor($r('app.color.title_text_color'))

          Column() {
            TextInput({ placeholder: $r('app.string.register_name')})
              .maxLength(CommonConstants.INPUT_ACCOUNT_LENGTH)
              .type(InputType.USER_NAME)
              .inputStyle()
              .onChange((value: string) => {
                this.name = value;
                this.isRegister();
              })

            Line().lineStyle()

            TextInput({ placeholder: $r('app.string.register_password')})
              .maxLength(CommonConstants.INPUT_PASSWORD_LENGTH)
              .type(InputType.NEW_PASSWORD)
              .inputStyle()
              .onChange((value: string) => {
                this.passWord = value;
                this.isRegister();
              })

            Line().lineStyle()

            TextInput({ placeholder: $r('app.string.register_confirm_password')})
              .maxLength(CommonConstants.INPUT_PASSWORD_LENGTH)
              .type(InputType.NEW_PASSWORD)
              .inputStyle()
              .onChange((value: string) => {
                this.confirmPassWord = value;
                this.isRegister();
              })
          }
          .backgroundColor(Color.White)
          .borderRadius($r('app.float.input_border_radius'))
          .padding({
            top: $r('app.float.input_padding_top'),
            bottom: $r('app.float.input_padding_top'),
            left: $r('app.float.input_padding_left'),
            right: $r('app.float.input_padding_left')
          })
          .margin({
            top: $r('app.float.register_margin_top')
          })

          if (this.isShowFace) {
            Row() {
              Checkbox()
                .selectedColor($r('app.color.register_checkbox'))
                .onChange((value: boolean) => {
                  this.isFace = value;
                })
              Text($r('app.string.register_face_checkbox'))
                .fontSize($r('app.float.small_text_size'))
                .fontWeight(FontWeight.Medium)
                .fontColor($r('app.color.register_text_color'))
            }
            .width(CommonConstants.FULL_PARENT)
            .margin({
              top: $r('app.float.face_margin_top'),
              left: $r('app.float.face_margin_left')
            })
          }

          if (this.isShowFingerprint) {
            Row() {
              Checkbox()
                .selectedColor($r('app.color.register_checkbox'))
                .onChange((value: boolean) => {
                  this.isFingerprint = value;
                })
              Text($r('app.string.register_fingerprint_checkbox'))
                .fontSize($r('app.float.small_text_size'))
                .fontWeight(FontWeight.Medium)
                .fontColor($r('app.color.register_text_color'))
            }
            .width(CommonConstants.FULL_PARENT)
            .margin({
              top: $r('app.float.fingerprint_margin_top'),
              left: $r('app.float.face_margin_left')
            })
          }

          Button($r('app.string.register_button'), { type: ButtonType.Capsule })
            .width(CommonConstants.BUTTON_WIDTH)
            .height($r('app.float.login_button_height'))
            .fontSize($r('app.float.normal_text_size'))
            .fontWeight(FontWeight.Medium)
            .backgroundColor(
              this.isRegisterAvailable ? $r('app.color.login_button_color') : $r('app.color.button_color_unavailable')
            )
            .margin({
              top: $r('app.float.register_button_top'),
              bottom: $r('app.float.button_bottom')
            })
            .enabled(this.isRegisterAvailable)
            .onClick(async () => {
              await this.register();
            })
        }
        .backgroundColor($r('app.color.background'))
        .height(CommonConstants.FULL_PARENT)
        .width(CommonConstants.FULL_PARENT)
        .padding({
          left: $r('app.float.page_padding_hor'),
          right: $r('app.float.page_padding_hor'),
          bottom: $r('app.float.login_page_bottom')
        })
      }
      .height(CommonConstants.FULL_PARENT)
    }
    .hideTitleBar(true)
    .onAppear(() => {
      HuksModel.isKeyItemExist(this.keyAlias)
        .then((isExist) => {
          if (!isExist) {
            HuksModel.generateKeyItem(this.keyAlias);
          }
        })
        .catch((error: BusinessError) => {
          Logger.error(CommonConstants.TAG, `huks keys not generate ${error.code} ${error.message}`);
          HuksModel.generateKeyItem(this.keyAlias);
        })
      this.isShowFace = UserAuthModel.isFaceAvailable();
      this.isShowFingerprint = UserAuthModel.isFingerprintAvailable();
      this.isFace = false;
      this.isFingerprint = false;
    })
  }
}

 商城主页面代码。


/**
 * Home tab content.
 */
import CommonConstants from '../common/constants/CommonConstants';
import ItemData from '../model/ItemDataModel';
import mainViewModel from '../viewmodel/MainViewModel';

@Component
export default struct Home {
  private swiperController: SwiperController = new SwiperController();
  
  build() {
    Scroll() {
      Column({ space: CommonConstants.COMMON_SPACE }) {
        Swiper(this.swiperController) {
          ForEach(mainViewModel.getSwiperImages(), (img: Resource) => {
            Image(img).borderRadius($r('app.float.home_swiper_radius'))
          })
        }
        .margin({ top:$r('app.float.home_swiper_margin') })
        .autoPlay(true)

        Grid() {
          ForEach(mainViewModel.getFirstGridData(), (item: ItemData) => {
            GridItem() {
              Column() {
                Image(item.img)
                  .width($r('app.float.home_cell_size'))
                  .height($r('app.float.home_cell_size'))
                Text(item.title)
                  .fontSize($r('app.float.little_text_size'))
                  .margin({ top: $r('app.float.home_cell_margin') })
              }
            }
          }, (item: ItemData, index: number) => index + JSON.stringify(item))
        }
        .columnsTemplate(CommonConstants.HOME_COLUMNS_TEMPLATE)
        .rowsTemplate(CommonConstants.HOME_ROWS_TEMPLATE)
        .columnsGap($r('app.float.home_grid_gap'))
        .rowsGap($r('app.float.home_row_gap'))
        .padding({
          top: $r('app.float.home_grid_padding'),
          bottom: $r('app.float.home_grid_padding')
        })
        .height($r('app.float.home_grid_height'))
        .backgroundColor(Color.White)
        .borderRadius($r('app.float.home_border_radius'))

        Text($r('app.string.home_list'))
          .fontSize($r('app.float.normal_text_size'))
          .fontWeight(FontWeight.Medium)
          .width(CommonConstants.FULL_PARENT)
          .margin({ top : $r('app.float.home_text_margin') })

        Grid() {
          ForEach(mainViewModel.getSecondGridData(), (secondItem: ItemData) => {
            GridItem() {
              Column() {
                Text(secondItem.title)
                  .fontSize($r('app.float.normal_text_size'))
                  .fontWeight(FontWeight.Medium)
                Text(secondItem.others)
                  .margin({ top: $r('app.float.home_list_margin') })
                  .fontSize($r('app.float.little_text_size'))
                  .fontColor($r('app.color.home_grid_font'))
              }
              .alignItems(HorizontalAlign.Start)
            }
            .padding({
              top: $r('app.float.home_list_padding'),
              left: $r('app.float.home_list_padding')
            })
            .borderRadius($r('app.float.home_image_radius'))
            .align(Alignment.TopStart)
            .backgroundImage(secondItem.img)
            .backgroundImageSize(ImageSize.Cover)
            .width(CommonConstants.FULL_PARENT)
            .height(CommonConstants.FULL_PARENT)
          }, (secondItem: ItemData, index: number) => index + JSON.stringify(secondItem))
        }
        .width(CommonConstants.FULL_PARENT)
        .height($r('app.float.home_second_height'))
        .columnsTemplate(CommonConstants.SECOND_COLUMNS_TEMPLATE)
        .rowsTemplate(CommonConstants.SECOND_ROWS_TEMPLATE)
        .columnsGap($r('app.float.home_grid_gap'))
        .rowsGap($r('app.float.home_row_gap'))
        .margin({ bottom: $r('app.float.setting_button_bottom')})
      }
    }
    .height(CommonConstants.FULL_PARENT)
  }
}

运行截图

图3-1是软件桌面显示。

图3-1

图3-2是商城登录页面。

图3-2

图3-3是商城账号注册页面。

图3-3

图3-4是商品主页面。

图3-4

图3-5是个人信息页面。

图3-5

项目参考: UserAuth: 本示例主要使用人脸和指纹认证用户身份、使用密码保险箱实现密码自动填充以及涉及口令输入的应用界面防截屏或录屏等功能的实现方式。icon-default.png?t=O83Ahttps://gitee.com/harmonyos_samples/UserAuth

标签:string,color,app,float,CommonConstants,HarmonyOS,小米,top,仿造
From: https://blog.csdn.net/2401_85573077/article/details/144564463

相关文章

  • HarmonyOS鸿蒙开发 - 解决上下两栏白边 - 沉浸式效果
    鸿蒙应用开发从入门到入行预览器上下两栏白边自从HarmonyOS升级到release版后,很多同学会问猫林老师:为什么他的预览器上下有白边,为什么明明根容器写了宽高百分百但没铺满。如下图白边原因其实上面的白边,称之为状态栏。上面会放手机wifi信号、电池电量等信息。一般情况下......
  • HarmonyOS NEXT基础入门
    基础入门储存鸿蒙应用提供多种数据存储方式,包括:Preferences:轻量级数据存储,适用于简单键值对。SQLite:关系型数据库,适用于结构化数据存储。文件存储:通过文件系统直接存储数据。数组数组是一组有序的数据集合,可以通过索引访问每个元素。letnumbers=[1,2,3,4,5];con......
  • 「九」HarmonyOS 5 端云一体化实战项目——「M.U.」应用云侧开发云数据库
    1立意背景M.代表“我”,U.代表“你”,这是一款用于记录情侣从相识、相知、相恋、见家长、订婚直至结婚等各个阶段美好记忆留存的应用程序。它旨在为情侣们提供一个专属的空间,让他们能够将一路走来的点点滴滴,如初次相遇时的心动瞬间、逐渐了解彼此过程中的深入交流、甜蜜......
  • HarmonyOS应用开发--LazyForeach懒加载
    引言在鸿蒙应用开发中,ArkTS(ArkTypeScript)作为开发语言,提供了丰富的API来构建高效、流畅的应用程序。其中,LazyForeach作为一种懒加载技术,对于优化性能和提升用户体验具有重要作用。本文将对LazyForeach懒加载进行深入学习总结。ArkTS简介ArkTS是基于TypeScript的开发语言,专......
  • HarmonyOS 获取进程相关的信息process 常用的几个方法
    获取进程相关的信息,提供进程管理的相关功能。process1.EventListener2.isIsolatedProcess3.is64Bit4.getStartRealtime5.getPastCpuTime导入模块import{process}from'@kit.ArkTS';属性名称类型可读可写说明uidnumber是否进程的用户标识。pidnumber是......
  • HarmonyOS:@Extend装饰器:定义扩展组件样式
    一、前言使用@Styles用于样式的重用,在@Styles的基础上,使用@Extend扩展原生组件样式。说明从APIversion9开始,该装饰器支持在ArkTS卡片中使用。从APIversion11开始,该装饰器支持在元服务中使用。二、装饰器使用说明语法@Extend(UIComponentName)functionfu......
  • 华为HarmonyOS实现跨多个子系统融合的场景化服务 -- 3 打开授权设置页Button
    场景介绍本章节将向您介绍如何使用Button组件打开授权设置页功能,开发者可调用对应Button组件跳转到应用对应的权限设置页面,供用户快速进行应用权限的查看和修改。效果图展示单击“打开授权设置页”按钮,跳转至应用对应的设置页界面。开发步骤导入ScenarioFusionKit模块......
  • HarmonyOS Next 入门实战 - 文字转拼音,文字转语音
    文字转拼音安装pinyin4js三方库ohpminstall@ohos/pinyin4jspinyin4js提供了以下接口:●文字转拼音(带声调和不带声调)●文字转拼音首字母●简体繁体互转letrawText="风急天高猿萧哀,渚清沙白鸟飞回;"letpinyin1:string=pinyin4js.convertToPinyinString(rawT......
  • HarmonyOS Next分布式智能家居控制系统实战
    本文旨在深入探讨基于华为鸿蒙HarmonyOSNext系统(截止目前API12)构建分布式智能家居控制系统的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。一、项......
  • HarmonyOS Next 设备适配与生态拓展
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)在设备适配与生态拓展方面的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。一、设备适配......