简介
服务卡片框架提供了FormExtensionAbility基类,通过继承此基类,实现调用服务卡片的生命周期函数,来实现具体卡片的功能。
开放了属性动画和显式动画,增加了自定义绘制的能力,可以使用Canvas画布组件自定义绘制和构建更多样的显示和交互效果。允许卡片中运行逻辑代码,业务逻辑可以在卡片内部自闭环。
不支持功能
- 不支持导入共享包。
- 不支持native语言,仅支持声明式范式的部分组件、事件、动效、数据管理、状态管理和API能力。
- 暂不支持极速预览。
- 暂不支持setTimeOut。
工程目录
新建流程(静态服务窗口)
1.选择静态服务窗口
2.选择项目模板
3.设置卡片名称、简介、模块大小等
4.根据选择的样板,自动添加卡片项目相关文件。
5.默认的预览视图
6.需要修改卡片配置,可以去form_config.json中设置
卡片事件(静态卡片)
案例代码
实现效果
项目架构
DateUtil.ets
export class DateUtil {
/**
* 返回时间
* @param date
* @returns 14:53样式的时间
*/
static ToTime(date: Date): string {
if (date == null) {
return "";
}
return `${DateUtil.PrefixInteger(date.getHours(), 2)}:${DateUtil.PrefixInteger(date.getMinutes(), 2)}`
}
/**
* 返回月份和周几
* @param date
* @returns 返回6月17日(周一)的样式
*/
static ToMonthDay(date: Date): string {
if (date == null) {
return "";
}
const weekDays = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]
return `${date.getMonth() + 1}月${date.getDate()}日(${weekDays[date.getDay()]})`
}
static PrefixInteger(num: number, length: number) {
return (Array(length).join('0') + num).slice(-length);
}
}
Ticket_WidgetCard.ets
import { TicketShow_ViewModel } from '../viewmodel/TicketShow_ViewModel'
import { TicketShow_View } from '../view/TicketShow_view'
@Entry
@Component
struct Ticket_WidgetCard {
/*
* action的类型
*/
readonly ACTION_TYPE: string = 'router';
/*
* action为router / call 类型时跳转的UIAbility名
*/
readonly ABILITY_NAME: string = 'EntryAbility';
/*
* The message.
*/
readonly MESSAGE: string = 'add detail';
/*
* The height percentage setting.
*/
readonly FULL_HEIGHT_PERCENT: string = '100%';
@State ticketShowVM: TicketShow_ViewModel = new TicketShow_ViewModel(
"G6357",
new Date(2024, 5, 17, 14, 33),
new Date(2024, 5, 17, 20, 0),
"凤凰古城",
"广州",
"二等车 06车 05F号");
build() {
FormLink({
action: this.ACTION_TYPE,
abilityName: this.ABILITY_NAME,
params: {
message: this.MESSAGE
}
}) {
Stack({ alignContent: Alignment.BottomEnd }) {
TicketShow_View({
viewModel: this.ticketShowVM
})
.margin(10)
Image($r('app.media.railway'))
.height(80)
.opacity(0.3)
.margin({ bottom: 10, right: 20 })
}
.height(this.FULL_HEIGHT_PERCENT)
.width("100%")
.backgroundColor('#00000000')
.linearGradient({
angle: 90,
colors: [["#1f82ca", 0.0], ["#24c8df", 1.0]]
})
}
}
}
TicketShow_view.ets
import { DateUtil } from '../../common/DateUtil';
import { TicketShow_ViewModel, TicketStage } from '../viewmodel/TicketShow_ViewModel'
@Component
export struct TicketShow_View {
@ObjectLink viewModel: TicketShow_ViewModel
/**
* 字体颜色
*/
readonly TEXT_COLOR: ResourceColor = Color.White;
build() {
Column() {
Row() {
Column() {
Text(DateUtil.ToTime(this.viewModel.BoardingTime))
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor(this.TEXT_COLOR)
Text(this.viewModel.BoardingAddress)
.fontSize(14)
.margin({ top: 5 })
.fontColor(this.TEXT_COLOR)
}
.height("100%")
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
.justifyContent(FlexAlign.Start)
Column() {
Text(this.viewModel.Id)
.fontSize(14)
.fontColor(this.TEXT_COLOR)
Path()
.commands('M0 0 L300 0 L270 -10 L270 0 Z')
.margin({ top: 4 })
.strokeWidth(1)
.fill(this.TEXT_COLOR)
.stroke(this.TEXT_COLOR)
Text(DateUtil.ToMonthDay(this.viewModel.BoardingTime))
.fontSize(12)
.margin({ top: 5 })
.fontColor(this.TEXT_COLOR)
}
.height("100%")
.layoutWeight(2)
.justifyContent(FlexAlign.Start)
Column() {
Text(DateUtil.ToTime(this.viewModel.ArrivalTime))
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor(this.TEXT_COLOR)
Text(this.viewModel.ArrivalAddress)
.fontSize(14)
.margin({ top: 5 })
.fontColor(this.TEXT_COLOR)
}
.height("100%")
.layoutWeight(1)
.alignItems(HorizontalAlign.End)
.justifyContent(FlexAlign.Start)
}
.width("100%")
.layoutWeight(2)
.margin({ top: 20 })
Column() {
Text(this.viewModel.Position)
.fontSize(12)
.fontColor(this.TEXT_COLOR)
Row() {
Text("状态:")
.fontSize(12)
.fontColor(this.TEXT_COLOR)
Text(TicketStage[this.viewModel.Stage])
.fontSize(12)
.fontColor(this.TEXT_COLOR)
}
.margin({ top: 5 })
}
.width("100%")
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
.justifyContent(FlexAlign.Start)
}
.width("100%")
.height("100%")
}
}
TicketShow_ViewModel.ets
/**
* 展示组件的ViewModel
*/
@Observed
export class TicketShow_ViewModel {
/**
* 火车编号
*/
public Id: string = '';
/**
* 开始时间
*/
public BoardingTime: Date = new Date();
/**
* 到达时间
*/
public ArrivalTime: Date = new Date();
/**
* 起始站
*/
public BoardingAddress: string = "";
/**
* 终点站
*/
public ArrivalAddress: string = "";
/**
* 座位
*/
public Position: string = "";
/**
* 状态
*/
public Stage: TicketStage = TicketStage.待车
constructor(
id: string,
boardingTime: Date,
arrivalTime: Date,
boardingAddress: string,
arrivalAddress: string,
position: string) {
this.Id = id;
this.BoardingTime = boardingTime;
this.BoardingAddress = boardingAddress;
this.ArrivalTime = arrivalTime;
this.ArrivalAddress = arrivalAddress;
this.Position = position;
}
public isDraft(): boolean {
return true;
}
}
/**
* 车票状态
*/
export enum TicketStage {
待车,
正在检票,
停止检票
}
注意
里面的图片是需要自己去下载的,暂未实现数据和程序联动