请求服务器图片资源刷新卡片?

功能场景描述及使用场景

场景:卡片中经常需要更新数据,如天气中更新温度等,都需要请求服务器资源更新目前的温度,气候等,接受服务器的资源如图片等进行重新渲染。

阅读 516
1 个回答

使用的核心API

downloadFile(context: BaseContext, config: DownloadConfig): Promise

updateForm(formId: string, formBindingData: formBindingData.FormBindingData): Promise

postCardAction(component: Object, action: Object): void

核心代码解释

卡片的渲染页面中增加一个按钮来触发刷新操作,postCardAction为组件的能力请到指南中卡片部分参考,其余两个接口可在API文档查阅,通过postCardAction发送一个messgae,该接口会触发卡片ability的onFormEvent生命周期,下载和刷新操作在该生命周期进行。以下按流程分享源码:

核心代码如下:

//pages/WidgetCard.ets
let storage = new LocalStorage();
@Entry(storage)
@Component
struct WidgetCard {
  @LocalStorageProp('text') text: string = '加载中...';
  @LocalStorageProp('loaded') loaded: boolean = false;
  @LocalStorageProp('imgName') imgName: string = 'name';

  build() {
    Column() {
      Text(this.text)
        .fontSize('12vp')
        .textAlign(TextAlign.Center)
        .width('100%')
        .height('30%')
        .margin({bottom:20})
      Row() {
        if (this.loaded) {
          Image('memory://' + this.imgName)
            .width('30%')
            .height('30%')
            .margin('5%')
        } else {
          Image($r("app.media.startIcon"))
            .width('20%')
            .height('20%')
            .margin('5%')
        }
      }.alignItems(VerticalAlign.Center)
      .justifyContent(FlexAlign.Center)
      Button('刷新')
        .height('15%')
        .onClick(() => {
          //发送message,触发卡片的onFormEvent生命周期
          postCardAction(this, {
            'action': 'message',
            'params': {
              'info': 'refreshImage'
            }
          });
        })
    }
    .width('100%').height('100%')
    .alignItems(HorizontalAlign.Center)
    .padding('5%')
  }
}
//entryformability/EntryFormAbility
import formBindingData from '@ohos.app.form.formBindingData';
import formProvider from '@ohos.app.form.formProvider';
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
import request from '@ohos.request';
import fs from '@ohos.file.fs';
import Base from '@ohos.base';
import fileFs from '@ohos.file.fs';
import Want from '@ohos.app.ability.Want';
import formInfo from '@ohos.app.form.formInfo';

export default class EntryFormAbility extends FormExtensionAbility {
  onAddForm(want: Want) {
    // 假设在当前卡片应用的tmp目录下有一个本地图片:head.PNG
    let tempDir = this.context.getApplicationContext().tempDir;
    // 打开本地图片并获取其打开后的fd
    let file: fileFs.File;
    let imgBear: Record<string, number>;
    try {
      file = fs.openSync(tempDir + '/' + 'icon.png');
      imgBear = {
        'imgBear': file.fd
      }
    } catch (e) {
      console.error(`openSync failed: ${JSON.stringify(e as Base.BusinessError)}`);
    }
    class FormDataClass{
      text: string = 'Image: Bear'
      imgName: string = 'imgBear'
      loaded: boolean = true
      formImages: Record<string, number> = imgBear
    }
    let formData = new FormDataClass();

    // 将fd封装在formData中并返回至卡片页面
    return formBindingData.createFormBindingData(formData);
  }

  onCastToNormalForm(formId: string) {
    // Called when the form provider is notified that a temporary form is successfully
    // converted to a normal form.
  }

  onUpdateForm(formId: string) {
    // Called to notify the form provider to update a specified form.
  }

  onChangeFormVisibility(newStatus: Record<string, number>) {
    // Called when the form provider receives form events from the system.
  }

  onFormEvent(formId: string, message: string) {
    let param: Record<string, string> = {
      'text': '刷新中...'
    };
    let formInfo: formBindingData.FormBindingData =formBindingData.createFormBindingData(param);
    formProvider.updateForm(formId, formInfo);
    // 注意:FormExtensionAbility在触发生命周期回调时被拉起,仅能在后台存在5秒
    // 建议下载能快速下载完成的小文件,如在5秒内未下载完成,则此次网络图片无法刷新至卡片页面上
    let netFile = 'https://piccpndali.v.myalicdn.com/pic/cctv2_2.png'; // 需要在此处使用真实的网络图片下载链接
    let tempDir = this.context.getApplicationContext().tempDir;
    let fileName = 'file' + Date.now();
    let tmpFile = tempDir + '/' + fileName+'.png';
    console.info('ArkTSCard download complete:');
    request.downloadFile(this.context, {
      url: netFile, filePath: tmpFile, enableMetered: true, enableRoaming: true
    }).then((task) => {
      task.on('complete', () => {
        console.info('ArkTSCard download complete:' + tmpFile);
        let file: fileFs.File;
        let imgBear: Record<string, number>;
        try {
          file = fs.openSync(tmpFile);
          imgBear = {
            'imgBear': file.fd
          }
          console.info('ArkTSCard download file.fd:' + file.fd);
        } catch (e) {
          console.error(`openSync failed: ${JSON.stringify(e as Base.BusinessError)}`);
        }
        class FormDataClass{
          text: string = 'Image:' + fileName
          imgName: string = 'imgBear'
          loaded: boolean = true
          formImages: Record<string, number> = imgBear
        }
        let formData = new FormDataClass();
        console.info('FormAbility updateForm datainfo:{'+formData.loaded+' '+ formData.text + ' ' +formData.formImages +' ' +formData.imgName +'}.');
        let formInfo = formBindingData.createFormBindingData(formData);
        formProvider.updateForm(formId, formInfo).then(() => {
          console.info('FormAbility updateForm success.');
        }).catch((error: Base.BusinessError) => {
          console.error('FormAbility updateForm failed: ' + JSON.stringify(error));
        });
      })
      task.on('fail', (err: number) => {
        console.info('ArkTSCard download task failed. Cause:' + err);
        let param: Record<string, string> = {
          'text': '刷新失败'
        };
        let formInfo: formBindingData.FormBindingData = formBindingData.createFormBindingData(param);
        formProvider.updateForm(formId, formInfo);
      });
    }).catch((err: Base.BusinessError) => {
      console.error('Failed to request the download. Cause: ' + JSON.stringify(err));
    });
  }

  onRemoveForm(formId: string) {
    // Called to notify the form provider that a specified form has been destroyed.
  }

  onAcquireFormState(want: Want) {
    // Called to return a {@link FormState} object.
    return formInfo.FormState.READY;
  }
};

总结:

  • 主要难点在于:资源文件的下载和卡片数据的封装。

实现效果

注明适配的版本信息

  • IDE:DevEco Studio 4.0.3.600
  • SDK:HarmoneyOS 4.0.10.11
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进