HarmonyOS NEXT 实战之元服务:静态案例效果---我的快递查询

背景:

前几篇学习了元服务,后面几期就让我们开发简单的元服务吧,里面丰富的内容大家自己加,本期案例 仅供参考

先上本期效果图 ,里面图片自行替换

效果图1完整代码案例如下:

  • Index

    import { authentication } from '@kit.AccountKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    import { hilog } from '@kit.PerformanceAnalysisKit';
    import { EventMyItem } from './EventMyItem';
    import { SearchBar } from './SearchBar';
    import { promptAction } from '@kit.ArkUI';

    export class ListItem1 {
    img: ResourceStr;
    title: string;
    yuji: string;
    content: string;
    danhao: string;

    复制代码
    constructor(img: ResourceStr, title: string, yuji: string, content: string, danhao: string) {
      this.img = img;
      this.title = title;
      this.yuji = yuji;
      this.content = content;
      this.danhao = danhao;
    }

    }

    @Entry
    @Component
    struct Index {
    @State message: string = 'Hello World';
    @State listItem1: ListItem1[] = [
    new ListItem1(r('app.media.img'), '运输中', '预计12.31送达', '手机尾号1415的包裹', '邮政快递包裹 | 9857489893889'), new ListItem1(r('app.media.img'), '运输中', '预计明天送达', '手机尾号1415的包裹',
    '邮政快递包裹 | 98574898589'),
    new ListItem1(r('app.media.img_1'), '已发货', '', '天猫|漫花400张20大包纸巾抽纸...', '极兔快递包裹 | 98578545889'), new ListItem1(r('app.media.img_2'), '已签收', '本人签收', '手机尾号1415的包裹', '中通快递包裹 | 985740124889'),
    new ListItem1($r('app.media.img_2'), '运输中', '预计12.29送达', '手机尾号1415的包裹', '中通快递包裹 | 985796582'),

    复制代码
    ]
    
    build() {
      Column() {
        Text($r('app.string.EntryAbility_label')).fontSize(20).margin({ bottom: 10 })
        SearchBar({
          onClickVoice: () => {
            promptAction.showToast({ message: '暂无查询的快递,请稍后重试' })
          }
        })
        List({ space: 6 }) {
          ForEach(this.listItem1, (item: ListItem1) => {
            ListItem() {
              EventMyItem({ data: item })
            }.onClick(() => {
              promptAction.showToast({ message: '您的快递正在:' + item.title })
            })
    
          })
    
    
        }
    
      }
      .alignItems(HorizontalAlign.Start)
      .height('100%')
      .padding(8)
      .width('100%')
      .margin({ top: 40 })
    }
    
    aboutToAppear() {
    
    
      hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
      this.loginWithHuaweiID();
    }
    
    /**
     * Sample code for using HUAWEI ID to log in to atomic service.
     * According to the Atomic Service Review Guide, when a atomic service has an account system,
     * the option to log in with a HUAWEI ID must be provided.
     * The following presets the atomic service to use the HUAWEI ID silent login function.
     * To enable the atomic service to log in successfully using the HUAWEI ID, please refer
     * to the HarmonyOS HUAWEI ID Access Guide to configure the client ID and fingerprint certificate.
     */
    private loginWithHuaweiID() {
      // Create a login request and set parameters
      let loginRequest = new authentication.HuaweiIDProvider().createLoginWithHuaweiIDRequest();
      // Whether to forcibly launch the HUAWEI ID login page when the user is not logged in with the HUAWEI ID
      loginRequest.forceLogin = false;
      // Execute login request
      let controller = new authentication.AuthenticationController();
      controller.executeRequest(loginRequest).then((data) => {
        let loginWithHuaweiIDResponse = data as authentication.LoginWithHuaweiIDResponse;
        let authCode = loginWithHuaweiIDResponse.data?.authorizationCode;
        // Send authCode to the backend in exchange for unionID, session
    
      }).catch((error: BusinessError) => {
        hilog.error(0x0000, 'testTag', 'error: %{public}s', JSON.stringify(error));
        if (error.code == authentication.AuthenticationErrorCode.ACCOUNT_NOT_LOGGED_IN) {
          // HUAWEI ID is not logged in, it is recommended to jump to the login guide page
    
        }
      });
    }

    }

  • SearchBar

    /**

    • Author:J

    • Describe:SearchBar

    • ----------使用 leftView-------------------------------
      @State textOne: string = '标准';
      @State textTwo: string = '精准';
      @State textOneAngle: number = 0;
      @State textTwoAngle: number = 0;

    • SearchBar({

    • leftView: this.leftViewBuilder.bind(this),

    • })

    @Builder leftViewBuilder() {
    Row() {
    titleImage({
    text: this.textOne,
    angle: this.textOneAngle,
    onClick: () => {
    this.textOne = '标题,原文'
    this.textOneAngle = this.textOneAngle == 0 ? 180 : 0
    }
    })
    titleImage({
    text: this.textTwo,
    angle: this.textTwoAngle,
    onClick: () => {
    this.textTwoAngle = this.textTwoAngle == 0 ? 180 : 0
    }
    })
    }
    }

    • ----------使用 leftView-------------------------------
      */
      @Preview
      @ComponentV2
      export struct SearchBar {
      //左边视图
      @BuilderParam leftView: () => void = this.leftViewBuilder;
      //输入内容
      @Param textInput: string = '';
      @Param onChange: (value: string) => void = () => {
      };
      @Param onSubmit: (enterKey: EnterKeyType) => void = () => {
      };
      //语音点击
      @Param onClickVoice: (event?: ClickEvent) => void = () => {
      };
    复制代码
    build() {
      Row() {
    
        this.leftView()
    
        TextInput({ text: this.textInput, placeholder: '请输入搜索内容' })
          .width('100%')
          .layoutWeight(1)
          .padding({ left: 8 })
          .backgroundColor(Color.White)
          .placeholderColor('#999999')
          .placeholderFont({ size: 14, weight: 400 })//光标颜色
          // .caretColor($r('app.color.colorPrimary'))
          .enterKeyType(EnterKeyType.Search)//输入内容发生变化时,触发该回调
          .onChange(this.onChange)// 按下输入法回车键触发该回调,返回值为当前输入法回车键的类型
          .onSubmit(this.onSubmit)
    
        // Image($r('app.media.ic_clear_input_text')).width(16).margin(10)
        Image($r('app.media.ic_local_search')).width(24).margin(8).onClick(this.onClickVoice)
    
      }
      .width('100%')
      .height(40)
      .border({ width: 1, color: '#222222', radius: 6 })
    }
    
    @Builder
    leftViewBuilder() {
    }

    }

    interface TitleImageOption {
    text: string,
    angle: number,
    onClick: (event?: ClickEvent) => void
    }

    @Builder
    export function titleImage($$: TitleImageOption) {
    Row() {
    Text($$.text)
    .width(30)
    .maxLines(1)
    .textOverflow({ overflow: TextOverflow.Ellipsis })
    .fontSize(14)
    .fontColor('#222222')
    Image(r('app.media.ic_local_search')).width(12).margin({ left: 4 }).rotate({ angle: .angle }) } .padding(4) .onClick($.onClick)
    }

  • Item

    import { ListItem1 } from "./Index"

    @ComponentV2
    export struct EventMyItem {
    @Param data: ListItem1 = new ListItem1('', '', '', '','')

    复制代码
    build() {
      Column() {
        Row({ space: 6 }) {
          Image(this.data.img).width(60).height(60).borderRadius(10)
          Column({ space: 6 }) {
            Row({space:6}){
              Text(this.data.title)
                .fontColor('#222222')
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
              Text(this.data.yuji)
                .fontColor(Color.Blue)
                .fontSize(14)
            }
    
            Text(this.data.content)
              .fontColor('#888888')
              .fontSize(16)
            Text(this.data.danhao)
              .fontColor('#092D3E')
              .padding(8)
              .borderRadius(8)
              .backgroundColor('#EBF4FF')
              .fontSize(16)
          }.alignItems(HorizontalAlign.Start)
    
        }.width("100%")
        .justifyContent(FlexAlign.Start)
        .alignItems(VerticalAlign.Top)
    
      }
      .width("100%")
      .margin({ top: 4, bottom: 4 })
      .padding({
        right: 12,
        left: 12,
        top: 8,
        bottom: 6
      })
      .border({ width: 1, radius: 8, color: '#F0F0F0' })
    }

    }

    function generateRandomDate(): string {
    const minYear = 2024; // 最小年份
    const maxYear = 2024; // 最大年份
    const minMonth = 12; // 最小月份
    const maxMonth = 12; // 最大月份
    const minDay = 1; // 最小日期
    const maxDay = 31; // 最大日期

    复制代码
    // 生成随机年份
    const year = Math.floor(Math.random() * (maxYear - minYear + 1)) + minYear;
    
    // 生成随机月份
    const month = Math.floor(Math.random() * (maxMonth - minMonth + 1)) + minMonth;
    
    // 根据月份生成合理的日期
    let day = 0;
    if ([1, 3, 5, 7, 8, 10, 12].includes(month)) {
      day = Math.floor(Math.random() * (31 - minDay + 1)) + minDay;
    } else if ([4, 6, 9, 11].includes(month)) {
      day = Math.floor(Math.random() * (30 - minDay + 1)) + minDay;
    } else if (month === 2) {
      // 处理闰年
      if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
        day = Math.floor(Math.random() * (29 - minDay + 1)) + minDay;
      } else {
        day = Math.floor(Math.random() * (28 - minDay + 1)) + minDay;
      }
    }
    
    // 返回格式化的日期字符串
    return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;

    }

    function generateFiveDigitRandomNumber(): number {
    const min = 100; // 五位数的最小值
    const max = 999; // 五位数的最大值
    return Math.floor(Math.random() * (max - min + 1)) + min;
    }

最近文章>>>>>>>>>>>

HarmonyOS NEXT实战:元服务与应用 APP 发布应用市场的详细步骤与流程

若本文对您稍有帮助,诚望您不吝点赞,多谢。

有兴趣的同学可以点击查看源码

相关推荐
行者961 小时前
Flutter与OpenHarmony深度集成:数据导出组件的实战优化与性能提升
flutter·harmonyos·鸿蒙
小雨下雨的雨1 小时前
Flutter 框架跨平台鸿蒙开发 —— Row & Column 布局之轴线控制艺术
flutter·华为·交互·harmonyos·鸿蒙系统
小雨下雨的雨1 小时前
Flutter 框架跨平台鸿蒙开发 —— Center 控件之完美居中之道
flutter·ui·华为·harmonyos·鸿蒙
小雨下雨的雨2 小时前
Flutter 框架跨平台鸿蒙开发 —— Icon 控件之图标交互美学
flutter·华为·交互·harmonyos·鸿蒙系统
小雨下雨的雨2 小时前
Flutter 框架跨平台鸿蒙开发 —— Placeholder 控件之布局雏形美学
flutter·ui·华为·harmonyos·鸿蒙系统
行者963 小时前
OpenHarmony Flutter弹出菜单组件深度实践:从基础到高级的完整指南
flutter·harmonyos·鸿蒙
小雨下雨的雨4 小时前
Flutter 框架跨平台鸿蒙开发 —— Padding 控件之空间呼吸艺术
flutter·ui·华为·harmonyos·鸿蒙系统
行者964 小时前
Flutter到OpenHarmony:横竖屏自适应布局深度实践
flutter·harmonyos·鸿蒙
小雨下雨的雨4 小时前
Flutter 框架跨平台鸿蒙开发 —— Align 控件之精准定位美学
flutter·ui·华为·harmonyos·鸿蒙
行者965 小时前
Flutter与OpenHarmony集成:跨平台开关组件的实践与优化
flutter·harmonyos·鸿蒙