<< All versions
Skill v1.0.0
currentAutomated scan100/100tencent-tds/kuiklyui-ai/kuikly-expand-view
──Details
PublishedOctober 29, 2026 at 07:51 PM
Content Hashsha256:960f6dffc011c605...
Git SHAd9ac08511784
──Files
Files (1 file, 11.2 KB)
SKILL.md11.2 KBactive
SKILL.md · 358 lines · 11.2 KB
name: kuikly-expand-view description: "Kuikly 自定义 View 开发助手。指导如何创建自定义 UI 组件,将原生 View 暴露给 Kuikly 侧使用。覆盖完整开发流程:Kuikly 侧组件定义、各平台 Native 侧实现(Android/iOS/鸿蒙ArkTS/H5/小程序)及使用。当用户需要自定义扩展 UI 组件时使用。" metadata: version: "1.0.0"
Contents
Core Guidelines
- View 是跨平台 UI 组件的统一接口: Kuikly 已封装常用 View(Text、Image、List 等),自定义 View 用于复用已有原生 UI 组件或满足特殊需求。
- 自定义 View 需双端实现: Kuikly 侧定义组件结构(viewName、Attr、Event),Native 侧(Android/iOS/鸿蒙/H5/小程序)实现具体渲染逻辑,通过
viewName关联。 - 组件名必须全端一致: Kuikly 侧
viewName()返回值必须与 Native 侧注册的名字完全一致。 - 属性和事件走 setProp 方法: Native 侧通过
setProp(propKey, propValue)接收 Kuikly 侧设置的属性和事件。 - 方法调用走 call 方法: Native 侧通过
call(method, params, callback)响应 Kuikly 侧的方法调用。
Workflow: Creating Expand View (Kuikly Side)
Use this workflow to create a expand View on the Kuikly (Kotlin) side.
Kuikly 组件由四部分组成:
viewName: 组件对应到原生组件的名字Attr: 组件的属性,用于指定该组件含有哪些属性Event: 用于接收来自原生组件发送的事件方法: 组件本身支持的方法,最终实现在原生侧
步骤:
- 新建 View 类继承
DeclarativeBaseView<XxxAttr, XxxEvent> - 实现
viewName()、createAttr()、createEvent()方法 - 定义
Attr类继承Attr,添加属性方法 - 定义
Event类继承Event,添加事件注册方法 - 编写声明式 API 扩展函数
- 在业务代码中使用组件
Step 1: 定义 View 类
kotlin
import com.tencent.kuikly.core.base.DeclarativeBaseViewclass MyImageView : DeclarativeBaseView<MyImageAttr, MyImageEvent>() {override fun createAttr(): MyImageAttr {return MyImageAttr()}override fun createEvent(): MyImageEvent {return MyImageEvent()}// 返回 Native 侧注册的组件名override fun viewName(): String {return "HRImageView"}// 组件方法(可选),实际实现在 Native 侧fun test() {performTaskWhenRenderViewDidLoad {renderView?.callMethod("test", "params")}}}
Step 2: 定义 Attr 类
Attr 表示组件支持的属性集。
kotlin
import com.tencent.kuikly.core.base.Attrclass MyImageAttr : Attr() {/*** 设置图片数据源* @param src 图片 URL* @return this(支持链式调用)*/fun src(src: String): MyImageAttr {"src" with src // 将属性透传给原生组件return this}/*** 设置占位图*/fun placeholder(url: String): MyImageAttr {"placeholder" with urlreturn this}/*** 设置缩放模式*/fun scaleType(type: String): MyImageAttr {"scaleType" with typereturn this}}
Step 3: 定义 Event 类
Event 表示组件支持的事件。
kotlin
import com.tencent.kuikly.core.base.event.Eventimport com.tencent.kuikly.core.nvi.serialization.json.JSONObjectclass MyImageEvent : Event() {/*** 图片加载成功回调*/fun loadSuccess(handler: (LoadSuccessParams) -> Unit) {register(LOAD_SUCCESS) {handler(LoadSuccessParams.decode(it))}}/*** 图片加载失败回调*/fun loadError(handler: (LoadErrorParams) -> Unit) {register(LOAD_ERROR) {handler(LoadErrorParams.decode(it))}}companion object {const val LOAD_SUCCESS = "loadSuccess"const val LOAD_ERROR = "loadError"}}// 事件参数解析类data class LoadSuccessParams(val src: String,val width: Int,val height: Int) {companion object {fun decode(params: Any?): LoadSuccessParams {val tempParams = params as? JSONObject ?: JSONObject()return LoadSuccessParams(src = tempParams.optString("src", ""),width = tempParams.optInt("width", 0),height = tempParams.optInt("height", 0))}}}data class LoadErrorParams(val src: String,val errorCode: Int) {companion object {fun decode(params: Any?): LoadErrorParams {val tempParams = params as? JSONObject ?: JSONObject()return LoadErrorParams(src = tempParams.optString("src", ""),errorCode = tempParams.optInt("errorCode", 0))}}}
Step 4: 组件方法(可选)
组件方法是 Kuikly 侧暴露的 API,实际实现在 Native 侧。
kotlin
class MyImageView : DeclarativeBaseView<MyImageAttr, MyImageEvent>() {// .../*** 重新加载图片(无返回值)*/fun reload() {performTaskWhenRenderViewDidLoad {renderView?.callMethod("reload", null)}}/*** 获取图片信息(异步回调)*/fun getImageInfo(callback: (width: Int, height: Int) -> Unit) {performTaskWhenRenderViewDidLoad {renderView?.callMethod("getImageInfo", null) { result ->val json = result as? JSONObjectcallback(json?.optInt("width") ?: 0, json?.optInt("height") ?: 0)}}}}
⚠️ 注意:- View 的方法支持异步回调结果,即renderView?.callMethod("method", "params", callback),但不支持同步返回结果。- View 方法不支持传递二进制数据,如需传输图片等二进制内容,请通过 Base64 编码后以 JSON 形式传递,或使用 Module 方法实现。
Step 5: 编写声明式 API
kotlin
import com.tencent.kuikly.core.base.ViewContainerfun ViewContainer<*, *>.MyImage(init: MyImageView.() -> Unit) {addChild(MyImageView(), init)}
Step 6: 业务使用
kotlin
override fun body(): ViewBuilder {val ctx = thisreturn {MyImage {attr {size(176f, 132f)src("https://example.com/image.png")placeholder("https://example.com/placeholder.png")}event {loadSuccess { params ->println("图片加载成功: ${params.src}, 尺寸: ${params.width}x${params.height}")}loadError { params ->println("图片加载失败: ${params.errorCode}")}}}}}
使用 ViewRef 获取组件引用
通过 ViewRef 可以获取组件实例,在 Pager 其他位置调用组件方法。
kotlin
@Page("MyPage")class MyPage : Pager() {// 声明 ViewRefprivate val imageRef = ViewRef<MyImageView>()override fun body(): ViewBuilder {return {MyImage {// 绑定 refref(imageRef)attr {src("https://example.com/image.png")}}Button {attr { title("重新加载") }event {click {// 通过 ref 调用方法imageRef.view?.reload()}}}}}}
Workflow: Implementing Native Side View
Use this workflow to implement the Native side of a expand View.
前提: 只需在业务需要支持的平台上实现 Native 侧 View,无需实现所有平台。
步骤:
- 确定需要支持的目标平台(Android/iOS/鸿蒙/H5/小程序)。
- 在目标平台宿主工程中创建对应的 View 类。
- 实现
setProp方法处理属性和事件。 - 实现
call方法处理方法调用。 - 将 View 注册到 Kuikly 框架。
各平台实现详见 VIEW_IMPLEMENT.md
速查:各平台 View 基类与注册方式
| 平台 | 基类/协议 | 注册方式 | 注意事项 | |
|---|---|---|---|---|
| Android | IKuiklyRenderViewExport | registerExternalRenderView 中 renderViewExport(name) { View(ctx) } | 继承原生 View 并实现接口 | |
| 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 支持的数据类型
| Kuikly 侧类型 | Native 侧接收类型 | |
|---|---|---|
String | String / NSString | |
Int / Float / Double | 对应基础类型 / NSNumber | |
Boolean | Boolean / BOOL | |
Event 回调 | KuiklyRenderCallback |
事件触发机制
在 Native 侧,事件通过 KuiklyRenderCallback 回调给 Kuikly 侧:
kotlin
// 保存回调private var loadSuccessCallback: KuiklyRenderCallback? = nulloverride fun setProp(propKey: String, propValue: Any): Boolean {return when (propKey) {"loadSuccess" -> {loadSuccessCallback = propValue as KuiklyRenderCallbacktrue}else -> super.setProp(propKey, propValue)}}// 触发回调private fun onImageLoaded(src: String, width: Int, height: Int) {loadSuccessCallback?.invoke(mapOf("src" to src,"width" to width,"height" to height))}
常见陷阱与正确做法
| ❌ 错误做法 | ✅ 正确做法 | |
|---|---|---|
| View 名字 Kuikly 侧与 Native 侧不一致 | 确保 viewName() 返回值与 Native 注册名完全一致 | |
| 自定义 View 未设置宽高导致不显示 | 自定义 View 跨端侧使用时必须显式设置宽高(如 size(w, h)),否则可能不会显示 | |
| iOS 侧 View 类名与 Kuikly 侧 viewName 不一致 | iOS 通过类名动态创建 View,类名必须与 `viewName()` 一致 | |
iOS 侧用 Swift 实现但未加 @objc 注解 | Swift 实现的 View 需要 @objc 或 @objcMembers 修饰 | |
鸿蒙侧忘记实现 createArkUIView() | 鸿蒙侧必须实现此方法返回 ComponentContent | |
| 忘记在 Native 侧注册自定义 View | 自定义 View 必须注册后才能使用 | |
在 performTaskWhenRenderViewDidLoad 之外调用 renderView | View 方法必须在 performTaskWhenRenderViewDidLoad 回调中调用 |