arkts-ui-widget-image-update.md 6.7 KB
Newer Older
Z
zhongjianfei 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# 刷新本地图片和网络图片


在卡片上通常需要展示本地图片或从网络上下载的图片,获取本地图片和网络图片需要通过FormExtensionAbility来实现,如下示例代码介绍了如何在卡片上显示本地图片和网络图片。


1. 下载网络图片需要使用到网络能力,需要申请ohos.permission.INTERNET权限,配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md)

2. 在EntryFormAbility中的onAddForm生命周期回调中实现本地文件的刷新
   
   ```ts
   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';
X
xuzhihao 已提交
17 18 19
   import Want from '@ohos.app.ability.Want';
   import Base from '@ohos.base';
   import fileFs from '@ohos.file.fs';
Z
zhongjianfei 已提交
20 21 22 23
   
   export default class EntryFormAbility extends FormExtensionAbility {
     ...
     // 在添加卡片时,打开一个本地图片并将图片内容传递给卡片页面显示
X
xuzhihao 已提交
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
    onAddForm(want: Want) {
      // 假设在当前卡片应用的tmp目录下有一个本地图片:head.PNG
      let tempDir = this.context.getApplicationContext().tempDir;
      // 打开本地图片并获取其打开后的fd
      let file: fileFs.File;
      let formData = new Map<string, Object>();
      formData.set('text', 'Image: Bear');
      formData.set('imgName', 'imgBear');
      formData.set('loaded', true);
      try {
        file = fs.openSync(tempDir + '/' + 'head.PNG');
        let imgBear: Record<string, number> = {
          'imgBear': file.fd
        }
        formData.set('formImages', imgBear);
      } catch (e) {
        console.error(`openSync failed: ${JSON.stringify(e as Base.BusinessError)}`);
      }
      // 将fd封装在formData中并返回至卡片页面
      return formBindingData.createFormBindingData(formData);
    }
Z
zhongjianfei 已提交
45 46 47 48 49 50 51
   
     ...
   }
   ```

3. 在EntryFormAbility中的onFormEvent生命周期回调中实现网络文件的刷新
   
X
xuzhihao 已提交
52 53 54 55 56 57 58 59
  ```ts
  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';
Z
zhongjianfei 已提交
60
   
X
xuzhihao 已提交
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
  export default class EntryFormAbility extends FormExtensionAbility {
    // 在卡片页面触发message事件时,下载一个网络图片,并将网络图片内容传递给卡片页面显示
    onFormEvent(formId: string, message: string) {
      let formInfo = formBindingData.createFormBindingData({
        'text': '刷新中...'
      })
      formProvider.updateForm(formId, formInfo)
      // 注意:FormExtensionAbility在触发生命周期回调时被拉起,仅能在后台存在5秒
      // 建议下载能快速下载完成的小文件,如在5秒内未下载完成,则此次网络图片无法刷新至卡片页面上
      let netFile = 'https://xxxx/xxxx.png'; // 需要在此处使用真实的网络图片下载链接
      let tempDir = this.context.getApplicationContext().tempDir;
      let fileName = 'file' + Date.now();
      let tmpFile = tempDir + '/' + fileName;
      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 formData = new Map<string, Object>();
          try {
            file = fs.openSync(tmpFile);
            formData.set('text', 'Image: Bear' + fileName);
            formData.set('imgName', 'imgBear' + fileName);
            formData.set('loaded', true);
            let imgBear: Record<string, number> = {
              'imgBear': file.fd
            };
            formData.set('formImages', imgBear);
          } catch (e) {
            console.error(`openSync failed: ${JSON.stringify(e as Base.BusinessError)}`);
          }
          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 formInfo = formBindingData.createFormBindingData({
            'text': '刷新失败'
          })
          formProvider.updateForm(formId, formInfo)
        });
      }).catch((err: Base.BusinessError) => {
        console.error('Failed to request the download. Cause: ' + JSON.stringify(err));
      });
    }
  };
  ```
Z
zhongjianfei 已提交
113 114

4. 在卡片页面通过Image组件展示EntryFormAbility传递过来的卡片内容。
Z
zhongjianfei 已提交
115

Z
zhongjianfei 已提交
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
   ```ts
   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('15%')
   
         Row() {
           if (this.loaded) {
             Image('memory://' + this.imgName)
               .width('50%')
               .height('50%')
               .margin('5%')
           } else {
             Image('common/start.PNG')
               .width('50%')
               .height('50%')
               .margin('5%')
           }
         }.alignItems(VerticalAlign.Center)
         .justifyContent(FlexAlign.Center)
   
         Button('刷新')
           .height('15%')
           .onClick(() => {
             postCardAction(this, {
               'action': 'message',
               'params': {
                 'info': 'refreshImage'
               }
             });
           })
       }
       .width('100%').height('100%')
       .alignItems(HorizontalAlign.Center)
       .padding('5%')
     }
   }
   ```

166
> **说明:**
Z
zhongjianfei 已提交
167 168 169
> - Image组件通过入参(**memory://fileName**)中的**memory://**标识来进行远端内存图片显示,其中**fileName**需要和EntryFormAbility传递对象(**'formImages': {key: fd})**中的**key**相对应。
> 
> - Image组件通过传入的参数是否有变化来决定是否刷新图片,因此EntryFormAbility每次传递过来的**imgName**都需要不同,连续传递两个相同的**imgName**时,图片不会刷新。