实现简易元服务卡片Demo

通过元服务卡片实现一个简易资讯推送卡片的功能。元服务卡片主要使用场景如天气、关键事务备忘、热点新闻列表等。

HarmonyOS
2024-05-26 14:57:34
浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
失望的满天星

核心代码

编写卡片显示页

import { Info } from '../../utils/interface' 
 
@Entry 
@Component 
struct WidgetCard { 
  /* 
   * The display priority value is 1. 
   */ 
  readonly DISPLAY_PRIORITY_ONE: number = 1; 
  /* 
   * The display priority value is 2. 
   */ 
  readonly DISPLAY_PRIORITY_TWO: number = 2; 
  /* 
   * The flex grow value is 1. 
   */ 
  readonly FLEX_GROW_VALUE: number = 1; 
  /* 
   * The width or height full percentage setting. 
   */ 
  readonly FULL_PERCENT: string = '100%'; 
  /* 
   * The height of image. 
   */ 
  readonly IMAGE_HEIGHT: string = '58%'; 
  /* 
   * The action type. 
   */ 
  readonly ACTION_TYPE: string = 'router'; 
  /* 
   * The ability name. 
  */ 
  readonly ABILITY_NAME: string = 'EntryAbility'; 
  /* 
   * The message. 
   */ 
  readonly MESSAGE: string = 'add detail'; 
  /* 
   * The layoutWeightValue. 
   */ 
  readonly LAYOUT_WEIGHT_VALUE: number = 1; 
  /* 
   * The maxLinesValue. 
   */ 
  readonly MAX_LINES_VALUE: number = 1; 
  private swiperController: SwiperController = new SwiperController() 
  private data: Info = { 
    src: $r('app.media.hot'), 
    title: '热辣滚烫成春节档最大赢家?', 
    introduction: '2024年2月20日 — 中国女演员贾玲自导自演的喜剧电影《热辣滚烫》以27.2亿元人民币的票房成为春节档期的冠军,打破影史春节档剧情片票房纪录。' 
  } 
 
  build() { 
    Stack({ alignContent: Alignment.TopStart }) { 
 
      Flex({ direction: FlexDirection.Column }) { 
        Flex({ direction: FlexDirection.Row }) { 
          Column() { 
            Image(this.data.src) 
              .width(this.FULL_PERCENT) 
              .height(this.IMAGE_HEIGHT) 
              .borderRadius($r('app.float.image_border_radius')) 
              .margin({ bottom: $r('app.float.image_margin_bottom') }) 
              .flexGrow(this.FLEX_GROW_VALUE) 
            Column() { 
              Text(this.data.title) 
                .fontSize($r('app.float.card_title_font_size')) 
                .width(this.FULL_PERCENT) 
                .fontColor($r('app.color.information_title_font')) 
                .fontWeight(FontWeight.Medium) 
                .maxLines(this.MAX_LINES_VALUE) 
                .textOverflow({ overflow: TextOverflow.Ellipsis }) 
              Text(this.data.introduction) 
                .fontSize($r('app.float.item_font_size')) 
                .width(this.FULL_PERCENT) 
                .fontColor($r('app.color.item_text_font')) 
                .fontWeight(FontWeight.Regular) 
                .margin({ top: $r('app.float.item_margin_top') }) 
                .maxLines(this.MAX_LINES_VALUE) 
                .textOverflow({ overflow: TextOverflow.Ellipsis }) 
            } 
            .justifyContent(FlexAlign.Center) 
            .layoutWeight(this.LAYOUT_WEIGHT_VALUE) 
            .flexGrow(this.FLEX_GROW_VALUE) 
          } 
          .width($r('app.float.info_column_width')) 
          .height(this.FULL_PERCENT) 
          .flexGrow(this.FLEX_GROW_VALUE) 
        } 
        .backgroundColor($r('app.color.image_info_background')) 
        .displayPriority(this.DISPLAY_PRIORITY_TWO) 
        .flexGrow(this.FLEX_GROW_VALUE) 
        .height($r('app.float.info_column_height')) 
        .padding($r('app.float.info_column_padding')) 
      } 
    } 
    .onClick(() => { 
      postCardAction(this, { 
        action: this.ACTION_TYPE, 
        abilityName: this.ABILITY_NAME, 
        params: { 
          message: this.data 
        } 
      }); 
    }) 
  } 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.

ability接收卡片数据

// 如果UIAbility第一次启动,在收到Router事件后会触发onCreate生命周期回调 
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { 
  console.info("onCreate want:" + JSON.stringify(want)); 
  if (want.parameters?.params !== undefined) { 
    let data: Info = JSON.parse(want.parameters?.params.toString()).message; 
    console.info("data:" + data); 
    globalThis.data = data; 
  } 
} 
// 如果UIAbility已在后台运行,在收到Router事件后会触发onNewWant生命周期回调 
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam) { 
  console.info("onNewWant want:" + JSON.stringify(want)); 
  if (want.parameters?.params !== undefined) { 
    let data: Info = JSON.parse(want.parameters?.params.toString()).message; 
    console.info("data:" + data); 
    globalThis.data = data; 
  } 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

主页渲染

import { authentication } from '@kit.AccountKit'; 
import { BusinessError } from '@kit.BasicServicesKit'; 
import { hilog } from '@kit.PerformanceAnalysisKit'; 
import { Info } from '../utils/interface' 
 
@Entry 
@Component 
struct Index { 
  @State message: string = 'Hello World'; 
  @State popData: Info | undefined = undefined; 
  @State normalData: Info = { 
    src: $r('app.media.food'), 
    title: '火锅是否影响了当代年轻人健康?', 
    introduction: '2024年2月20日 — 据有关部门统计,现如今年轻人患病胃癌,直肠癌的比例越打越大,专家提倡年轻人应该少吃辛辣食物,提倡多运动,注意身体健康。' 
  }; 
  @State currentIndex: number = 0; 
  private controller: TabsController = new TabsController(); 
 
  aboutToAppear() { 
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); 
    this.loginWithHuaweiID(); 
  } 
 
  onPageShow(): void { 
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onPageShow'); 
    this.loginWithHuaweiID(); 
    this.popData = globalThis.data; 
  } 
 
  @Builder 
  tabBuilder(index: number, name: string) { 
    Column() { 
      Text(name) 
        .fontColor(this.currentIndex === index ? Color.Red : Color.Black) 
        .fontSize(16) 
        .fontWeight(this.currentIndex === index ? 500 : 400) 
        .lineHeight(22) 
        .margin({ top: 17, bottom: 7 }) 
      Divider() 
        .strokeWidth(2) 
        .color(Color.Gray) 
        .opacity(this.currentIndex === index ? 1 : 0) 
    }.width('100%') 
  } 
 
  build() { 
    Column() { 
      Tabs({ barPosition: BarPosition.Start, controller: this.controller }) { 
        TabContent() { 
          Column() { 
            Image(this.popData?.src) 
              .width('100%') 
              .height(300) 
              .borderRadius($r('app.float.image_border_radius')) 
              .margin({ bottom: $r('app.float.image_margin_bottom') }) 
 
            Text(this.popData?.title) 
              .fontSize(30) 
              .fontWeight(FontWeight.Bold) 
              .margin(20) 
 
            Text(this.popData?.introduction) 
              .fontSize(20) 
              .fontWeight(FontWeight.Bold) 
          } 
          .width('100%').height('100%') 
        }.tabBar(this.tabBuilder(0, '首页')) 
 
        TabContent() { 
          Column() { 
            Image(this.normalData?.src) 
              .width('100%') 
              .height(300) 
              .borderRadius($r('app.float.image_border_radius')) 
              .margin({ bottom: $r('app.float.image_margin_bottom') }) 
 
            Text(this.normalData?.title) 
              .fontSize(30) 
              .fontWeight(FontWeight.Bold) 
              .margin(20) 
 
            Text(this.normalData?.introduction) 
              .fontSize(20) 
              .fontWeight(FontWeight.Bold) 
 
          } 
          .width('100%') 
        }.tabBar(this.tabBuilder(1, '其它')) 
 
      } 
      .barMode(BarMode.Fixed) 
      .barWidth(360) 
      .barHeight(56) 
      .animationDuration(400) 
      .onChange((index: number) => { 
        this.currentIndex = index 
      }) 
      .width(360) 
      .height('100%') 
    }.width('100%') 
 
  } 
 
  /** 
   * 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 
 
      } 
    }); 
  } 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
分享
微博
QQ
微信
回复
2024-05-27 19:55:48


相关问题
HarmonyOS 服务卡片
787浏览 • 1回复 待解决
服务服务卡片的区别
6282浏览 • 1回复 待解决
HarmonyOS 服务服务卡片的区别
658浏览 • 1回复 待解决
HarmonyOS 服务卡片服务的区别
1229浏览 • 1回复 待解决
如何在服务更新卡片数据?
303浏览 • 0回复 待解决
HarmonyOS 服务卡片是否可以加桌
871浏览 • 1回复 待解决
应用市场推荐展示服务卡片异常
2593浏览 • 1回复 待解决
HarmonyOS 新建demo卡片服务不生效
957浏览 • 1回复 待解决
应用、服务卡片是什么关系
3028浏览 • 1回复 待解决
HarmonyOS 服务功能开发的demo实例
852浏览 • 1回复 待解决
HarmonyOS 服务相关实现
1016浏览 • 1回复 待解决
服务是否可以全程使用js实现
2418浏览 • 1回复 待解决