从零开始仿抖音做一个APP(首页顶部标签添加&页面关联)
本文主要介绍首页顶部标签相关布局及页面切换。
先看看首页布局:
首先一个顶部标签栏,底部一个Swiper,用于跟随顶部标签的变化而变化,同时支持页面滚动切换。此外对左右两个icon都进行了封装,对于重复使用的标签或者view都可以这样使用,如下图所示:
@Builder
iconTop(src: ResourceStr, clickevent: () => void) {
Row() {
Image(src)
.width(22)
.height(22)
}
.onClick(() => {
//处理点击事件
})
.height(HomeConstant.HOME_TAB_HEIGHT)
.width(36)
.justifyContent(FlexAlign.Center)
}
对于顶部标签的布局,本文使用了ForEach工具,每一个标签再次进行了封装,具体代码如下:
Flex({
justifyContent: FlexAlign.SpaceBetween,
space: { main: LengthMetrics.px(30), cross: LengthMetrics.px(30) }
}) {
ForEach(HomeConstant.HOME_TAB_ARRAY, (item: string, index: number) => {
this.textTop(index, item)
})
}.layoutWeight(1)
this.iconTop($r('app.media.home_search'), () => {
})
text封装:
@Builder
textTop(index: number, name: string) {
Column() {
Text(name)
.fontColor(this.currentIndex === index ? $r('app.color.home_tab_selected_color') :
$r('app.color.home_tab_normal_color'))
.fontSize(16)
.fontWeight(this.currentIndex === index ? 500 : 400)
.lineHeight(20)
.margin({ top: 10, bottom: 8 })
Divider()
.strokeWidth(2)//后续再对此处宽度、动画做进一步处理
.width(24)
.color('#fff')
.opacity(this.currentIndex === index ? 1 : 0)
}
.height('100%')
.justifyContent(FlexAlign.Center)
.layoutWeight(1)
.onClick(() => {
this.currentIndex = index
this.swiperController.changeIndex(this.currentIndex)
})
}
接下来将顶部标签与swiper进行关联,根据标签变化动态更新UI。此处swiper的数据源swiperData需要转为IDataSource类型。
Swiper(this.swiperController) {
LazyForEach(this.swiperData, (item: string, index: number) => {
if (index === 0) {
ExperienceView()
} else if (index === 1) {
LongVideoView()
} else if (index === 2) {
HotView()
} else if (index === 3) {
FocusView()
} else if (index === 4) {
RecommendView()
}
}, (item: string) => item)
}
.loop(false)
.onAnimationStart((index: number, targetIndex: number, extraInfo: SwiperAnimationEvent) => {
this.currentIndex = targetIndex
this.swiperController.changeIndex(targetIndex)
})
如此便实现了首页各个标签页面的切换的加载,效果如下所示。
接下来就是完成各个子模块的页面绘制。
本项目为工作之余随手编写,有很多可继续完善的地方(比如顶部是否用Tabs组件、部分组件的数据能否进一步封装、UI加载是否可以更流畅等),有待后续优化。