移动/游戏
在 Kuikly 中需要复用原生 UI 组件或实现特殊跨端…
在 Kuikly 项目中开发自定义 UI 组件并把原生 View 暴露给 Kuikly 侧使用时适用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在 Kuikly 中需要复用原生 UI 特定
解决思路
- 判断是否自定义 View:当需要复用已有原生 UI 组件或满足特殊需求时才自定义 View;否则优先使用 Kuikly 已封装的 Text、Image、List 等常用 View。
- 按双端实现组织:Kuikly 侧定义组件结构(viewName、Attr、Event、方法),Native 侧实现具体渲染逻辑,并通过 viewName 关联。
- 保证组件名全端一致:Kuikly 侧 viewName() 的返回值必须与 Native 侧注册的名字完全一致。
- Native 侧用 setProp(propKey, propValue) 接收 Kuikly 侧设置的属性和事件。
- Native 侧用 call(method, params, callback) 响应 Kuikly 侧的方法调用。
- 记住 Kuikly 组件由四部分组成:viewName、Attr、Event、方法;方法最终实现在 Native 侧。
- Kuikly 侧第 1 步:新建 View 类继承 DeclarativeBaseView<XxxAttr, XxxEvent>。
- Kuikly 侧第 2 步:在 View 类中实现 viewName()、createAttr()、createEvent();viewName() 返回 Native 侧注册的组件名,例如 HRImageView。
- Kuikly 侧第 3 步:定义 Attr 类继承 Attr,并为每个属性添加返回 this 的属性方法,便于链式调用。
- Kuikly 侧定义属性时用 "src" with src 等方式把属性透传给原生组件,例如 src(src)、placeholder(url)、scaleType(type)。
- Kuikly 侧第 4 步:定义 Event 类继承 Event,用 register(...) 注册事件,并为事件名定义常量,例如 LOAD_SUCCESS、LOAD_ERROR。
- Kuikly 侧解析事件参数:为事件参数创建 data class,并在 decode(params) 中把 params 转为 JSONObject,再用 optString/optInt 读取字段。
- Kuikly 侧第 5 步:编写声明式 API 扩展函数,例如 fun ViewContainer<*, *>.MyImage(init: MyImageView.() -> Unit) { addChild(MyImageView(), init) }。
- Kuikly 侧第 6 步:在业务代码中使用组件,例如 MyImage { attr { size(176f, 132f); src(...); placeholder(...) } event { loadSuccess { ... }; loadError { ... } } }。
- Kuikly 侧实现无返回值组件方法时,在方法中调用 performTaskWhenRenderViewDidLoad { renderView?.callMethod("reload", null) }。
- Kuikly 侧实现异步回调组件方法时,在 performTaskWhenRenderViewDidLoad 中调用 renderView?.callMethod("getImageInfo", null) { result -> ... },并从 result 中解析 JSONObject。
- 组件方法只支持异步回调结果,不支持同步返回结果。
- 组件方法不支持传递二进制数据;如需传输图片等二进制内容,通过 Base64 编码后以 JSON 形式传递,或改用 Module 方法实现。
- 使用 ViewRef 获取组件引用:声明 private val imageRef = ViewRef<MyImageView>(),在组件上调用 ref(imageRef),在 Pager 其他位置通过 imageRef.view?.reload() 调用组件方法。
- Native 侧只选择业务需要支持的平台实现 View,不必实现所有平台。
- Native 侧第 1 步:确定需要支持的目标平台(Android/iOS/鸿蒙/H5/小程序)。
- Native 侧第 2 步:在目标平台宿主工程中创建对应的 View 类。
- Native 侧第 3 步:实现 setProp 方法处理属性和事件。
- Native 侧第 4 步:实现 call 方法处理方法调用。
- Native 侧第 5 步:将 View 注册到 Kuikly 框架。
- 各平台实现详见 references/VIEW_IMPLEMENT.md。
- Android:继承原生 View 并实现 IKuiklyRenderViewExport;在 registerExternalRenderView 中通过 renderViewExport(name) { View(ctx) } 注册。
- iOS:实现 KuiklyRenderViewExportProtocol;注册依赖运行时动态创建,类名必须与 viewName 一致;属性方法命名 setCss_xxx,方法命名 css_xxx。
- 鸿蒙 ArkTS:继承 KuiklyRenderBaseView;在 getCustomRenderViewCreatorRegisterMap 或 getCustomRenderViewCreatorRegisterMapV2 中注册;必须实现 createArkUIView() 返回 ComponentContent。
- H5:实现 IKuiklyRenderViewExport;在 registerExternalRenderView 中通过 renderViewExport(name) { View() } 注册;重写 ele 属性返回 DOM 元素。
- 小程序:实现 IKuiklyRenderViewExport;在 registerExternalRenderView 中注册,同时调用 Transform.addComponentsAlias 并配置 base.wxml 模板;需创建 MiniXxxElement 并配置模板。
- Native 侧 setProp 数据类型映射:String 对应 String/NSString;Int/Float/Double 对应基础类型/NSNumber;Boolean 对应 Boolean/BOOL;Event 回调对应 KuiklyRenderCallback。
- Native 侧保存事件回调:在 setProp 中遇到 loadSuccess 等事件键时,把 propValue as KuiklyRenderCallback 保存到变量;需要触发时调用 callback.invoke(mapOf("src" to src, "width" to width, "height" to height))。
- 避免名字不一致:确保 Kuikly 侧 viewName() 返回值与 Native 注册名完全一致。
- 避免不显示:自定义 View 跨端侧使用时必须显式设置宽高,如 size(w, h)。
- 避免 iOS 创建失败:iOS 侧 View 类名必须与 Kuikly 侧 viewName() 一致。
- 避免 iOS Swift 实现问题:Swift 实现的 View 需要 @objc 或 @objcMembers 修饰。
- 避免鸿蒙缺失方法:鸿蒙侧必须实现 createArkUIView() 返回 ComponentContent。
- 避免忘记注册:自定义 View 必须在 Native 侧注册后才能使用。
- 避免 renderView 调用时机错误:View 方法必须在 performTaskWhenRenderViewDidLoad 回调中调用 renderView。
适用边界 · 注意事项
- 只需要 Kuikly 已封装的 Text、Image、List 等标准 View,且没有复用原生 UI 组件或特殊 UI 需求时,不适用。
- 无法修改或编译目标平台宿主工程、无法在 Native 侧注册 View 时,不适用。
- 需要 View 方法同步返回结果或直接传递二进制数据时,不适用;应改用 Module 方法或 Base64 编码后的 JSON 传递。