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 发布应用市场的详细步骤与流程

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

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

相关推荐
轻口味38 分钟前
【每日学点鸿蒙知识】hap安装报错、APP转移账号、import本地文件、远程包构建问题、访问前端页面方法
前端·华为·harmonyos
轻口味1 小时前
【每日学点鸿蒙知识】Web请求支持Http、PDF展示、APP上架应用搜索问题、APP备案不通过问题、滚动列表问题
前端·http·harmonyos
轻口味2 小时前
【每日学点鸿蒙知识】webview性能优化、taskpool、热更新、Navigation问题、调试时每次都卸载重装问题
javascript·list·harmonyos
kirk_wang5 小时前
Flutter适配HarmonyOS实践
flutter·华为·harmonyos
Jalor6 小时前
HarmonyOS NEXT | 一文搞懂 华为账号登录(获取UnionID/OpenID)
spring boot·flutter·harmonyos
carrie呀carrie8 小时前
HarmonyOS:删除多层ForEach循环渲染的复杂数据而导致的一系列问题
开发语言·harmonyos·鸿蒙
轻口味9 小时前
【每日学点鸿蒙知识】启动耗时分析、IDE报错、emitter内存泄漏、radio C API、SDK下载失败
c语言·华为·harmonyos
轻口味9 小时前
【每日学点鸿蒙知识】混淆配置、主线程处理大量数据、客户端拖拽效果、三方网站加载样式、List警告问题
华为·harmonyos
李游Leo9 小时前
自学记录HarmonyOS Next Image API 13:图像处理与传输的开发实践
图像处理·华为·harmonyos
JasonYin~10 小时前
HarmonyOS NEXT 实战之元服务:静态案例效果---我的生活记录
华为·生活·harmonyos