mcpField
K
kuikly-compose-interop-dsl

kuikly-compose-interop-dsl

github.com/tencent-tds開発134438 回インストール11 週間前に更新
リポジトリ

kuikly-compose-interop-dsl について

Compose DSL のページに Kuikly DSL コンポーネントを組み込むための相互運用ガイドです。アトミック・コンテナコンポーネントのブリッジ、更新時の制約、Module の取得方法を説明し、逆方向の組み込みには対応しません。

主な機能

  1. 01ComposeContainer によるページ構築
  2. 02MakeKuiklyComposeNode によるコンポーネント埋め込み
  3. 03アトミック・コンテナコンポーネントへの対応
  4. 04viewUpdate でのプロパティとイベントの同期
  5. 05Compose からの Kuikly Module 取得

活用シーン

  1. 01Compose ページでの Kuikly 動画コンポーネントのラップ
  2. 02Compose ページへの Kuikly コンテナ埋め込み
  3. 03Compose の状態に応じたプロパティとコールバックの更新

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/tencent-tds/kuiklyui-ai --skill kuikly-compose-interop-dsl

インストール後、Claude Code で/kuikly-compose-interop-dslを入力して読み込まれたか確認します。

同梱ファイルreferences/COMPONENT_WRAPPING.mdreferences/MODULE_USAGE.md

詳細

プロジェクトの README より

Compose DSL 混用 Kuikly DSL 组件

⚠️ 注意:本 skill 仅适用于 Compose DSL 中混用 Kuikly DSL(即在 Compose 页面中嵌入 Kuikly DSL 组件),不支持反向在 Kuikly DSL 中混用 Compose DSL。

Contents

  • ComposeContainer 页面搭建
  • MakeKuiklyComposeNode API(原子 / 容器)
  • 关键约束与常见错误
  • Compose 中使用 Kuikly Module
  • 详细参考文档

ComposeContainer 页面搭建

Compose 页面继承 ComposeContainer(即 Pager),在 willInit() 中调用 setContent {}:

import com.tencent.kuikly.compose.ComposeContainer
import com.tencent.kuikly.compose.setContent
import com.tencent.kuikly.core.annotations.Page

@Page("myPage")
class MyPage : ComposeContainer() {
    override fun willInit() {
        super.willInit()
        setContent { MyScreen() }
    }
}

ComposeContainer 继承自 Kuikly Core 的 Pager,拥有统一的跨端页面生命周期(willInit / created / pageDidAppear / pageDidDisappear / pageWillDestroy)。

MakeKuiklyComposeNode API

桥接入口,将 Kuikly DSL 组件嵌入 Compose 渲染树。两个重载:

原子组件(无子节点)

适用于 DeclarativeBaseView 子类(Video、地图等自渲染组件):

@Composable
fun <T : DeclarativeBaseView<*, *>> MakeKuiklyComposeNode(
    factory: () -> T,
    modifier: Modifier,
    viewInit: T.() -> Unit = {},       // 创建时调用一次
    viewUpdate: (T) -> Unit = {},      // 每次重组时调用
    measurePolicy: MeasurePolicy = KuiklyDefaultMeasurePolicy
)

最小示例(封装 VideoView):

import androidx.compose.runtime.Composable
import com.tencent.kuikly.compose.extension.MakeKuiklyComposeNode
import com.tencent.kuikly.compose.ui.Modifier
import com.tencent.kuikly.core.views.VideoPlayControl
import com.tencent.kuikly.core.views.VideoView

@Composable
fun Video(src: String, playControl: VideoPlayControl, modifier: Modifier = Modifier) {
    MakeKuiklyComposeNode<VideoView>(
        factory = { VideoView() },
        modifier = modifier,
        viewInit = { getViewAttr().run { src(src); playControl(playControl) } },
        viewUpdate = { it.getViewAttr().run { src(src); playControl(playControl) } },
    )
}
容器组件(有子节点)

适用于 ViewContainer 子类,可挂载 Compose 子节点:

@Composable
fun <T : DeclarativeBaseView<*, *>> MakeKuiklyComposeNode(
    factory: () -> T,
    modifier: Modifier,
    content: @Composable () -> Unit,   // 子内容插槽
    viewInit: T.() -> Unit = {},
    viewUpdate: (T) -> Unit = {},
    measurePolicy: MeasurePolicy = DefaultColumnMeasurePolicy
)

最小示例(封装容器卡片):

import com.tencent.kuikly.core.base.ViewContainer
import com.tencent.kuikly.core.base.ContainerAttr
import com.tencent.kuikly.core.base.Event
import com.tencent.kuikly.core.base.ViewConst

class KuiklyCard : ViewContainer<ContainerAttr, Event>() {
    override fun createAttr() = ContainerAttr()
    override fun createEvent() = Event()
    override fun viewName() = ViewConst.TYPE_VIEW

    fun setup(cornerRadius: Float = 12f, onClick: (() -> Unit)? = null) {
        attr { borderRadius(cornerRadius) }
        onClick?.let { event { click { onClick() } } }
    }
}

@Composable
fun KuiklyCard(
    modifier: Modifier = Modifier,
    cornerRadius: Float = 12f,
    onClick: (() -> Unit)? = null,
    content: @Composable () -> Unit,
) {
    MakeKuiklyComposeNode<KuiklyCard>(
        factory = { KuiklyCard() },
        modifier = modifier,
        viewInit = { setup(cornerRadius, onClick) },
        viewUpdate = { it.setup(cornerRadius, onClick) },
        content = content,
    )
}

关键约束与常见错误

factory 基类选择
场景基类
原子组件(无子节点)DeclarativeBaseView
容器组件(有子节点)ViewContainer
❌ 禁止ComposeView
❌ 禁止将 ComposeView 子类传入 factory

ComposeView 的扁平化优化导致布局 frame 丢失,视图不可见:

// ❌ 编译通过但运行时不可见
class MyView : ComposeView<ComposeAttr, ComposeEvent>() { ... }
MakeKuiklyComposeNode<MyView>(factory = { MyView() }, ...)

// ✅ 原子组件用 DeclarativeBaseView
// ✅ 容器组件用 ViewContainer
viewUpdate 必须同步更新

viewInit 只在创建时调用一次;随 Compose 状态变化的属性和事件回调必须在 viewUpdate 中也设置,否则重组后不更新。

Compose 中使用 Kuikly Module

通过 LocalActivity.current.getPager() 获取 Pager 实例,再调用 acquireModule:

import com.tencent.kuikly.compose.ui.platform.LocalActivity
import com.tencent.kuikly.core.pager.Pager
import com.tencent.kuikly.core.module.RouterModule

@Composable
fun MyScreen() {
    val pager = LocalActivity.current.getPager() as Pager
    val router = pager.acquireModule<RouterModule>(RouterModule.MODULE_NAME)
    // 使用 router.openPage("targetPage", params) / router.closePage() 等
}

acquireModule 找不到时抛异常;getModule 找不到时返回 null。

详细参考

  • 组件封装详解(原子/容器、viewInit vs viewUpdate、错误排查):COMPONENT_WRAPPING.md
  • Module 使用详情(Router / Notify / SP / PageData / 自定义 Module):MODULE_USAGE.md

コメント