目录

一、开发环境搭建:

创建一个空的工程文件:

二、使用JS开发卡片:

 标签”forms”中卡片的配置:

 卡片的定点/定时刷新:


 一、开发环境搭建:

安装和配置DevEco Studio,详情请参考我的入门篇博客:下载和安装软件

这次实战使用的是DevEco Studio版本为DevEco Studio 2.1 Beta4,使用的SDK版本为API Version 5

创建一个空的工程文件:

        创建一个HarmonyOS的工程,然后选择模板Empty Ability(JS)或Empty Ability(Java),点击按钮Next,进入到工程配置界面:(这里,使用的是SDK版本为API Version 5)

        其中,工程类型有两种:一种是”Service”,也就是原子化服务;另一种是”Application”,也就是传统的应用。此外,还可以选择”是否在服务中心进行展示”。我们将工程类型指定为”原子化服务”,并且选择”在服务中心进行展示”。按照上图进行配置之后,点击按钮Finish以创建一个工程。

连接远程设备: 

 开启远程设备:


二、使用JS开发卡片:

        打开DevEco Studio,创建一个HarmonyOS的工程,然后选择模板Empty Ability(JS),点击按钮Next,进入到工程配置界面:

        其中,将工程类型指定为传统应用,并且不选择”在服务中心进行展示”。按照上图进行配置之后,点击按钮Finish以创建一个工程。

        如何在一个传统应用的工程中创建卡片呢?

        在目录entry上点击右键,在弹出的菜单中选择New,然后在弹出的子菜单中点击Service Widget:

这里的Service Widget指的就是卡片。

        在模板选择界面,选择基本的模板Grid Pattern,点击按钮Next,进入到卡片配置界面: 

        首先配置卡片的名称和描述;然后配置卡片关联的Page Ability;然后配置卡片的编程语言类型是JS;接下来配置卡片的JS组件名称;最后配置卡片支持的规格,其中,2*2的小尺寸是必须要支持的,我们再勾选一个1*2的微尺寸。点击按钮Finish以创建一个卡片。

再创建2*4的中尺寸和4*4的大尺寸:

DevEco Studio会自动帮我们生成了一些目录和文件:

  •  widget01和widget02是创建卡片时配置的JS组件名称
  • index.hml中定义了卡片中包含哪些UI组件;index.css中定义了卡片中的UI组件样式
  • index.json中定义了卡片中动态绑定的数据,此外,还可以定义click触发事件

        widget01和widget01是创建卡片时配置的卡片名称;在MainAbility中添加了卡片的生命周期回调方法,如:onCreateForm()、onUpdateForm()、onTriggerFormEvent()、等。 还添加了FormControllerManager、FormController、以及两个以Impl结尾的实现类。

        在config.json中自动添加了很多配置:

{
  "app": {
    "bundleName": "com.example.demo",
    "vendor": "example",
    "version": {
      "code": 1000000,
      "name": "1.0.0"
    }
  },
  "deviceConfig": {},
  "module": {
    "package": "com.example.demo",
    "name": ".MyApplication",
    "mainAbility": "com.example.demo.MainAbility",
    "deviceType": [
      "phone"
    ],
    "distro": {
      "deliveryWithInstall": true,
      "moduleName": "entry",
      "moduleType": "entry",
      "installationFree": true
    },
    "abilities": [
      {
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ],
        "name": "com.example.demo.MainAbility",
        "icon": "$media:icon",
        "description": "$string:mainability_description",
        "label": "$string:entry_MainAbility",
        "type": "page",
        "launchType": "standard",
        "formsEnabled": true,
        "forms": [
          {
            "jsComponentName": "widget01",
            "isDefault": true,
            "scheduledUpdateTime": "10:30",
            "defaultDimension": "2*2",
            "name": "widget01",
            "description": "This is a service widget",
            "colorMode": "auto",
            "type": "JS",
            "supportDimensions": [
              "1*2",
              "2*2"
            ],
            "updateEnabled": true,
            "updateDuration": 1
          },
          {
            "jsComponentName": "widget02",
            "isDefault": false,
            "scheduledUpdateTime": "10:30",
            "defaultDimension": "2*2",
            "name": "widget02",
            "description": "This is a service widget",
            "colorMode": "auto",
            "type": "JS",
            "supportDimensions": [
              "2*2",
              "2*4",
              "4*4"
            ],
            "updateEnabled": true,
            "updateDuration": 1
          }
        ]
      }
    ],
    "js": [
      {
        "pages": [
          "pages/index/index"
        ],
        "name": "default",
        "window": {
          "designWidth": 720,
          "autoDesignWidth": true
        }
      },
      {
        "pages": [
          "pages/index/index"
        ],
        "name": "widget01",
        "window": {
          "designWidth": 720,
          "autoDesignWidth": true
        },
        "type": "form"
      },
      {
        "pages": [
          "pages/index/index"
        ],
        "name": "widget02",
        "window": {
          "designWidth": 720,
          "autoDesignWidth": true
        },
        "type": "form"
      }
    ]
  }
}

        MainAbility添加了标签”forms”,这里的form就是卡片的意思,和Service Widget是一回事儿。”forms”是一个数组,包含两个元素,分别表示我们创建的两个卡片。顺便提一下,在前面我们有讲到:“可以在config.json中为每个Page Ability配置0~16个卡片”,也就是说,数组”forms”中最多可以包含16个元素。上图的最下方还添加了一个标签”js”,”js”也是一个数组,包含三个元素,其中后两个元素就是两个卡片对应的js组件,”name”分别是”widget01”和”widget02”,这两个值就对应着上面的标签”forms”中”jsComponentName”的两个值。也就是说,上面的标签”forms”中卡片的js组件,是在下面的标签”js”中定义的。

 标签”forms”中卡片的配置:

  • “isDefault”表示该卡片是否为默认的上滑卡片,也就是用手指按下应用图标的同时往上滑时弹出的卡片。
  • “scheduledUpdateTime”表示卡片定点刷新的时刻,采用24小时制,精确到分钟。
  • “defaultDimension“表示卡片的默认尺寸规格,取值必须在下面的“supportDimensions“所配置的列表中。
  • “colorMode“表示卡片的主题样式,默认值是”auto”,表示自适应,还可以取值为”dark”或”light”,分别表示深色主题和浅色主题。
  • “supportDimensions“表示卡片支持的尺寸规格,也就是我们在创建卡片时配置的尺寸规格。
  • “updateEnabled”表示卡片是否支持定时刷新或定点刷新,优先选择定时刷新。
  • “updateDuration“表示卡片定时刷新的周期。当取值为0时,表示该参数不生效;当取值为正整数N时,表示刷新周期为30*N分钟。

         由于该工程的类型是”原子化服务”,所以在桌面上并没有相应的图标。由于在创建工程时选择了”在服务中心进行展示”,因此,打开服务中心,就看到了相应的入口卡片:

上下滑动所有卡片,总共有5个:

  • widget01的卡片有两个,尺寸分别是1*2和2*2
  • widget02的卡片有三个,尺寸分别是2*2、2*4和4*4

        widget1的2*2的卡片被设为了上滑卡片,这是因为:在config.json中,将”isDefault”设为了”true”,并且将”defaultDimension”设为了” 2*2”:

"forms": [
          {
            "jsComponentName": "widget",
            "isDefault": true,
            "scheduledUpdateTime": "10:30",
            "defaultDimension": "2*2",
            "name": "widget",
            "description": "This is a service widget",
            "colorMode": "auto",
            "type": "JS",
            "supportDimensions": [
              "2*2"
            ],
            "updateEnabled": true,
            "updateDuration": 1
          },

        在桌面上长按应用的图标然后显示所有卡片的时候,MainAbility中卡片的生命周期方法onCreateForm()会被自动回调,方法onCreateForm()的实现:

    @Override
    protected ProviderFormInfo onCreateForm(Intent intent) {
        HiLog.info(TAG, "onCreateForm");
        long formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, INVALID_FORM_ID);
        String formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);
        int dimension = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, DEFAULT_DIMENSION_2X2);
        HiLog.info(TAG, "onCreateForm: formId=" + formId + ",formName=" + formName);
        FormControllerManager formControllerManager = FormControllerManager.getInstance(this);
        FormController formController = formControllerManager.getController(formId);
        formController = (formController == null) ? formControllerManager.createFormController(formId,
                formName, dimension) : formController;
        if (formController == null) {
            HiLog.error(TAG, "Get null controller. formId: " + formId + ", formName: " + formName);
            return null;
        }
        return formController.bindFormData();
    }

因为总共有5个卡片,所以方法onCreateForm()会被回调5次!!!

方法bindFormData():

@Override
    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);
        }
        providerFormInfo.setJsBindingData(new FormBindingData(zsonObject));
        return providerFormInfo;
    }

         程序根据卡片的尺寸,分别设置了两个变量”mini”和”dim2X4”的值,这两个变量是子目录widget01中的index.json中的两个变量。

{
  "data": {
    "mini": false,
    "dim2X4": false,
    "miniTitle": "Title",
    "title": "Title",
    "content": "Introduction",
    "detailTitle": "Title"
  }
}

        这里顺便说一下,在index.hml中,很多变量都使用两个花括号括了起来,这些变量的值是在程序的运行过程中动态确定的,这种技术称之为动态绑定。这些变量的初始值在index.json中的标签”data”中进行了定义。所以,在方法bindFormData()中,根据卡片的尺寸修改了两个动态绑定的变量的值。

 所有卡片的标题都被修改了(尺寸最小的卡片除外,因为他本来就不显示标题)。

 卡片的定点/定时刷新:

        打开config.json,先将widget02对应的标签”updateDuration”修改为0,以关闭定时刷新。

         对于标签“scheduledUpdateTime”设定的时刻,当到达之后,MainAbility中卡片的回调方法onUpdateForm()就会被自动调用:

        将要刷新的数据存放在一个ZSONObject实例中,然后,将其封装在一个FormBindingData的实例bindingData中,最后,调用MainAbility的方法updateForm(),并将bindingData作为第二个实参。

@Override
    public void updateFormData(long formId, Object... vars) {
        HiLog.info(TAG, "update form data timing, default 30 minutes");

        //刷新数据:
        ZSONObject data = new ZSONObject();
        data.put("title","更新操作");
        FormBindingData bindingData = new FormBindingData(data);
        try {
            ((MainAbility)context).updateForm(formId, bindingData);
        } catch (FormException e) {
            HiLog.error(TAG,e.toString());
        }
    }

 打开config.json,将标签“scheduledUpdateTime”的值修改为当前时刻的一分钟之后:

        运行工程,将widget02对应的卡片都添加到桌面上,当到达设定的定点时刻之后,卡片标题都刷新了:


【本文正在参与"有奖征文|HarmoneyOS征文大赛"活动】

传送口:https://marketing.csdn.net/p/ad3879b53f4b8b31db27382b5fc65bbc

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐