一个简单的日程提醒鸿蒙卡片开发!
效果图展示:
项目介绍
项目为一个简单的在日历上添加日程的应用,我们可以将当日的日程生成卡片到桌面,便于直观查看当日要做事项。
此项目旨在帮助开发者快速掌握如下技术点:
Js 卡片的布局、初始化、更新、事件处理。
Java 卡片的布局、初始化、更新、事件处理。
代码结构解读
本教程我们只是对核心代码进行讲解,您可以在最后的参考中下载完整代码,首先来介绍下整个工程的代码结构:
项目介绍
项目为一个简单的在日历上添加日程的应用,我们可以将当日的日程生成卡片到桌面,便于直观查看当日要做事项。
此项目旨在帮助开发者快速掌握如下技术点:
Js 卡片的布局、初始化、更新、事件处理。
Java 卡片的布局、初始化、更新、事件处理。
代码结构解读
本教程我们只是对核心代码进行讲解,您可以在最后的参考中下载完整代码,首先来介绍下整个工程的代码结构:
选择模板→下一步:
输入卡片名称、选择卡片类型(单选)、卡片大小(多选),点击 finish 即可。
②默认卡片页面
js-widget-pages-index-index.json 默认卡片页面的数据:
data:默认数据。
actions:routerEvent 为 router 事件,用于应用跳转
js-widget-pages-index-index.css 卡片的样式:同 js 页面样式开发。
js-widget-pages-index-index.html 卡片的页面:
同 js 页面开发,不过要使用卡片支持组件。
click 事件关联 json 文件中的 actions 下的应用跳转事件,此处关联的是点击跳转应用的页面,页面代码:on:click=“routerEvent”(不可以传参)。
③初始化卡片页面
在 WidgetImpl.java 文件中 bindFromData 方法中,进行页面展示数据的初始化:
public ProviderFormInfo bindFormData() {
ZSONObject zsonObject = new ZSONObject();
ProviderFormInfo providerFormInfo = new ProviderFormInfo();
String scheduleData = StorageUtil.initPreferences(context).getSchedule();
if(!"".equals(scheduleData)) {
ZSONArray array = ZSONArray.stringToZSONArray(scheduleData);
if(array.size()>0) {
ZSONArray result = StorageUtil.getSwiperCardSchedule(array);
CardConstant.SWIPER_CARD_LENGTH = result.size();
zsonObject.put("schedule", result);
zsonObject.put("count", array.size());
}
}
zsonObject.put("index", 0);
providerFormInfo.setJsBindingData(new FormBindingData(zsonObject));
return providerFormInfo;
}
④更新卡片页面
config.json 配置定时或周期性刷新:定时或周期性刷新均会调用 WidgetImpl.java 文件中 updateFormData 方法,因本卡片未实现此方法,所以不支持此功能。
在下面 js2x2 与 2x4 卡片中介绍周期性刷新;在下面 java2x2 与 2x4 卡片中介绍定时刷新。
添加当日日程导致数据变化 ,对日程进行更新介绍:数据变化时,触发数据监听方法,代码在 StorageUtil.java 工具类,这里开启 CardServiceAbility 服务。
代码如下:
private class PreferencesChangeCounter implements Preferences.PreferencesObserver {
private Context mContext;
public PreferencesChangeCounter(Context context){
this.mContext = context;
}
@Override
public void onChange(Preferences preferences, String key) {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.example.myohoscard")
.withAbilityName("com.example.myohoscard.CardServiceAbility")
.build();
intent.setOperation(operation);
mContext.startAbility(intent,0);
}
}
CardServiceAbility 服务的 onCommand 方法中进行卡片更新,其更新代码如下:
public void swiperData(ZSONArray array){
ZSONArray result = StorageUtil.getSwiperCardSchedule(array);
CardConstant.SWIPER_CARD_LENGTH = result.size();
ZSONObject zsonObject = new ZSONObject();
zsonObject.put("schedule", result);
zsonObject.put("count", array.size());
FormBindingData formBindingData = new FormBindingData(zsonObject);
FormControllerManager formControllerManager = FormControllerManager.getInstance(this);
for(long id:formControllerManager.getAllFormIdFromSharePreference(CardConstant.SWIPER_CARD_FORMS_NAME)) {
try {
updateForm(id, formBindingData);
} catch (FormException e) {
e.printStackTrace();
}
}
}
⑤卡片的轮播
CardServiceAbility 服务的 onCommand 方法中调用卡片轮播,其代码如下:
public void swiperLoop(){
ZSONObject data = new ZSONObject();
if(CardConstant.SWIPER_CARD_THREAD != null) {
CardConstant.SWIPER_CARD_THREAD.interrupt();
}
CardConstant.SWIPER_CARD_THREAD = new Thread(() -> {
while (true) {
try {
if(Thread.currentThread().isInterrupted()){
//处理中断逻辑
break;
}
Thread.sleep(2000);
data.put("index", index % CardConstant.SWIPER_CARD_LENGTH);
FormBindingData bindingData = new FormBindingData(data);
FormControllerManager formControllerManager = FormControllerManager.getInstance(this);
for(long formid:formControllerManager.getAllFormIdFromSharePreference(CardConstant.SWIPER_CARD_FORMS_NAME)) {
updateForm(formid, bindingData);
}
index++;
if(index == CardConstant.SWIPER_CARD_LENGTH){
index = 0;
}
} catch (Exception e) {
break;
}
}
});
CardConstant.SWIPER_CARD_THREAD.start();
}
缺点:此处退出应用程序时,service 不再运行导致轮播线程结束,轮播失效。
JS 2x2 与 2x4 卡片
①新建卡片页面
同 js 轮播卡片的新建卡片页面操作步骤,勾选 2x2、2x4 卡片。
②默认卡片页面
js-card2x4-pages-index-index.json 默认卡片页面的数据:
data:默认数据。
actions:routerEvent 为 router 事件,用于应用跳转;sendMessageEvent1 与 sendMessageEvent2 为 message 事件,用于卡片开发人员自定义点击事件。
js-card2x4-pages-index-index.css 卡片的样式:同 js 页面样式开发。
js-card2x4-pages-index-index.html 卡片的页面:
同 js 页面开发,不过要使用卡片支持组件。
2x2 或 2x4 的卡片公用一个 html 页面,利用 dim2X4 变量 true 或者 false,来展示 2x2 或 2x4 的布局。
click 事件关联 json 文件中的 actions 下的操作事件,此处关联的是点击跳转应用的页面。
代码:on:click="routerEvent"或on:click=“sendMessageEvent1”、on:click=“sendMessageEvent2”(不支持参数传递)。
③初始化卡片页面
在 Jscard2x4Impl.java 文件中 bindFromData 方法中,进行页面展示数据的初始化:
public ProviderFormInfo bindFormData() {
HiLog.info(TAG, "bind form data");
ZSONObject zsonObject = new ZSONObject();
ProviderFormInfo providerFormInfo = new ProviderFormInfo();
if (dimension == DIMENSION_1X2) {
zsonObject.put("mini", true);
}
if (dimension == DIMENSION_2X4) {
zsonObject.put("dim2X4", true);
}
String scheduleData = StorageUtil.initPreferences(context).getSchedule();
if(!"".equals(scheduleData)) {
ZSONArray array = ZSONArray.stringToZSONArray(scheduleData);
if(array.size()>0) {
zsonObject = getObject(array,zsonObject);
}
}
providerFormInfo.setJsBindingData(new FormBindingData(zsonObject));
return providerFormInfo;
}
/**
- 当天日程存在时,卡片数据展示
- @param array
- @param zsonObject
- @return
*/
public static ZSONObject getObject(ZSONArray array,ZSONObject zsonObject){
ZSONArray result = StorageUtil.getCurrentCardSchedule(array);
ZSONObject schedule_current = ZSONObject.stringToZSON(ZSONObject.toZSONString(result.get(0)));
if(schedule_current != null){
zsonObject.put("schedule_current", schedule_current);
}
ZSONObject schedule_1 = ZSONObject.stringToZSON(ZSONObject.toZSONString(result.get(1)));
ZSONObject schedule_2 = ZSONObject.stringToZSON(ZSONObject.toZSONString(result.get(2)));
if(schedule_1 != null){
zsonObject.put("noSchedule", false);
zsonObject.put("hasSchedule1", true);
zsonObject.put("schedule_1", schedule_1);
}
if(schedule_2 != null){
zsonObject.put("hasSchedule2", true);
zsonObject.put("schedule_2", schedule_2);
}
zsonObject.put("count", array.size());
return zsonObject;
}
④更新卡片页面
config.json 配置周期性刷新:config.json 中 jscard2X4 卡片配置"updateEnabled": true 与"updateDuration": 1。
其中 updateDuration 配置参数为 30 分钟倍数,此处 1 即 30 分钟主动刷新一次卡片。
周期性刷新调用 Jscard2x4Impl.java 文件中 updateFormData 方法,代码如下:
public void updateFormData(long formId, Object... vars) {
HiLog.info(TAG, "update form data timing, default 30 minutes");
String scheduleData = StorageUtil.initPreferences(context).getSchedule();
if(!"".equals(scheduleData)) {
ZSONArray array = ZSONArray.stringToZSONArray(scheduleData);
if(array.size()>0) {
FormBindingData formBindingData = new FormBindingData(getObject(array,new ZSONObject()));//上一步中有getObject()方法代码
try {
((MainAbility)context).updateForm(formId, formBindingData);
} catch (FormException e) {
e.printStackTrace();
}
}
}
}
添加当日日程导致数据变化 ,对日程进行更新介绍:数据变化时,触发数据监听方法,代码在 StorageUtil.java 工具类中,这里开启 CardServiceAbility 服务。
CardServiceAbility 服务的 onCommand 方法中调用 cardData 进行卡片更新,其更新代码如下:
FormBindingData formBindingData = new FormBindingData(Jscard2X4Impl.getObject(array,new ZSONObject()));//上一步中有getObject()方法代码
FormControllerManager formControllerManager = FormControllerManager.getInstance(this);
try {
for(long id:formControllerManager.getAllFormIdFromSharePreference(CardConstant.JS_CARD_FORMS_NAME)) {
updateForm(id, formBindingData);
}
} catch (FormException e) {
e.printStackTrace();
}
⑤router 事件与 message 事件处理
router 事件:在跳转后的页面,接收参数并进行处理,这里请看 MainAbility.java 下的 onStart 方法。
代码如下:
String strParams = intent.getStringParam("params");
if(strParams != null) {
ZSONObject data = ZSONObject.stringToZSON(strParams);
String message = data.getString("message");
//此处可以根据message判断点击了某个按钮,从而做相应的处理
new ToastDialog(this).setText(message)
.setAlignment(LayoutAlignment.CENTER).show();
}
message 事件:在 Jscard2x4Impl.java 文件中 onTriggerFormEvent 方法中进行处理。
代码如下:
public void onTriggerFormEvent(long formId, String message) {
HiLog.info(TAG, "handle card click event.");
ZSONObject data = ZSONObject.stringToZSON(message);
String msg = data.getString("msg");
Intent intent = new Intent();
intent.setParam("params","{\"message\":\""+msg+"\"}");
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.example.myohoscard")
.withAbilityName("com.example.myohoscard.MainAbility")
.build();
intent.setOperation(operation);
((MainAbility)context).startAbility(intent);
}
Java 2x2 与 2x4 卡片
①新建卡片页面
同 js 轮播卡片的新建卡片页面操作步骤,勾选 type—java、Dimensions—2x2 与 2x4 卡片。
②默认卡片页面
resources-base-layout 下:
java2x2 卡片布局页面—form_grid_pattern_javacard2x4_2_2.xml
java2x2 卡片布局页面—form_grid_pattern_javacard2x4_2_4.xml
其开发模式同应用 java 模式页面布局开发
③初始化卡片页面
在 Javacard2x4Impl.java 文件中 bindFromData 方法中,进行页面展示数据的初始化:
public ProviderFormInfo bindFormData() {
HiLog.info(TAG, "bind form data when create form");
ProviderFormInfo providerFormInfo = new ProviderFormInfo(RESOURCE_ID_MAP.get(dimension), context);
String scheduleData = StorageUtil.initPreferences(context).getSchedule();
if(!"".equals(scheduleData)) {
ZSONArray array = ZSONArray.stringToZSONArray(scheduleData);
if(array.size()>0) {
// ComponentProvider表示Java卡片
ComponentProvider componentProvider = new ComponentProvider();
providerFormInfo.mergeActions(getFormDataCreate(array,context,dimension,componentProvider));
}
}
return providerFormInfo;
}
public static ComponentProvider getFormDataCreate(ZSONArray array,Context context,int dimension,ComponentProvider componentProvider){
componentProvider.setVisibility(ResourceTable.Id_count, Text.VISIBLE);
componentProvider.setText(ResourceTable.Id_count, array.size()+"");
ZSONArray result = StorageUtil.getCurrentCardSchedule(array);
ZSONObject schedule_current = ZSONObject.stringToZSON(ZSONObject.toZSONString(result.get(0)));
if(schedule_current != null){
componentProvider.setText(ResourceTable.Id_time, schedule_current.getString("startCardShow")+"-"+schedule_current.getString("endCardShow"));
componentProvider.setText(ResourceTable.Id_schedule, schedule_current.getString("title"));
}
if (dimension == DEFAULT_DIMENSION_2X2) {
componentProvider.setIntentAgent(ResourceTable.Id_layout, getStartAbilityIntentAgent(context));
}
if (dimension == DIMENSION_2X4) {
componentProvider.setVisibility(ResourceTable.Id_noschedule, Text.HIDE);
ZSONObject schedule_1 = ZSONObject.stringToZSON(ZSONObject.toZSONString(result.get(1)));
if(schedule_1 != null){
// componentProvider.setText(ResourceTable.Id_time1, schedule_1.getString("startCardShow")+"-"+schedule_1.getString("endCardShow"));
componentProvider.setText(ResourceTable.Id_schedule1, schedule_1.getString("title"));
}
ZSONObject schedule_2 = null;
if(result.get(2) != null){
schedule_2 = ZSONObject.stringToZSON(ZSONObject.toZSONString(result.get(2)));
}
if(schedule_2 != null){
componentProvider.setVisibility(ResourceTable.Id_line, Text.VISIBLE);
// componentProvider.setText(ResourceTable.Id_time2, schedule_2.getString("startCardShow")+"-"+schedule_2.getString("endCardShow"));
componentProvider.setText(ResourceTable.Id_schedule2, schedule_2.getString("title"));
}
}
if (dimension == DIMENSION_2X4) {
componentProvider.setIntentAgent(ResourceTable.Id_more, getStartAbilityIntentAgent(context));
}
return componentProvider;
}
④更新卡片页面
config.json 配置定时刷新:config.json 中 jscard2X4 卡片配置"scheduledUpdateTime":“10:42"与"updateDuration”:0。
其中 scheduledUpdateTime 配置参数为 24 小时制,可以在当天指定时间对卡片进行刷新。
定时刷新调用 Javacard2x4Impl.java 文件中 updateFormData 方法,代码如下:
public void updateFormData(long formId, Object... vars) {
HiLog.info(TAG, "update form data timing, default 30 minutes");
String scheduleData = StorageUtil.initPreferences(context).getSchedule();
if(!"".equals(scheduleData)) {
ZSONArray array = ZSONArray.stringToZSONArray(scheduleData);
if(array.size()>0) {
ComponentProvider componentProvider =
new ComponentProvider(RESOURCE_ID_MAP.get(dimension), context);
try {
((MainAbility)context).updateForm(formId, getFormDataUpdate(array,context,dimension,componentProvider));
} catch (FormException e) {
HiLog.error(TAG, e.toString());
}
}
}
}
public static ComponentProvider getFormDataUpdate(ZSONArray array,Context context,int dimension,ComponentProvider componentProvider){
componentProvider.setVisibility(ResourceTable.Id_count, Text.VISIBLE);
componentProvider.setText(ResourceTable.Id_count, array.size()+"");
ZSONArray result = StorageUtil.getCurrentCardSchedule(array);
ZSONObject schedule_current = ZSONObject.stringToZSON(ZSONObject.toZSONString(result.get(0)));
if(schedule_current != null){
componentProvider.setText(ResourceTable.Id_time, schedule_current.getString("startCardShow")+"-"+schedule_current.getString("endCardShow"));
componentProvider.setText(ResourceTable.Id_schedule, schedule_current.getString("title"));
}
if (dimension == DIMENSION_2X4) {
componentProvider.setVisibility(ResourceTable.Id_noschedule, Text.HIDE);
ZSONObject schedule_1 = ZSONObject.stringToZSON(ZSONObject.toZSONString(result.get(1)));
if(schedule_1 != null){
// componentProvider.setText(ResourceTable.Id_time1, schedule_1.getString("startCardShow")+"-"+schedule_1.getString("endCardShow"));
componentProvider.setText(ResourceTable.Id_schedule1, schedule_1.getString("title"));
}
ZSONObject schedule_2 = null;
if(result.get(2) != null){
schedule_2 = ZSONObject.stringToZSON(ZSONObject.toZSONString(result.get(2)));
}
if(schedule_2 != null){
componentProvider.setVisibility(ResourceTable.Id_line, Text.VISIBLE);
// componentProvider.setText(ResourceTable.Id_time2, schedule_2.getString("startCardShow")+"-"+schedule_2.getString("endCardShow"));
componentProvider.setText(ResourceTable.Id_schedule2, schedule_2.getString("title"));
}
}
return componentProvider;
}
添加当日日程导致数据变化 ,对日程进行更新介绍:数据变化时,触发数据监听方法,代码在 StorageUtil.java 工具类中,这里开启 CardServiceAbility 服务。
CardServiceAbility 服务的 onCommand 方法中调用 cardData 进行卡片更新,其更新代码如下:
try {
for(long id:formControllerManager.getAllFormIdFromSharePreference(CardConstant.JAVA_CARD_FORMS_NAME)) {
int dimension = formControllerManager.getDimension(id+"");
ComponentProvider componentProvider =
new ComponentProvider(Javacard2x4Impl.RESOURCE_ID_MAP.get(dimension), this);
updateForm(id, Javacard2x4Impl.getFormDataUpdate(array,this,dimension,componentProvider));//上一步中有此方法代码
}
} catch (FormException e) {
e.printStackTrace();
}
⑤卡片点击事件添加
给控件点击点击事件,其代码为:
componentProvider.setIntentAgent(ResourceTable.Id_more, getStartAbilityIntentAgent(context))
其中 getStartAbilityIntentAgent 方法代码如下:
private static IntentAgent getStartAbilityIntentAgent(Context context) {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.example.myohoscard")
.withAbilityName("com.example.myohoscard.MainAbility")
.build();
intent.setOperation(operation);
List
intentList.add(intent);
List
flags.add(IntentAgentConstant.Flags.UPDATE_PRESENT_FLAG);
IntentAgentInfo paramsInfo =
new IntentAgentInfo(200, IntentAgentConstant.OperationType.START_ABILITY, flags, intentList, null);
return IntentAgentHelper.getIntentAgent(context, paramsInfo);
}
- 分享
- 举报
-
浏览量:4291次2021-08-26 14:50:36
-
浏览量:4775次2021-09-28 13:45:07
-
浏览量:6524次2022-05-30 15:26:15
-
浏览量:1533次2023-04-13 10:45:45
-
浏览量:4679次2021-06-28 14:52:06
-
浏览量:4177次2021-07-19 18:05:51
-
浏览量:4451次2021-08-16 11:02:13
-
浏览量:2237次2022-03-22 09:00:12
-
浏览量:3013次2019-10-28 14:15:46
-
浏览量:1225次2023-03-20 15:51:34
-
浏览量:3657次2021-07-14 14:13:47
-
浏览量:592次2023-10-24 17:47:15
-
浏览量:4599次2021-08-17 16:28:57
-
浏览量:694次2023-04-20 08:54:12
-
浏览量:5348次2021-07-14 14:09:54
-
浏览量:985次2023-04-21 08:46:56
-
浏览量:766次2023-04-21 08:55:25
-
浏览量:993次2023-04-23 09:44:59
-
浏览量:769次2023-04-23 09:46:58
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
奋斗的疯子
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
这是手机平台上的么?