实现简易元服务卡片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 
        } 
      }); 
    }) 
  } 
}

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; 
  } 
}

主页渲染

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 
 
      } 
    }); 
  } 
}
分享
微博
QQ
微信
回复
2024-05-27 19:55:48
相关问题
服务服务卡片的区别
1330浏览 • 1回复 待解决
应用市场推荐展示服务卡片异常
783浏览 • 1回复 待解决
应用、服务卡片是什么关系
750浏览 • 1回复 待解决
服务是否可以全程使用js实现
705浏览 • 1回复 待解决
HarmonyOS服务与原子服务
11181浏览 • 2回复 待解决
服务顶部状态栏怎么设置标题
785浏览 • 3回复 待解决
UnionID在服务和应用间的关系
697浏览 • 1回复 待解决
鸿蒙手表支持服务卡片
7527浏览 • 2回复 待解决
服务卡片默认没有东西
5517浏览 • 1回复 待解决
服务包名命名需要使用什么格式
630浏览 • 1回复 待解决