鸿蒙开发自定义TabLayout和TabPager联动
鸿蒙开发TabLayout和TabPager联动,类似Android的SlidingTabLayout和ViewPaer
一、效果图:
二、思路:
自定义组件TabLayout和TabPager
三、关键代码:
@Component
export struct TabLayout {
@ObjectLink mediator: TabLayoutPagerMediator
@State tabItemWidth: number = 0
@BuilderParam TabItemBuilder: (item: TabItem) => void
@BuilderParam TabIndicatorBuilder: () => void
indexChanged?: (item: number) => void
showIndicator: boolean = true
build() {
Stack({ alignContent: Alignment.BottomStart }) {
Row() {
ForEach(this.mediator.tabItems, (item: TabItem, index:number) => {
Stack({ alignContent: Alignment.Center }) {
if (this.TabItemBuilder) {
this.TabItemBuilder(item)
} else {
this.DefaultTabItemBuilder(item)
}
}.layoutWeight(1)
.onAreaChange((_, newValue: Area) => {
this.tabItemWidth = newValue.width as number
})
.onClick(() => {
this.indexChanged?.(item.index)
this.mediator.jumpToIndex(item.index)
})
}, (item:TabItem) => `${item.index}-${JSON.stringify(item)}`)
}
if (this.showIndicator) {
Stack({ alignContent: Alignment.Bottom }) {
if (this.TabIndicatorBuilder) {
this.TabIndicatorBuilder()
} else {
this.DefaultTabIndicatorBuilder()
}
}
.offset({ x: this.getIndicatorOffsetX() })
.width(this.tabItemWidth)
}
}
}
getIndicatorOffsetX():number{
//logContent("getIndicatorOffsetX",`${this.mediator.currentIndex} - ${this.tabItemWidth} - ${this.mediator.currentIndex * this.tabItemWidth}`)
return this.mediator.currentIndex * this.tabItemWidth
}
@Builder
DefaultTabItemBuilder(item: TabItem) {
Text(item.name)
.fontSize(SizeConstant.TEXT_L)
.fontColor(this.mediator.currentIndex === item.index
? $r('app.color.color_222')
: $r('app.color.color_555'))
.textAlign(TextAlign.Center)
.fontWeight(FontWeight.Bold)
.height(SizeConstant.TAB_LAYOUT_HEIGHT)
}
@Builder
DefaultTabIndicatorBuilder() {
Divider()
.strokeWidth(SizeConstant.TAB_LAYOUT_INDICATOR_HEIGHT)
//.margin({ bottom: SizeConstant.SPACE_S })
.color($r('app.color.color_main'))
.width(SizeConstant.TAB_LAYOUT_INDICATOR_WIDTH)
.lineCap(LineCapStyle.Round)
.align(Alignment.Bottom)
}
}
四、项目demo源码结构图:
有需要完整源码demo的私信我,我每天都看私信的。