首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >从0使用Kuikly框架写一个小红书Demo-Day3

从0使用Kuikly框架写一个小红书Demo-Day3

原创
作者头像
用户11358903
发布2025-10-13 10:53:48
发布2025-10-13 10:53:48
200
举报

三、  ComposeView组合组件及其生命周期详解

编写UI时,无论是Vue/React这些前端框架,或者是Android/iOS开发,往往都会将页面UI分模块,然后每个UI模块封装成独立的UI组件,以达到UI代码复用和UI逻辑分治的目的。Kuikly也是如此,Kuikly封装组件的手段是使用ComposeView组合组件。接下来就跟着Kuikly详细的官方教程学习怎么封装组件:https://kuikly.woa.com/%E5%BC%80%E5%8F%91%E6%96%87%E6%A1%A3/compose-view.html#%E5%A6%82%E4%BD%95%E5%B0%81%E8%A3%85composeview

3.1 封装组件

以Title Bar为例,首先新建一个类并继承ComposeView。

代码语言:kotlin
复制
internal class NavigationBarView : ComposeView<ComposeAttr, ComposeEvent>() {
 
    override fun body(): ViewBuilder {
    }
 
    override fun createAttr(): ComposeAttr {
        return ComposeAttr()
    }
 
    override fun createEvent(): ComposeEvent {
        return ComposeEvent()
    }
 
}

在NavigationBarView中,我们需要实现三个方法:body()、createAttr()、createEvent()

  • body() : 组件UI界面写在这里面,
  • createAttr() : 定义组件有哪些属性
  • createEvent() : 定义组件有哪些事件

接着我们实现NavigationBarView的UI,NavigationBarView左边有一个返回箭头,中间有一个title

代码语言:kotlin
复制
internal class NavigationBarView : ComposeView<ComposeAttr, ComposeEvent>() {
    override fun createAttr(): ComposeAttr {
        return ComposeAttr()
    }
 
    override fun createEvent(): ComposeEvent {
        return ComposeEvent()
    }
 
    override fun body(): ViewBuilder {
        return {
 
            View {
                attr {
                    size(pagerData.pageViewWidth, 44f)
                    marginTop(pagerData.statusBarHeight)
                    allCenter()
                    backgroundColor(Color.GRAY)
                }
 
                Image {
                    attr {
                        size(16f, 16f)
                        src(BASE_64)
                        resizeContain()
                        absolutePosition(left = 15f, top = (44f - 16f) / 2)
                    }
                }
 
                Text {
                    attr {
                        fontWeightBold()
                        fontSize(16f)
                        text("这是标题栏")
                    }
                }
 
            }
        }
    }
 
    companion object {
        private const val BASE_64 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAASBAMAAAB/WzlGAAAAElBMVEUAAAAAAAAAAAAAAAAAAAAAAADgKxmiAAAABXRSTlMAIN/PELVZAGcAAAAkSURBVAjXYwABQTDJqCQAooSCHUAcVROCHBiFECTMhVoEtRYA6UMHzQlOjQIAAAAASUVORK5CYII="
    }
 
}
 

实现完UI后,我们需要提供一个声明式方法给外部使用

代码语言:kotlin
复制
internal fun ViewContainer<*, *>.NavBar(init: NavigationBarView.() -> Unit) {
    addChild(NavigationBarView(), init)
}

在上述代码中,我们在ViewContainer扩展了NavBar方法, 并传入NavigationBarView的初始化闭包, 在方法内, 调用addChild, 把NavigationBarView实例和初始化闭包传入

外部调用NavBar方法即可将title bar组件添加到UI结构上

代码语言:kotlin
复制
@Page("1")
internal class TestPage : BasePager() {
 
    override fun body(): ViewBuilder {
        val ctx = this
        return {
            NavBar {  }
        }
    }
 
}

3.2 定义组件的属性

一个组件不仅仅只有UI界面,还有数据的流动。在NavigationBarView中,我们的标题的写死的,如果我们想使用从外部传入的标题,应该怎么做呢?

每个组合组件都有一个Attr类,代表组件自身的属性,让外部在调用组合组件时,配置组合组件的参数。

首先先定义一个类并继承ComposeAttr,声明title变量

代码语言:kotlin
复制
internal class NavBarAttr : ComposeAttr() {
    
    var title = ""
    
}

回到NavigationBarView中,将ComposeView<ComposeAttr, ComposeEvent>换成ComposeView<NavBarAttr, ComposeEvent>

并在createAttr()方法中返回NavBarAttr,最后将NavBarAttr中的title设置给Text组件

代码语言:kotlin
复制
internal class NavigationBarView : ComposeView<NavBarAttr, ComposeEvent>() {
 
    override fun createAttr(): NavBarAttr {
        return NavBarAttr()
    }
 
    override fun createEvent(): ComposeEvent {
        return ComposeEvent()
    }
 
    override fun body(): ViewBuilder {
        val ctx = this
        return {
 
            View {
                attr {
                    size(pagerData.pageViewWidth, 44f)
                    marginTop(pagerData.statusBarHeight)
                    allCenter()
                    backgroundColor(Color.GRAY)
                }
 
                Image {
                    attr {
                        size(16f, 16f)
                        src(BASE_64)
                        resizeContain()
                        absolutePosition(left = 15f, top = (44f - 16f) / 2)
                    }
                }
 
                Text {
                    attr {
                        fontWeightBold()
                        fontSize(16f)
                        text(ctx.attr.title)
                    }
                }
 
            }
        }
    }
 
    companion object {
        private const val BASE_64 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAASBAMAAAB/WzlGAAAAElBMVEUAAAAAAAAAAAAAAAAAAAAAAADgKxmiAAAABXRSTlMAIN/PELVZAGcAAAAkSURBVAjXYwABQTDJqCQAooSCHUAcVROCHBiFECTMhVoEtRYA6UMHzQlOjQIAAAAASUVORK5CYII="
    }
 
}

`

外部在使用NavBar时, 可在attr{}中,传入title的属性

代码语言:kotlin
复制
@Page("1")
internal class TestPage : BasePager() {
 
    private var translateAnimationFlag by observable(false)
 
    override fun body(): ViewBuilder {
        val ctx = this
        return {
            NavBar {
                attr {
                    title = "外部传入的标题"
                }
            }
        }
    }
}

3.3 定义组件的事件

属性可以自定义,事件自然也可以自定义,我们来看看怎么定义事件

先新建一个类并继承ComposeEvent,并定义backIconClick方法

代码语言:kotlin
复制
internal class NavBarEvent : ComposeEvent() {
    
    var clickHandler: (() -> Unit)? = null
    
    fun backIconClick(handler: () -> Unit) {
        clickHandler = handler
    }
}

和自定义属性一样,这里也需要把NavBarEvent传入NavBarView中,同时在点击事件触发时,通知外部

代码语言:kotlin
复制
internal class NavigationBarView : ComposeView<NavBarAttr, NavBarEvent>() {
 
    override fun createAttr(): NavBarAttr {
        return NavBarAttr()
    }
 
    override fun createEvent(): NavBarEvent {
        return NavBarEvent()
    }
 
    override fun body(): ViewBuilder {
        val ctx = this
        return {
 
            View {
                attr {
                    size(pagerData.pageViewWidth, 44f)
                    marginTop(pagerData.statusBarHeight)
                    allCenter()
                    backgroundColor(Color.GRAY)
                }
 
                Image {
                    attr {
                        size(16f, 16f)
                        src(BASE_64)
                        resizeContain()
                        absolutePosition(left = 15f, top = (44f - 16f) / 2)
                    }
                    
                    event { 
                        click { 
                            ctx.event.clickHandler?.invoke() // 回调给外部
                        }
                    }
                }
 
                Text {
                    attr {
                        fontWeightBold()
                        fontSize(16f)
                        text(ctx.attr.title)
                    }
                }
 
            }
        }
    }
 
    companion object {
        private const val BASE_64 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAASBAMAAAB/WzlGAAAAElBMVEUAAAAAAAAAAAAAAAAAAAAAAADgKxmiAAAABXRSTlMAIN/PELVZAGcAAAAkSURBVAjXYwABQTDJqCQAooSCHUAcVROCHBiFECTMhVoEtRYA6UMHzQlOjQIAAAAASUVORK5CYII="
    }
 
}

外部在使用NavBar时, 可在evnet{}中,监听NavBar组件的返回箭头点击事件

代码语言:kotlin
复制
internal class TestPage : BasePager() {
 
    override fun body(): ViewBuilder {
        val ctx = this
        return {
            NavBar {
                attr {
                    title = "外部传入的标题"
                }
                
                event {
                    backIconClick {
                        // 返回键点击事件
                    }
                }
            }
        }
    }
}

3.4 ComposeView生命周期

  • created: ComposeView已经创建, 此方法会在body方法前调用
  • viewWillLoad: ComposeView的UI组件树即将创建, 此方法会在body方法前调用
  • viewDidLoad: ComposeView的UI组件树已经创建好, 此方法会在body方法之后调用
  • viewDidLayout: ComposeView的UI组件树已经测量完毕,可以在此方法执行一些依赖组件大小的操作,例如开始启动动画
  • viewWillUnload: ComposeView即将被移除
  • viewDidUnload: ComposeView已经被移除
  • viewDestroyed: ComposeView已经被销毁

通过在继承ComposeView的子类重写这些方法,就可以在指定组件在什么时候干什么事了。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 三、  ComposeView组合组件及其生命周期详解
    • 3.1 封装组件
    • 3.2 定义组件的属性
    • 3.3 定义组件的事件
    • 3.4 ComposeView生命周期
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档