0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

OpenAtom OpenHarmony 来源:未知 2023-04-05 00:25 次阅读

点击蓝字 ╳ 关注我们


开源项目 OpenHarmony
是每个人的 OpenHarmony

周黎生

OpenHarmony知识体系工作组

ImageKnife是一款图像加载缓存库,主要功能特性如下:
支持内存缓存,使用LRUCache算法,对图片数据进行内存缓存。
支持磁盘缓存,对于下载图片会保存一份至磁盘当中。
支持进行图片变换:支持图像像素源图片变换效果。
支持用户配置参数使用:(例如:配置是否开启一级内存缓存,配置磁盘缓存策略,配置仅使用缓存加载数据,配置图片变换效果,配置占位图,配置加载失败占位图等)。
更多细节请访问源码仓库地址:
https://gitee.com/openharmony-tpc/ImageKnife

背景说明

早期ImageKnife三方库在实现渲染部分的时候,使用的是image组件来展示图片的。由于image组件其实是一个完整的集加载解析和图片展示的组件,渲染的模式只能通过配置固定参数进行,面对复杂的需求场景,可能会出现扩展性不够的情况。
现在随着时间的推移渲染组件又多了一位重量级选手Canvas组件。可以通过2个组件渲染层的能力对比进行判断渲染层最终交由哪个组件展示。
如果想了解更多ImageKnife的背景知识,可以点击链接查看之前的文章介绍:
旧版本ImageKnife加载流程介绍
https://developer.huawei.com/consumer/cn/forum/topic/0203864555891240375?fid=0101587866109860105

组件选型,能力对比

首先我们来看看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:一句代码,加个圆角效果
代码如下:
import {ImageKnifeComponent} from '@ohos/imageknife'
import {ImageKnifeOption} from '@ohos/imageknife'
import {ImageKnifeDrawFactory} from '@ohos/imageknife'
@Entry
@Component
struct Index {
@State imageKnifeOption1: ImageKnifeOption =
{ // 加载一张本地的png资源(必选)
loadSrc: $r('app.media.pngSample'),
// 主图的展示模式是 缩放至适合组件大小,并且在组件底部绘制
mainScaleType: ScaleType.FIT_END,
// 占位图使用本地资源icon_loading(可选)
placeholderSrc: $r('app.media.icon_loading'),
// 失败占位图使用本地资源icon_failed(可选)
errorholderSrc: $r('app.media.icon_failed'),
// 绘制圆角30,边框5,边框"#ff00ff".用户自定义绘制(可选)
drawLifeCycle:ImageKnifeDrawFactory.createRoundLifeCycle(5,"#ff00ff",30)
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 })
.width(300) // 自定义组件已支持设置通用属性和事件,这里宽高设置放在链式调用中完成
.height(300)
}
}
.width('100%')
.height('100%')
}
}

场景2:全局配置网络下载百分比效果展示
仅需一句代码所有网络图片加载都能新增网络下载百分比效果展示。代码如下:
import AbilityStage from '@ohos.application.Ability'
import { ImageKnife,ImageKnifeDrawFactory} from '@ohos/imageknife'


export default class EntryAbility extends Ability {
onCreate(want,launchParam) {
globalThis.ImageKnife = ImageKnife.with(this.context);
// 全局配置网络加载进度条
globalThis.ImageKnife.setDefaultLifeCycle(ImageKnifeDrawFactory.createProgressLifeCycle("#10a5ff", 0.5))
}
}
这里大家可能会问,为什么会将这个IDrawLifeCycle放在EntryAbility里面实现?
这是因为网络下载百分比进度很多时候都是全局通用,如果有需要全局配置的自定义展示方案。推荐在EntryAbility里面,往ImageKnife的setDefaultLifeCycle函数中注入,即可将ImageKnifeComponent中的默认绘制方案替换。
在这里我们实现的效果如下图所示。


点4:通用属性方法和属性已经支持链式调用
比如下面的代码的宽高已经不用设置在ImageKnifeOption对象中了,直接在自定义组件下方链式调用设置即可。
import {ImageKnifeComponent,ImageKnifeOption,ImageKnifeDrawFactory} from '@ohos/imageknife'
@Entry
@Component
struct Index {
@State imageKnifeOption1: ImageKnifeOption =
{ // 加载一张本地的png资源(必选)
loadSrc: $r('app.media.pngSample'),
};
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 })
.width(300) // 自定义组件已支持设置通用属性和事件,这里宽高设置放在链式调用中完成
.height(300)
}
}
.width('100%')
.height('100%')
}
}

点5:如何在列表使用
支持列表使用图片加载,只需要维护一个@State options:Array = []
对象即可
import {ImageKnifeOption,ImageKnifeComponent} from '@ohos/imageknife'
@Entry
@Component
struct BasicTestFeatureAbilityPage {
urls=[
"http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg",
"http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg",
"http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg",
"http://g.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d5277fd5d0628535e5dd6f4a.jpg",
"http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg",
]
@State options:Array = []
aboutToAppear(){
this.options = this.urls.map((url)=>{
return {
loadSrc:url
}
})
console.log('this.options length ='+this.options.length)
}
build() {
Stack({ alignContent: Alignment.TopStart }) {
Column() {
List({ space: 20, initialIndex: 0 }) {
ForEach(this.options, (item) => {
ListItem() {
ImageKnifeComponent({imageKnifeOption:item}).width(300).height(300)
}
}, item => item.loadSrc)
}
.listDirection(Axis.Vertical) // 排列方向
.divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线
.edgeEffect(EdgeEffect.None) // 滑动到边缘无效果
.chainAnimation(false) // 联动特效关闭
}.width('100%')
}.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 })
}
}

渲染层重构的总结

综上可知,此次重构渲染层,一共新增了6个基础能力,适配了IDE最新版特性自定义组件可链式调用通用属性和方法,并且采用适合的设计模式保留了自定义组件绘制部分的拓展能力。展示了部分常用场景下使用代码的方式,帮助开发者更快上手开发。
最后在OpenHarmony不断推陈出新之际,三方库ImageKnife也应该激流勇进,不断地提升组件的实用性和适用性,为开发者创造一个良好的开发体验。
我们将会持续更新ImageKnife三方库,后续会切换成GPU来渲染图片变换能力,不断进行性能优化,提升ImageKnife三方库。
同时也欢迎开发者使用和提issue。




原文标题:基于ArkUI框架开发-ImageKnife渲染层重构

文章出处:【微信公众号:OpenAtom OpenHarmony】欢迎添加关注!文章转载请注明出处。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 鸿蒙
    +关注

    关注

    57

    文章

    2272

    浏览量

    42526
  • OpenHarmony
    +关注

    关注

    25

    文章

    3558

    浏览量

    15785

原文标题:基于ArkUI框架开发-ImageKnife渲染层重构

文章出处:【微信号:gh_e4f28cfa3159,微信公众号:OpenAtom OpenHarmony】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    ArkUI-X开发指南:【SDK配置和构建说明】

    ArkUI-X SDK是ArkUI-X开源项目的编译产物,可将ArkUI-X SDK集成到现有Android和iOS应用工程中,使开发者基于一套ArkTS主代码,就可以构建支持多平台的
    的头像 发表于 05-25 16:48 2263次阅读
    <b class='flag-5'>ArkUI</b>-X<b class='flag-5'>开发</b>指南:【SDK配置和构建说明】

    鸿蒙开发ArkUI-X基础知识:【ArkUI代码工程及构建介绍】

    ArkUI作为OpenHarmony的默认开发框架,在本项目(ArkUI-X)中需要做到一套代码同时支持多平台构建,所以会采取共仓开发的方式
    的头像 发表于 05-25 16:45 1878次阅读
    鸿蒙<b class='flag-5'>开发</b><b class='flag-5'>ArkUI</b>-X基础知识:【<b class='flag-5'>ArkUI</b>代码工程及构建介绍】

    鸿蒙开发ArkUI-X基础知识:【ArkUI跨平台设计总体说明】

    本文档描述ArkUI开发框架跨平台运行能力相关的总体技术方案。
    的头像 发表于 05-24 15:41 1287次阅读
    鸿蒙<b class='flag-5'>开发</b><b class='flag-5'>ArkUI</b>-X基础知识:【<b class='flag-5'>ArkUI</b>跨平台设计总体说明】

    鸿蒙ArkUI-X跨平台技术:【开发准备】

    本文档适用于ArkUI跨平台应用开发的初学者。通过开发环境搭建、应用工程创建、编译和运行,熟悉ArkUI跨平台应用开发基本流程。
    的头像 发表于 05-24 10:40 319次阅读
    鸿蒙<b class='flag-5'>ArkUI</b>-X跨平台技术:【<b class='flag-5'>开发</b>准备】

    鸿蒙ArkUI-X框架开发:【开发准备】

    本文档适用于ArkUI-X框架开发的初学者。通过环境搭建、代码下载、代码编译、API扩展和使用,快速了解跨平台项目开发流程。
    的头像 发表于 05-23 21:02 316次阅读
    鸿蒙<b class='flag-5'>ArkUI</b>-X<b class='flag-5'>框架开发</b>:【<b class='flag-5'>开发</b>准备】

    鸿蒙ArkUI-X跨平台开发:【bility开发说明(Android平台)】

    本文介绍将ArkUI框架扩展到Android平台所需要的必要的类及其使用说明,开发者基于OpenHarmony,可复用大部分的应用代码(生命周期等)并可以部署到Android平台,降低跨平台应用
    的头像 发表于 05-21 10:54 760次阅读
    鸿蒙<b class='flag-5'>ArkUI</b>-X跨平台<b class='flag-5'>开发</b>:【bility<b class='flag-5'>开发</b>说明(Android平台)】

    鸿蒙ArkUI-X跨平台开发:【SDK目录结构介绍】

    本文档配套ArkUI-X,将OpenHarmony ArkUI开发框架扩展到不同的OS平台,比如Android和iOS平台,让开发者基于
    的头像 发表于 05-20 16:28 685次阅读
    鸿蒙<b class='flag-5'>ArkUI</b>-X跨平台<b class='flag-5'>开发</b>:【SDK目录结构介绍】

    鸿蒙ArkUI-X跨平台开发:【 应用工程结构说明】

    本文档配套ArkUI-X,将OpenHarmony ArkUI开发框架扩展到不同的OS平台,比如Android和iOS平台,让开发者基于
    的头像 发表于 05-19 21:05 396次阅读
    鸿蒙<b class='flag-5'>ArkUI</b>-X跨平台<b class='flag-5'>开发</b>:【 应用工程结构说明】

    鸿蒙跨平台框架:【ArkUi-X】创建工程

    鸿蒙推出了鸿ArkUi-X 框架所以就写个文章分享一下
    的头像 发表于 05-13 17:48 656次阅读
    鸿蒙跨平台<b class='flag-5'>框架</b>:【<b class='flag-5'>ArkUi</b>-X】创建工程

    鸿蒙ArkUI:【从代码到UI显示的整体渲染流程】

    方舟开发框架(简称ArkUI)是鸿蒙开发的UI框架,提供如下两种开发范式,我们 **只学声明式
    的头像 发表于 05-13 16:06 618次阅读
    鸿蒙<b class='flag-5'>ArkUI</b>:【从代码到UI显示的整体<b class='flag-5'>渲染</b>流程】

    鸿蒙开发学习:初探【ArkUI-X】

    **简单来说,ArkTS + ArkUI-X 对标的框架为 flutter,一次代码,编译为 native 全平台运行**
    的头像 发表于 05-13 15:58 836次阅读
    鸿蒙<b class='flag-5'>开发</b>学习:初探【<b class='flag-5'>ArkUI</b>-X】

    HarmonyOS实战开发-合理选择条件渲染和显隐控制

    if/else条件渲染ArkUI应用开发框架提供的渲染控制的能力之一。条件渲染可根据应用的不
    发表于 05-10 15:16

    鸿蒙ArkUI开发学习:【渲染控制语法】

    ArkUI开发框架是一套构建 HarmonyOS / OpenHarmony 应用界面的声明式UI开发框架,它支持程序使用 `if/else
    的头像 发表于 04-09 16:40 809次阅读
    鸿蒙<b class='flag-5'>ArkUI</b><b class='flag-5'>开发</b>学习:【<b class='flag-5'>渲染</b>控制语法】

    鸿蒙ArkUI开发-Tabs组件的使用

    鸿蒙ArkUI开发-Tabs组件的使用
    的头像 发表于 01-19 16:01 1456次阅读
    鸿蒙<b class='flag-5'>ArkUI</b><b class='flag-5'>开发</b>-Tabs组件的使用

    鸿蒙开发-ArkUI框架实战【日历应用 】

    :eTS 关于eTS eTS语言:基于TypeScript(简称TS)拓展的出来的,是OpenHarmony应用开发语言,使用ArkUI框架提供的组件进行界面开发。 什么是TypeSc
    发表于 01-17 21:37