当前位置:   article > 正文

《HarmonyOS实战-实时天气卡片》_weather-card

weather-card

【本文正在参与“有奖征文 | HarmonyOS征文大赛”活动】

活动链接:https://marketing.csdn.net/p/ad3879b53f4b8b31db27382b5fc65bbc

目录

一、创建卡片服务

二、卡片数据填充

三、更新数据


本文主要阐述的内容有:

1、原子化卡片的创建

2、卡片的数据填充

3、数据更新

首先,先看下效果图:

HarmonyOS实时天气卡片

一、创建卡片服务

创建卡片之前先新建一个项目,这个就不在累赘的介绍了。点这里

右键entry新建选择service widget,如下图:

 next,下图:

 Finish完成,生成的项目目录如下红色表示在原有基础上新增的文件

这样我们的卡片服务就创建完成了。

二、卡片数据填充

找到MainAbiliity,里面新增了一写方法,onCreateForm为卡片创建的方法,onUpdateForm为卡片更新的方法,onDeleteForm为卡片删除的方法。

我们的config.json中新增了卡片的标签具体含义请查看:卡片服务

在onCreateFrorm中需要根据intent传递的参数获取对应的布局,比如1*2、2*2的布局,并为其设置数据。

流程如下图:

MainAbility代码如下:

  1. public class MainAbility extends Ability {
  2. public static final int DEFAULT_DIMENSION_2X2 = 2;
  3. public static final int DEFAULT_DIMENSION_2X4 = 3;
  4. private static final int INVALID_FORM_ID = -1;
  5. private static final HiLogLabel TAG = new HiLogLabel(HiLog.DEBUG, 0x0, MainAbility.class.getName());
  6. private String topWidgetSlice;
  7. private long formId;
  8. private ProviderFormInfo formInfo;
  9. private DatabaseHelper helper = new DatabaseHelper(this);
  10. private OrmContext connect;
  11. private static final String EMPTY_STRING = "";
  12. private OrmContext weatherConnect;
  13. @Override
  14. public void onStart(Intent intent) {
  15. super.onStart(intent);
  16. super.setMainRoute(MainAbilitySlice.class.getName());
  17. connect = helper.getOrmContext("Database", "CardDatabase.db", CardDatabase.class);
  18. weatherConnect=helper.getOrmContext("weather","WeatherDatabase.db", WeatherDataBase.class);
  19. }
  20. @Override
  21. protected ProviderFormInfo onCreateForm(Intent intent) {
  22. if (intent == null) {
  23. return new ProviderFormInfo();
  24. }
  25. HiLog.info(TAG, "onCreateForm");
  26. // 获取卡片id
  27. formId = INVALID_FORM_ID;
  28. if (intent.hasParameter(AbilitySlice.PARAM_FORM_IDENTITY_KEY)) {
  29. formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, INVALID_FORM_ID);
  30. } else {
  31. return new ProviderFormInfo();
  32. }
  33. // 获取卡片名称
  34. String formName = EMPTY_STRING;
  35. if (intent.hasParameter(AbilitySlice.PARAM_FORM_NAME_KEY)) {
  36. formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);
  37. }
  38. // 获取卡片规格
  39. int dimension = DEFAULT_DIMENSION_2X2;
  40. if (intent.hasParameter(AbilitySlice.PARAM_FORM_DIMENSION_KEY)) {
  41. dimension = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, DEFAULT_DIMENSION_2X2);
  42. }
  43. int layoutId = ResourceTable.Layout_form_image_with_information_widget_2_2;
  44. HiLog.info(TAG, "dimension:" + dimension);
  45. if (dimension == DEFAULT_DIMENSION_2X4) {
  46. layoutId = ResourceTable.Layout_form_image_with_information_widget_2_4;
  47. }
  48. formInfo = new ProviderFormInfo(layoutId, this);
  49. // 存储卡片信息
  50. Card form = new Card(formId, formName, dimension);
  51. if (weatherConnect==null){
  52. weatherConnect=helper.getOrmContext("weather","WeatherDatabase.db", WeatherDataBase.class);
  53. }
  54. ComponentProvider componentProvider = ComponentProviderUtils.getComponentProvider(form, weatherConnect,getApplicationContext());
  55. //componentProvider.setIntentAgent()
  56. formInfo.mergeActions(componentProvider);
  57. if (connect == null) {
  58. connect =
  59. helper.getOrmContext("Database", "CardDatabase.db", CardDatabase.class);
  60. }
  61. try {
  62. DatabaseUtils.insertForm(form, connect);
  63. } catch (Exception e) {
  64. DatabaseUtils.deleteFormData(form.getFormId(), connect);
  65. }
  66. return formInfo;
  67. }
  68. @Override
  69. protected void onDeleteForm(long formId) {
  70. super.onDeleteForm(formId);
  71. // 删除数据库中的卡片信息
  72. DatabaseUtils.deleteFormData(formId, connect);
  73. }
  74. @Override
  75. protected void onUpdateForm(long formId) {
  76. super.onUpdateForm(formId);
  77. }
  78. }

因大部分卡片提供方都不是常驻服务,只有在需要使用时才会被拉起获取卡片信息。且卡片管理服务支持对卡片进行多实例管理,卡片ID对应实例ID,因此若卡片提供方支持对卡片数据进行配置,则需要提供方对卡片的业务数据按照卡片ID进行持久化管理,以便在后续获取、更新以及拉起时能获取到正确的卡片业务数据。

三、更新数据

在MainAbilitySlice中我选用了RadioContainer内含两个RadioButton实现单选,根据选择的城市获取对应城市的实时温度。获取到数据之后,根据数据库存储的卡片信息遍历更新所有卡片。

MainAbilitySlice代码如下:

  1. public class MainAbilitySlice extends AbilitySlice {
  2. private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00202, "MainAbilitySlice");
  3. private RadioContainer mRadioContainer;
  4. private OrmContext connect, weatherConnect;
  5. private RadioButton mXiAn, mShangHai;
  6. private Text mWeatherText;
  7. private DatabaseHelper helper = new DatabaseHelper(this);
  8. private NetWorkUtils netWorkUtils;
  9. @Override
  10. public void onStart(Intent intent) {
  11. super.onStart(intent);
  12. super.setUIContent(ResourceTable.Layout_ability_main);
  13. mRadioContainer = (RadioContainer) findComponentById(ResourceTable.Id_radio_container);
  14. mXiAn = (RadioButton) findComponentById(ResourceTable.Id_xi_an);
  15. mShangHai = (RadioButton) findComponentById(ResourceTable.Id_shang_hai);
  16. mWeatherText = (Text) findComponentById(ResourceTable.Id_weather_text);
  17. connect = helper.getOrmContext("Database", "CardDatabase.db", CardDatabase.class);
  18. weatherConnect = helper.getOrmContext("weather", "WeatherDatabase.db", WeatherDataBase.class);
  19. netWorkUtils = NetWorkUtils.getInstance(getContext());
  20. mRadioContainer.setMarkChangedListener(new RadioContainer.CheckedStateChangedListener() {
  21. @Override
  22. public void onCheckedChanged(RadioContainer radioContainer, int i) {
  23. HiLog.error(LABEL, "onCheckedChanged->I:%{public}s", i);
  24. switch (i) {
  25. case 0:
  26. PreferencesUtils.getInstance(getApplicationContext()).putInt("City", 0);
  27. getWeather(0);
  28. break;
  29. case 1:
  30. PreferencesUtils.getInstance(getApplicationContext()).putInt("City", 1);
  31. getWeather(1);
  32. break;
  33. }
  34. }
  35. });
  36. init();
  37. }
  38. private void upDataFrom() {
  39. OrmPredicates ormPredicates = new OrmPredicates(Card.class);
  40. List<Card> formList = connect.query(ormPredicates);
  41. // 更新时分秒
  42. if (formList.size() <= 0) {
  43. return;
  44. }
  45. for (Card form : formList) {
  46. // 遍历卡片列表更新卡片
  47. ComponentProvider componentProvider = ComponentProviderUtils.getComponentProvider(form, weatherConnect, getApplicationContext());
  48. try {
  49. Long updateFormId = form.getFormId();
  50. getAbility().updateForm(updateFormId, componentProvider);
  51. } catch (FormException e) {
  52. // 删除不存在的卡片
  53. DatabaseUtils.deleteFormData(form.getFormId(), connect);
  54. HiLog.error(LABEL, "onUpdateForm updateForm error");
  55. }
  56. }
  57. }
  58. public void init() {
  59. int city = PreferencesUtils.getInstance(getApplicationContext()).getInt("City", 0);
  60. if (city == 0) {
  61. mXiAn.setChecked(true);
  62. } else {
  63. mShangHai.setChecked(true);
  64. }
  65. }
  66. @Override
  67. public void onActive() {
  68. super.onActive();
  69. }
  70. @Override
  71. public void onForeground(Intent intent) {
  72. super.onForeground(intent);
  73. }
  74. private void getWeather(int city) {
  75. String cityName;
  76. String url;
  77. if (city == 0) {
  78. url = Contents.ADDRESS_URL + "西安";
  79. cityName = "西安";
  80. } else {
  81. cityName = "上海";
  82. url = Contents.ADDRESS_URL + "上海";
  83. }
  84. HiLog.error(LABEL, "startTimer->url:%{public}s", url);
  85. netWorkUtils.getWeather(url);
  86. netWorkUtils.setNetWorkListener(new NetWorkListener() {
  87. @Override
  88. public void onSuccess(String result) {
  89. Weather weather = new Weather(cityName, result);
  90. DatabaseUtils.insertWeather(weather, weatherConnect);
  91. upDataFrom();
  92. }
  93. @Override
  94. public void onFail(String msg) {
  95. }
  96. });
  97. }
  98. }

 也有很多是卡片是需要实时刷新或者隔几秒刷新一次,那么我们就是使用seviceAbility写定时任务,将获取数据部分放入的service中。

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号