日历应用日程卡片 - 不同规格卡片的集成实现

日历应用支持用户在桌面新建不同规格的日历日程卡片来查看相关日程信息。

主要问题:

1、如何查询到自己想要的数据,在卡片中进行渲染展示?

2、如何监听数据变化并实时同步传入卡片框架,直至卡片数据刷新?

3、如何实现一个abality管理若干不同规格卡片?

HarmonyOS
2024-06-13 10:41:10
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
HearMe_cn

实现方案: 数据代理 + 卡片底座;

参考:

https://gitee.com/openharmony/docs/blob/d5e2c5d6deaaeee2ba6a04413107fec24be3c610/zh-cn/application-dev/application-models/arkts-ui-widget-update-by-proxy.md

日历卡片相关配置

moduule.json5:

"extensionAbilities": [ 
{ 
  "name": "AllFormAbility", 
  "srcEntry": "./ets/abilities/form/AllFormAbility.ets", 
  "label": "$string:form_DayFormAbility_label", 
  "description": "$string:day_form_description", 
  "type": "form", 
  "metadata": [ 
    { 
      "name": "ohos.extension.form", 
      "resource": "$profile:form_config_all" 
    } 
  ] 
} 
]

form_config_all.json:

{ 
  "forms" : [ 
    2x2 .. 2x4 
        ... 
      { 
          "name" : "AgendaCard4x4", 
          "description" : "$string:AgendaCard_Proximity_Agenda", 
          "src" : "./ets/widget/form/AgendaCardView4x4.ets", 
          "uiSyntax" : "arkts", 
          "window" : { 
              "designWidth" : 720, 
              "autoDesignWidth" : true 
          }, 
          "colorMode" : "auto", 
          "isDefault" : true, 
          "updateEnabled" : true, 
          "scheduledUpdateTime" : "00:00", 
          "updateDuration" : 1, 
          "formVisibleNotify" : true, 
          "defaultDimension" : "4*4", 
          "supportDimensions" : [ 
              "4*4" 
          ], 
          "dataProxyEnabled" : true 
      } 
  ] 
}

// 一个ability控制若干规格卡片 --问题3解决方案

AllFormAbility:

class AllFormAbility extends FormExtensionAbility { 
onAddForm(want: Want) { 
  Log.info(TAG, `onAddForm, want: ${JSON.stringify(want)}`); 
  return this.getFormProcessByWant(want).onAddForm(this.context, want); // -- 根据名称来匹配创建不同规格卡片 
} 
​ 
onCastToNormalForm(formId: string): FormExtensionCallback { 
  Log.info(TAG, `onCastToNormalForm, formId: ${formId}`); 
  return this.getFormProcess(formId).onCastToNormalForm(this.context, formId); 
} 
​ 
onUpdateForm(formId: string): FormExtensionCallback | undefined { 
  return; 
} 
private getFormProcessByWant(want: Want): FormExtensionCallback { 
let wantParam = want.parameters; 
let formId: string = ''; 
let formName: string = ''; 
let formSize: number = 0; 
if (wantParam !== null && wantParam !== undefined) { 
  formId = wantParam[formInfo.FormParam.IDENTITY_KEY] as string; 
  formName = wantParam[formInfo.FormParam.NAME_KEY] as string; 
  formSize = wantParam[formInfo.FormParam.DIMENSION_KEY] as number; 
} 
... 
} ... 
}

// 抽象出接口 不同规格卡片单独实现

FormExtensionCallback :

export default interface FormExtensionCallback { 
onAddForm(context: Context, want: Want): formBindingData.FormBindingData; 
​ 
onCastToNormalForm(context: Context, formId: string); 
​ 
onUpdateForm(context: Context, formId: string); 
​ 
onChangeFormVisibility(context: Context, newStatus: Record<string, number>); 
​ 
onFormEvent(context: Context, formId: string, message: string); 
​ 
onRemoveForm(context: Context, formId: string); 
​ 
onAcquireFormState(context: Context, want: Want): formInfo.FormState; 
}

// 4*4卡片规格例:AgendaCardController4x4:

export default class AgendaCardController4x4 implements FormExtensionCallback { 
static FORM_NAME: string = 'AgendaCard4x4';   -- 名称匹配配置文件中的卡片名称 
​ 
onAddForm(context: Context, want: Want) { 
  Log.info(TAG, `onAddForm, want: ${JSON.stringify(want)}`); 
  const dsOptions: dataShare.DataShareHelperOptions = { 
    isProxy: true 
  }; 
  let temp = want.parameters; 
  let subscriberId: string = ''; 
  if (temp) { 
    subscriberId = temp['ohos.extra.param.key.form_identity'] as string 
  } 
  const formData: Record<string, Object> = {}; 
  const template: dataShare.Template = { 
    predicates: { 
      'agendaObjList': QUERY_VALID_AGENDA_SQL 
    }, 
    scheduler: REFRESH_CARD_SQL 
  }; 
  const proxies: Array<formBindingData.ProxyData> = [ 
    { 
      'key': PROXY_URI_CALENDAR, 
      'subscriberId': subscriberId 
    } 
  ]; 
​ 
  dataShare.createDataShareHelper(context, PROXY_URI, dsOptions).then((dataShareHelper) => { 
    Log.info(TAG, 'DataShare createDataShareHelper, subscriberId ' + subscriberId); 
    dataShareHelper.addTemplate(PROXY_URI_CALENDAR, subscriberId, template); 
  }) 
​ 
  let formBinding: formBindingData.FormBindingData = formBindingData.createFormBindingData(formData); 
  formBinding['proxies'] = proxies; 
  ReportUtil.reportStatisticEvent(statisticEvents.useCardCreateDay44); 
  return formBinding; 
} 
... 
} 
     
问题1得到解决: 
// sql返回需要展示的数据 
const QUERY_VALID_AGENDA_SQL: string = `SELECT Instances._id AS id,event_id,begin,end,startDay,endDay,startMinute` + 
`,endMinute,title,allDay,eventLocation,calendar_id,calendar_color,service_verified,service_type` + 
`,service_cp_bz_uri FROM Instances INNER JOIN Events ON (Instances.event_id=Events._id) INNER JOIN Calendars ` + 
`ON (Events.calendar_id = Calendars._id) WHERE visible = 1 ` + 
`AND (begin < strftime('%s', datetime('now', 'localtime', 'start of day'), 'UTC') * 1000 + ` + 
`${DateUtil.DAY_PER_WEEK * DateUtil.ONE_DAY_TIMESTAMP} ` + 
`AND end > strftime('%s', datetime('now', 'localtime'), 'UTC') * 1000) ` + 
`AND important_event_type = 0 ` + 
`ORDER BY startDay ASC limit 20`; 
​ 
​ 
问题2得到解决: 
// 卡片刷新时间计算 sql:会议日程提前 10 分钟,日程过期,每天 0 点 
const REFRESH_CARD_SQL: string = `SELECT remindTimer(MIN(min_time) * 1000) FROM (` + 
`SELECT MIN(end / 1000) AS min_time FROM Instances INNER JOIN Events ` + 
`ON (Instances.event_id=Events._id) WHERE (end / 1000) > ABS(strftime('%s', datetime('now', 'localtime'), 'UTC')) ` + 
`UNION ` + 
`SELECT MIN((begin - 10 * ${DateUtil.ONE_MINUTE_TIMESTAMP}) / 1000) AS min_time FROM Instances INNER JOIN Events ` + 
`ON (Instances.event_id=Events._id) WHERE (service_type = 'Meeting') ` + 
`AND ((begin - 10 * ${DateUtil.ONE_MINUTE_TIMESTAMP}) / 1000) > ABS(strftime('%s', datetime('now', 'localtime'), 'UTC')) ` + 
`UNION ` + 
`SELECT ABS(strftime('%s', datetime('now', 'localtime', 'start of day'), 'UTC')) + ` + 
`${DateUtil.ONE_DAY_TIMESTAMP} / 1000 as min_time)`; 
AgendaCardView4x4 表单ui:

最终获取数据并解析渲染展示;

展示效果:

分享
微博
QQ
微信
回复
2024-06-13 20:48:15
相关问题
JS如何添加日历日程提醒?
6602浏览 • 1回复 待解决
实现简易元服务卡片Demo
450浏览 • 1回复 待解决
如何进行不同规格AES加解密
196浏览 • 1回复 待解决
卡片服务功能支持应用内部使用吗?
5774浏览 • 1回复 待解决
应用市场推荐展示元服务卡片异常
573浏览 • 1回复 待解决
鸿蒙卡片如何去掉应用桌面图标
9695浏览 • 3回复 已解决
卡片开发中如何实现数据持久化
650浏览 • 1回复 待解决
如何通过卡片点击实现业务登录场景
519浏览 • 1回复 待解决
应用、元服务和卡片是什么关系
587浏览 • 1回复 待解决
卡片提供方在主进程中主动更新卡片
377浏览 • 1回复 待解决
api6如何实现点击桌面卡片弹出提示
1621浏览 • 1回复 待解决