基于ArkUI框架开发-ImageKnife渲染层重构

ImageKnife是一款图像加载缓存库,主要功能特性如下:

●支持内存缓存,使用LRUCache算法,对图片数据进行内存缓存。

●支持磁盘缓存,对于下载图片会保存一份至磁盘当中。

●支持进行图片变换:支持图像像素源图片变换效果。

●支持用户配置参数使用:(例如:配置是否开启一级内存缓存,配置磁盘缓存策略,配置仅使用缓存加载数据,配置图片变换效果,配置占位图,配置加载失败占位图等)。

背景说明

早期ImageKnife三方库在实现渲染部分的时候,使用的是image组件来展示图片的。由于image组件其实是一个完整的集加载解析和图片展示的组件,渲染的模式只能通过配置固定参数进行,面对复杂的需求场景,可能会出现扩展性不够的情况。

现在随着时间的推移渲染组件又多了一位重量级选手Canvas组件。可以通过2个组件渲染层的能力对比进行判断渲染层最终交由哪个组件展示。

组件选型,能力对比

首先我们来看看Image组件和Canvas组件对于渲染这一块的支持情况。

从上表我们可以看出:

Image组件虽然支持了PixelMap的绘制,但是基本没有绘制控制能力,而且扩展性能力也比较弱,并且渲染过程不可见,也无法对绘制内容进行更多操作。

而Canvas组件属于更加底层的渲染组件,可以完美地控制绘制内容,并且渲染过程可见,符合了开发者对于扩展性要求较高的定制场景。

重构前后能力对比

重构完成的内容

1. 使用canvas组件替代Image组件进行渲染展示图片。
2. 所有图像数据在渲染层都转换为PixelMap,方便统一管理和扩展。
3. 所有回调节点,统一抽象成接口,方便后续进行扩展,提高代码可维护性。
4. 所有的回调节点绘制的实现,都采用了责任链模式,提高了自定义绘制扩展能力。
5. 将部分通用方法封装成工厂方法,减少开发者代码量。
6. 通用方法从配置参数剥离,可采用链式调用方式使用这些方法。
7. 为了支持列表ImageKnifeOption参数使用@LinkObject修饰,同时ImageKnifeOption类型被@Observed修饰继承,不可被继承。

重构中比较重要的点

点1:回调接口抽象为IDrawLifeCycle接口

渲染绘制是主线程才能操作。因此我们可以对渲染顺序进行了梳理,大致流程:展示占位图->展示网络加载进度->展示缩略图->展示主图->展示重试图层->展示失败占位图

这里每个蓝色的小方格都代表着一个数据返回的回调接口,我们需要在这个回调接口,处理接下来内容渲染的展示操作。因为每个回调的流程是固定的,有点像生命周期的流程。所以我这边抽象成接口IDrawLifeCycle绘制生命周期进行表达。这其实也是为了后面扩展做了准备。

点2:绘制实现采用责任链模式

我们支持了用户配置自定义绘制和全局配置自定义绘制的能力。采用了责任链模式实现,用户参数设置->全局参数设置->自定义组件内部设置。这样设计的好处就是保留了用户扩展的能力,用户可以参与自定义绘制。

点3:提供了ImageKnifeDrawFactory工厂类

在开发者需要进行自定义绘制时,必须实现IDrawLifeCycle的6个接口。为了简化开发者操作,这里提供了ImageKnifeDrawFactory工厂类。

ImageKnifeDrawFactory里面封装了圆角、椭圆、百分比下载等实现,简化用户操作。当然更多的需求,可以参考该工厂类自行扩展实现。

这里我们提供简单的场景示例:

场景1:一句代码,加个圆角效果

代码如下:

 1 import {ImageKnifeComponent} from '@ohos/imageknife'2 import {ImageKnifeOption} from '@ohos/imageknife'3 import {ImageKnifeDrawFactory} from '@ohos/imageknife'4 @Entry5 @Component6 struct Index {7   @State imageKnifeOption1: ImageKnifeOption =8     { // 加载一张本地的png资源(必选)9       loadSrc: $r('app.media.pngSample'),
10       // 主图的展示模式是 缩放至适合组件大小,并且在组件底部绘制
11       mainScaleType: ScaleType.FIT_END,
12       // 占位图使用本地资源icon_loading(可选)
13       placeholderSrc: $r('app.media.icon_loading'),
14       // 失败占位图使用本地资源icon_failed(可选)
15       errorholderSrc: $r('app.media.icon_failed'),
16       // 绘制圆角30,边框5,边框"#ff00ff".用户自定义绘制(可选)
17       drawLifeCycle:ImageKnifeDrawFactory.createRoundLifeCycle(5,"#ff00ff",30)
18     };
19   build() {
20     Scroll() {
21       Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
22         ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 })
23           .width(300) // 自定义组件已支持设置通用属性和事件,这里宽高设置放在链式调用中完成
24           .height(300)
25       }
26     }
27     .width('100%')
28     .height('100%')
29   }
30 }

场景2:全局配置网络下载百分比效果展示

仅需一句代码所有网络图片加载都能新增网络下载百分比效果展示。代码如下:

 1 import AbilityStage from '@ohos.application.Ability'2 import { ImageKnife,ImageKnifeDrawFactory} from '@ohos/imageknife'3 4 export default class EntryAbility extends Ability {5     onCreate(want,launchParam) {6         globalThis.ImageKnife = ImageKnife.with(this.context);7         // 全局配置网络加载进度条       8         globalThis.ImageKnife.setDefaultLifeCycle(ImageKnifeDrawFactory.createProgressLifeCycle("#10a5ff", 0.5))9     }
10 }

这里大家可能会问,为什么会将这个IDrawLifeCycle放在EntryAbility里面实现?

这是因为网络下载百分比进度很多时候都是全局通用,如果有需要全局配置的自定义展示方案。推荐在EntryAbility里面,往ImageKnife的setDefaultLifeCycle函数中注入,即可将ImageKnifeComponent中的默认绘制方案替换。

在这里我们实现的效果如下图所示。

点4:通用属性方法和属性已经支持链式调用

比如下面的代码的宽高已经不用设置在ImageKnifeOption对象中了,直接在自定义组件下方链式调用设置即可。

 1 import {ImageKnifeComponent,ImageKnifeOption,ImageKnifeDrawFactory} from '@ohos/imageknife'2 @Entry3 @Component4 struct Index {5   @State imageKnifeOption1: ImageKnifeOption =6     { // 加载一张本地的png资源(必选)7       loadSrc: $r('app.media.pngSample'),8     };9   build() {
10     Scroll() {
11       Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
12         ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 })
13           .width(300) // 自定义组件已支持设置通用属性和事件,这里宽高设置放在链式调用中完成
14           .height(300)
15       }
16     }
17     .width('100%')
18     .height('100%')
19   }
20 }

点5:如何在列表使用

支持列表使用图片加载,只需要维护一个@State options:Array = []

对象即可

 1 import {ImageKnifeOption,ImageKnifeComponent} from '@ohos/imageknife'2 @Entry3 @Component4 struct BasicTestFeatureAbilityPage {5   urls=[6    "http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg",7    "http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg",8    "http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg",9    "http://g.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d5277fd5d0628535e5dd6f4a.jpg",
10    "http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg",
11  ]
12   @State options:Array<ImageKnifeOption> = []
13   aboutToAppear(){
14     this.options =  this.urls.map((url)=>{
15       return {
16         loadSrc:url
17       }
18     })
19     console.log('this.options length ='+this.options.length)
20   }
21   build() {
22     Stack({ alignContent: Alignment.TopStart }) {
23       Column() {
24         List({ space: 20, initialIndex: 0 }) {
25           ForEach(this.options, (item) => {
26             ListItem() {
27               ImageKnifeComponent({imageKnifeOption:item}).width(300).height(300)
28             }
29           }, item => item.loadSrc)
30         }
31         .listDirection(Axis.Vertical) // 排列方向
32         .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线
33         .edgeEffect(EdgeEffect.None) // 滑动到边缘无效果
34         .chainAnimation(false) // 联动特效关闭
35       }.width('100%')
36     }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 })
37   }
38 }

渲染层重构的总结

综上可知,此次重构渲染层,一共新增了6个基础能力,适配了IDE最新版特性自定义组件可链式调用通用属性和方法,并且采用适合的设计模式保留了自定义组件绘制部分的拓展能力。展示了部分常用场景下使用代码的方式,帮助开发者更快上手开发。

最后在OpenHarmony不断推陈出新之际,三方库ImageKnife也应该激流勇进,不断地提升组件的实用性和适用性,为开发者创造一个良好的开发体验。

我们将会持续更新ImageKnife三方库,后续会切换成GPU来渲染图片变换能力,不断进行性能优化,提升ImageKnife三方库。

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/770376.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux配置elasticsearch开机自启

脚本&#xff1a; vi /etc/init.d/elasticsearch脚本内容&#xff1a; ES_HOME的路径替换为自己的 #!/bin/bash #chkconfig: 2345 80 90 #description: elasticsearch export ES_HOME/usr/local/elasticsearch-8.8.0case "$1" in start)su es<<!cd $ES_HOME.…

el-card设置内边距

el-card设置内边距 :deep(.el-card .el-card__body) {padding: 5px; }

Android 15全面解读:性能飙升、隐私守护与智能生活新纪元

1. 更强大的性能 Android 15 带来了一系列性能方面的改进&#xff0c;以确保您的设备在运行应用程序时能够更加流畅。通过对系统进行优化&#xff0c;Android 15 在响应速度和性能方面都有了显著的提升。 这些优化包括&#xff1a; 新一代处理器支持&#xff1a; Android 15 …

java第一次作业(二)

先写思路&#xff0c;再写代码&#xff0c;思路清晰&#xff0c;才能写对代码 7-6 求12...n的和 思路&#xff1a; 运用expression的字符串输出 重点&#xff1a; expression输出 代码&#xff1a; import java.util.Scanner; public class Main {public static void main…

【代驾+顺风车+货运】全开源双端APP代驾+顺风车+货运代驾小程序源码

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 一、详细介绍 系统是基于Thinkphpuniapp开发的&#xff0c;全开源未加密&#xff0c;这套源码可以拿回去自己做二开 后台用户端司机端 功能详情介绍&#xff1a; 车主实名认证&#xff0c;驾驶证认证&#xff0c;车…

Android-System SELinux 权限

一、SELinux概念 安全增强型 Linux&#xff08;Security-Enhanced Linux&#xff09;简称 SELinux&#xff0c;它是 Linux 的一个安全子系统。SELinux 主要作用是最大限度地减小系统中服务进程可访问的资源&#xff08;最小权限原则&#xff09;。对资源的访问控制分为两类: DA…

MySQL8.0.27(社区版)安装教程和环境变量配置

MySQL8.0.27&#xff08;社区版&#xff09;软件百度网盘链接 链接&#xff1a;https://pan.baidu.com/s/1SRS0hAQQBENQFTfLeDjYzw?pwd1111 提取码&#xff1a;1111 下载完成后&#xff0c;解压MySQL社区版的ZIP压缩文件&#xff0c;通过命令的方式安装MySQL 1.安装MySQL8.0…

前端理论总结(css3)——css优化的方法

1&#xff1a;首推的是合并css文件&#xff0c;如果页面加载10个css文件&#xff0c;每个文件1k&#xff0c;那么也要比只加载一个100k的css文件慢 2&#xff1a;减少css嵌套&#xff0c;最好不要套三层以上 3&#xff1a;不要在ID选择器前面进行嵌套&#xff0c;ID本来就是唯一…

讨论物联网如何帮助监测和改善环境质量

物联网&#xff08;IoT&#xff09;作为一种革命性的技术&#xff0c;通过将各种设备和物品连接到互联网&#xff0c;使它们能够收集和交换数据&#xff0c;为监测和改善环境质量提供了强大的工具。以下是物联网在环境监测和改善方面的一些关键作用&#xff1a; 实时数据收集&…

Ubuntu20.04下VSCode配置PCL和OpenCV库-C++

Ubuntu20.04 VSCode Cpp PCL OpenCV 准备工作 代码编辑&#xff1a;VSCode 开发语言&#xff1a;C 编译工具&#xff1a;Cmake G 依赖需求&#xff1a;PCL / OpenCV 安装PCL库 sudo apt install libpcl-dev配置OpenCV库 安装依赖 sudo apt-get install build-essenti…

云运营安全概述,云运营安全的方案措施有哪些?

精品推荐-2024最新企业网络安全运营方案资料合集&#xff08;29份&#xff09;.zip 【推荐】最新网络安全运营方案和实践合集&#xff08;共80多份&#xff09;.zip 云运营安全是指在云环境中进行运营活动时&#xff0c;确保数据和系统的安全性。这涉及到多个方面&#xff0c…

程序汪若依微服务华为云Linux部署保姆教程

若依官方有3个版本&#xff0c;程序汪以前已经出了对应的安装部署视频教程 单应用版本 前后分离版本 微服务版本 本视频是若依微服务版本&#xff0c;如果基础的环境软件都不会安装建议看下程序汪的单应用和前后端分离版本教程&#xff0c; 欢迎点击进入 &#xff08;单应…

Flask蓝图找不到路由地址,访问404

Flask蓝图找不到路由地址&#xff0c;访问404 问题描述&#xff1a; 使用flask的蓝图对不同的模块设置路由地址时&#xff0c;接口是放到不同的python文件里的&#xff0c;当编写完一个蓝图的接口&#xff0c;进行访问请求的时候&#xff0c;出现了404无法访问的情况。 一、检查…

SQLite3 数据库的基本操作

SQLite3 是一种轻量级的关系型数据库管理系统&#xff0c;常用于移动设备和小型应用程序中。下面是一些使用 SQLite3 数据库的基本操作&#xff1a; 连接到数据库&#xff1a;使用命令 0 来连接到一个 SQLite3 数据库文件&#xff0c;如果该文件不存在则会创建一个新的数据库文…

【Python】python+requests+excel+pytest-实现接口自动化实例

目录 测试需求实现思路完整框架2.1 初始化数据 (test_data.xlsx)2.2 核心脚本 (api_client.py)2.3 测试用例 (test_interfaces.py)2.4 日志 (logging)2.5 pytest配置文件 (pytest.ini)2.6 测试报告 (pytest-html)2.7 入口函数 (run_tests.py)2.8 完整流程注意事项测试需求 简单…

Dalle-3、Sora、Stable Diffusion 3 掀起AIGC新浪潮

随着科技的飞速发展&#xff0c;我们迎来了视觉AIGC高光时刻&#xff0c;一个充满无限可能与机遇的新时代。在这个时代里&#xff0c;三大里程碑Dalle-3、Sora和Stable Diffusion 3以其炸裂式的技术发展&#xff0c;引领着AIGC领域的新浪潮。文章首先做相应简要介绍&#xff0c…

【LeetCode-300.最长递增子序列】

题目详情&#xff1a; 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的…

字符驱动程序-LCD驱动开发

一、驱动程序的框架 总共分为五步&#xff1a; 1、自己设定或者系统分配一个主设备号 2、创建一个file_operations结构体 这个结构体中有操作硬件的函数&#xff0c;比如drv_open、drv_read 3、写一个注册设备驱动函数 需要register_chrdev(major,name,结构体)&#xff0…

kingbaseESV8逻辑备份还原

数据库逻辑备份还原 sys_dump -h127.0.0.1 -Usystem -f/home/kingbase/db01.dmp db01 ksql -h127.0.0.1 test system -c drop database db01 ksql -h127.0.0.1 test system -c create database db01 ksql -h127.0.0.1 -Usystem -ddb01 -f/home/kingbase/db01.dmp --------…

各种需要使用的方法-->vue/微信小程序/layui

各种需要使用的方法-->vue/微信小程序/layui 1、vue里样式不起作用的方法&#xff0c;可以通过deep穿透的方式2、 js获取本周、上周、本月、上月日期3、ArrayBuffer Blob 格式转换ArrayBuffer与Blob的区别ArrayBuffer转BlobBlob转ArrayBuffer需要借助fileReader对象 4、使用…