⚠️ Note: This skill only applies to mixing Kuikly DSL in Compose DSL(i.e., embedding Kuikly DSL components in Compose pages),does not supportthe reverse, mixing Compose DSL in Kuikly DSL.
Contents
- ComposeContainer page setup
- MakeKuiklyComposeNode API (atomic / container)
- Key constraints and common errors
- Using Kuikly Module in Compose
- Detailed reference documentation
ComposeContainer page setup
Compose pages inherit ComposeContainer(i.e., Pager) and call in willInit() call in 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 inherits from Kuikly Core's Pager, with a unified cross-platform page lifecycle (willInit / created / pageDidAppear / pageDidDisappear / pageWillDestroy)。
MakeKuiklyComposeNode API
bridging entry, embedding Kuikly DSL components into the Compose render tree. Two overloads:
Atomic components (no child nodes)
Applies to DeclarativeBaseView subclasses (self-rendering components such as Video, maps):
@Composable
fun <T : DeclarativeBaseView<*, *>> MakeKuiklyComposeNode(
factory: () -> T,
modifier: Modifier,
viewInit: T.() -> Unit = {}, // 创建时调用一次
viewUpdate: (T) -> Unit = {}, // 每次重组时调用
measurePolicy: MeasurePolicy = KuiklyDefaultMeasurePolicy
)
Minimal example(wrapping 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) } },
)
}
Container components (with child nodes)
Applies to ViewContainer subclasses, can mount Compose child nodes:
@Composable
fun <T : DeclarativeBaseView<*, *>> MakeKuiklyComposeNode(
factory: () -> T,
modifier: Modifier,
content: @Composable () -> Unit, // 子内容插槽
viewInit: T.() -> Unit = {},
viewUpdate: (T) -> Unit = {},
measurePolicy: MeasurePolicy = DefaultColumnMeasurePolicy
)
Minimal example(wrapping a container card):
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,
)
}
Key constraints and common errors
Choosing the factory base class
| Scenario | Base class |
|---|---|
| Atomic components (no child nodes) | DeclarativeBaseView |
| Container components (with child nodes) | ViewContainer |
| ❌ Forbidden | ComposeView |
❌ Forbidden to pass ComposeView subclasses to factory
ComposeView 's flattening optimization causes layout frame loss and the view to be invisible:
// ❌ 编译通过但运行时不可见
class MyView : ComposeView<ComposeAttr, ComposeEvent>() { ... }
MakeKuiklyComposeNode<MyView>(factory = { MyView() }, ...)
// ✅ 原子组件用 DeclarativeBaseView
// ✅ 容器组件用 ViewContainer
viewUpdate must be updated in sync
viewInit is called only once at creation; properties and event callbacks that change with Compose statemustalso be set in viewUpdate , otherwise they will not be updated after recomposition.
Using Kuikly Module in Compose
Via LocalActivity.current.getPager() obtain the Pager instance, then call 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() 等
}
acquireModulethrows an exception when not found;getModulereturns null when not found.
Detailed reference
- Component wrapping in detail(atomic/container, viewInit vs viewUpdate, error troubleshooting):COMPONENT_WRAPPING.md
- Module usage details(Router / Notify / SP / PageData / custom Module):MODULE_USAGE.md