本文由企业微信客户端团队黄玮分享,原题“在流沙上筑城:企微鸿蒙开发演进”,即时通讯网进行了排版优化和内容修订。
cover-opti.png (11.05 KB, 下载次数: 13)
下载附件 保存到相册
15 天前 上传
1.png (43.15 KB, 下载次数: 15)
2.png (19.2 KB, 下载次数: 10)
3.png (28.55 KB, 下载次数: 12)
export class TextData extends BaseData { text?: string | Resource fontColor?: ResourceColor fontSize?: number | string | Resource fontWeight?: number | FontWeight | string
//由Image+Text组成 export class ImgTextCellData extends BaseCellData { builder: WrappedBuilder<[]> = wrapBuilder(ImgTextCellBuilder) root: RowData img?: ImgData //对应Image控件 text?: TextData //对应Text控件 }
4.png (12.96 KB, 下载次数: 13)
完美的达成,不在于无可增添,而在于无可删减。 ——《风沙星辰》 安托万·德·圣-埃克苏佩里
//Repo对应Model层 class DemoContactRepo():IListRepository<DemoContactReq,DemoContactRsp> { override fun requestData( req: DemoContactReq,//请求参数 callback: (rsp: DemoContactRsp) -> Unit,//结果回调 errorCallback: (errorCode: Int, errorMsg: Any?) -> Unit//错误回调 ) { //请求数据,返回 ContactService.getContact(req){contacts-> callback(contacts) } } }
//继承自单数据源列表基类,泛型指明请求与返回的业务数据类型 class DemoContactViewModel: SingleListViewModel<DemoContactReq, DemoContactRsp>() { /** * 业务数据转为UI数据 */ overridefun transferData(data: DemoContactRsp): List<ICellData> { returndata.contacts.map { ImgPhotoTextImgCellData( //通用组件 dataId = it.id, photo = PhotoData(url = it.avatar),//一个图片控件 leftText = TextData(text = it.name))//一个文本控件 } } /** * 拉取数据所用的仓库(对应Model层) */ overridefun initRepository(): IListRepository<DemoContactReq, DemoContactRsp> { return DemoContactRepo() } /** * 初次或刷新页面时的请求参数 */ overridefun refreshParam(arguments: Bundle?): DemoContactReq { return DemoContactReq(0,20) } }
5.png (9.97 KB, 下载次数: 14)
//继承自本地静态列表基类,无数据请求 class DemoAttendanceViewModel:LocalSingleListViewModel() { //... //🔧 乐高式组件拼装 overridefun transformCellDataList(): List<ICellData> { return listOf( attendanceCellData("打卡人员","员工A").section(1), attendanceCellData("规则名称","打卡规则abc").section(1), attendanceCellData("规则类型","固定上下班").section(2), attendanceCellData("打卡时间","周一至周五,09:00-10:00").section(2), attendanceCellData("打卡方式","手机+智慧考勤机").section(3), attendanceCellData("打卡位置","天府三街198号").section(3), attendanceCellData("打卡Wi-Fi", "未设置").section(3), attendanceCellData("打卡设备", "").section(3), TextCellData(TextData.tips("位置和Wi-Fi满足任意一项即可打卡")).noneDivider(), attendanceCellData("加班规则","以加班申请为准").section(4), attendanceCellData("更多设置","").section(5), ButtonCellData(ButtonData("删除规则", buttonStyle = R.style.button_l_white, textColor = R.color.day_night_color_chrome_red.getColor())).section(6)) } //对通用Cell的简单封装 privatefun attendanceCellData(title:String,desc:String):ImgPhotoTextImgCellData{ return ImgPhotoTextImgCellData(/*设置属性*/) } }
6.png (18.46 KB, 下载次数: 13)
如果想设计一个便于推进各项工作的系统,其策略就是要在设计中尽可能长时间地保留尽可能多的可选项。 ——《整洁架构之道》
@Component export struct DemoPage{ build(){ Text("Hello World!") //这是一个函数,没法拿到它的对象,也就没法进行动态赋值 } }
7.png (31.19 KB, 下载次数: 14)
8.png (92.42 KB, 下载次数: 16)
9.png (29.05 KB, 下载次数: 14)
@Component export struct WwText { @ObjectLink data: TextData @State modifier: TextModifier = new TextModifier(new TextData()) aboutToAppear(): void { this.modifier.data = this.data } build() { Text(this.data.text) .attributeModifier(this.modifier) //通过modifier更新属性,不必再调其他函数 } }
10.png (24.2 KB, 下载次数: 13)
//WWText.ts export class WwText extends ViewPU { //... initialRender() { this.observeComponentCreation2((elmtId, isInitialRender) => { //这里就是会刷新的部分 Text.create(this.data.text); Text.attributeModifier.bind(this)(ObservedObject.GetRawObject(this.modifier)); }, Text); Text.pop(); } }
11.png (56.55 KB, 下载次数: 14)
12.png (10.71 KB, 下载次数: 14)
export class TextModifier extends BaseModifier<TextAttribute> { //... applyAttribute(instance: TextAttribute, data: TextData) { super.applyAttribute(instance, data) if (data.fontColor || data.fontColor == 0) { instance.fontColor(data.fontColor) } if (data.textAlign) { instance.textAlign(data.textAlign) } //... } }
class SubscribableHandler{ get(target,property,receiver){ //... switch(property){ default: const result = Reflect.get(target,property,receiver)//反射获取属性 if(/*...*/){ let isTracked = this.isPropertyTracked(target, propertyStr); this.readCbFunc_.call(this.obSelf_, receiver, propertyStr, isTracked); } } } }
一次刷新get次数 = 10X5X(23+45) = 3400次 3400/10000X9 = 3ms
Column(){ WwText({data:this.data1}).width("100%") WwText({data:this.data2}) }
13.png (10.07 KB, 下载次数: 13)
14.png (22.41 KB, 下载次数: 15)
15.png (33.65 KB, 下载次数: 13)
按官方的用法,只有多层嵌套监听的场景才需要@Observed注解
16.png (26.4 KB, 下载次数: 13)
export class BaseData<INS extends CommonAttribute = CommonAttribute>{ //view的实例,由Update赋值和清理 ins?:INS //用于刷新构造函数 updateConstructorFunc?: () =>void private _width?: Length private _height?: Length //... set width(width: Length|undefined) { this._width = width this.ins?.width(width) //设置属性时直接设置到view上 } get width():Length|undefined{ returnthis._width } //...
export class BaseUpdater<DATA extends BaseData, T extends CommonAttribute, C = Initializer<T>> extends AttributeUpdater<T, C> { data?: DATA constructor(data?: DATA) { super() this.data = data } //用于批量刷新所有已设置的属性,上屏或reuse时触发 updateData(data?: DATA, instance?: T): BaseUpdater<DATA, T, C> { //... this.setUpdateFunc(this.data, ins) if (ins) { this.applyAttribute(ins, this.data) this.refreshConstructor() } returnthis } //设置属性 applyAttribute(instance: CommonAttribute, data: BaseData) { if (data.width || data.width == 0) { instance.width(data.width) } if (data.height || data.height == 0) { instance.height(data.height) } //... } }
17.png (47.96 KB, 下载次数: 10)
@Component export struct ImgTextCell { @Consume@Watch("updateData") cellData: ImgTextCellData rootUpdater = new RowUpdater() imgUpdater = new ImageUpdater() textUpdater = new TextUpdater() aboutToAppear() { this.updateData() } aboutToReuse() { this.updateData() } build() { Row() { Image(ImageUpdater.EMPTY).attributeModifier(this.imgUpdater) Text().attributeModifier(this.textUpdater) }.attributeModifier(this.rootUpdater) } //data与updater绑定 private updateData() { this.rootUpdater.updateData(this.cellData.root) this.imgUpdater.updateData(this.cellData.img) this.textUpdater.updateData(this.cellData.text) } }
export class BaseData extends BaseUpdater{ //... }
@Component export struct ImgTextCell { @Consume cellData: ImgTextCellData build() { Row() { Image(ImageUpdater.EMPTY).attributeModifier(this.cellData.img) Text().attributeModifier(this.cellData.text) }.attributeModifier(this.cellData.root) } }
18.png (68.97 KB, 下载次数: 14)
19.png (23.13 KB, 下载次数: 12)
build() { Row() { Image("").attributeModifier(this.imgUpdater) Text().attributeModifier(this.textUpdater) }.attributeModifier(this.rootUpdater) }
initialRender() { this.observeComponentCreation2((elmtId, isInitialRender) => { Row.create(); Row.attributeModifier.bind(this)(this.rootUpdater); }, Row); this.observeComponentCreation2((elmtId, isInitialRender) => { Image.create(""); Image.attributeModifier.bind(this)(this.imgUpdater); }, Image); this.observeComponentCreation2((elmtId, isInitialRender) => { Text.create(); Text.attributeModifier.bind(this)(this.textUpdater); }, Text); Text.pop(); Row.pop(); }
由于鸿蒙的动态帧率机制,118其实就是滑动时满帧。
20.png (13.5 KB, 下载次数: 14)
来源:即时通讯网 - 即时通讯开发者社区!
轻量级开源移动端即时通讯框架。
快速入门 / 性能 / 指南 / 提问
轻量级Web端即时通讯框架。
详细介绍 / 精编源码 / 手册教程
移动端实时音视频框架。
详细介绍 / 性能测试 / 安装体验
基于MobileIMSDK的移动IM系统。
详细介绍 / 产品截图 / 安装体验
一套产品级Web端IM系统。
详细介绍 / 产品截图 / 演示视频
精华主题数超过100个。
连续任职达2年以上的合格正式版主
为论区做出突出贡献的开发者、版主等。
Copyright © 2014-2024 即时通讯网 - 即时通讯开发者社区 / 版本 V4.4
苏州网际时代信息科技有限公司 (苏ICP备16005070号-1)
Processed in 0.584984 second(s), 43 queries , Gzip On.