案例集合Tabs:自定义tabs突出(凸出)显示,异构,出血
·
🎯 案例集合Tabs:自定义tabs突出(凸出)显示,异构,出血
🌍 案例集合Tabs
🏷️ 效果图

📖 参考
🧩 拆解
import { common } from "@kit.AbilityKit"
import { window } from "@kit.ArkUI"
interface AvoidArea {
topRectHeight: number
bottomRectHeight: number
}
// 1、定义相关关键字和接口
const statusBarType = window.AvoidAreaType.TYPE_SYSTEM
const navBarType = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR
@Component
export struct tabHighlightedCase {
private mockData: string[] = ['购物', '体育', '服装', '军事']
private controller: TabsController = new TabsController()
@State selectIdx: number = 0
@State animationStartIdx: number = 0
// 2、初始化状态
context = this.getUIContext()?.getHostContext() as common.UIAbilityContext
private windowClass = this.context.windowStage.getMainWindowSync()
@State avoidArea: AvoidArea = { topRectHeight: 0, bottomRectHeight: 0 }
// 4、生命周期中调用
aboutToAppear(): void {
this.windowClass.setWindowLayoutFullScreen(true)
this.windowClass.on('avoidAreaChange', this.onAvoidAreaChange)
this.setAvoidArea()
}
aboutToDisappear(): void {
this.windowClass.setWindowLayoutFullScreen(false)
this.windowClass.off('avoidAreaChange', this.onAvoidAreaChange)
}
// 3、设置状态栏和导航栏避让区域 && 监听不同设备避让区域的变化
setAvoidArea() {
const statusBarArea = this.windowClass.getWindowAvoidArea(statusBarType)
this.avoidArea.topRectHeight = statusBarArea.topRect.height
const navBarArea = this.windowClass.getWindowAvoidArea(navBarType)
this.avoidArea.bottomRectHeight = navBarArea.bottomRect.height
}
onAvoidAreaChange = (data: window.AvoidAreaOptions) => {
if (data.type === statusBarType) {
this.avoidArea.topRectHeight = data.area.topRect.height
} else if (data.type === navBarType) {
this.avoidArea.bottomRectHeight = data.area.bottomRect.height
}
}
@Builder
tabBuilder(label: string, idx: number) {
if (idx === 2) {
Text().width(70)
}
Column({ space: 5 }) {
Text(label)
.fontSize(16)
.fontColor(this.animationStartIdx === idx ? Color.White : Color.Black)
.fontWeight(this.animationStartIdx === idx ? FontWeight.Medium : FontWeight.Normal)
Image($r('app.media.startIcon'))
.syncLoad(true)
.draggable(false)
.width(20)
.height(20)
}
.onClick(() => {
this.controller.changeIndex(idx)
this.selectIdx = this.animationStartIdx = idx
})
.layoutWeight(1)
}
build() {
Stack({ alignContent: Alignment.Bottom }) {
Tabs({ index: this.selectIdx }) {
ForEach(this.mockData, (item: string) => {
TabContent() {
Column() {
Text(item)
.fontColor(Color.White)
.fontSize(20)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.backgroundColor(Color.Brown)
}
})
}
.barHeight(0)
.onChange((idx: number) => {
this.selectIdx = idx
})
// 关键:切换动画开始时触发该回调:解决切换tabs延迟的问题
.onAnimationStart((idx: number, targetIndex: number) => {
if (idx === targetIndex) {
return
}
this.animationStartIdx = targetIndex
})
// 自定义tabs
Row() {
ForEach(this.mockData, (item: string, idx: number) => {
this.tabBuilder(item, idx)
})
Text('+')
.width(70)
.aspectRatio(1)
.fontSize(40)
.fontColor(Color.White)
.fontWeight(FontWeight.Regular)
.textAlign(TextAlign.Center)
.backgroundColor(Color.Blue)
.borderRadius('50%')
// 绝对定位
// 将组件的左上角顶点定位到父容器水平方向的中心点(即X轴50%位置)。此时组件左侧与父容器中心线对齐,未实现视觉居中
.position({ x: '50%', y: -20 })
// 反向平移
// 将组件沿X轴向左平移自身宽度的50%。通过负值偏移,组件的中心点移动到原定位点(父容器中心线),从而实现水平居中
.translate({ x: '-50%' })
.onClick(() => this.getUIContext().getPromptAction().showToast({ message: '添加独有逻辑' }))
}
.width('100%')
.backgroundColor(Color.Gray)
.padding({ bottom: this.avoidArea.bottomRectHeight + 'px', top: 5 })
}
.width('100%')
.height('100%')
.padding({ top: this.avoidArea.topRectHeight + 'px' })
}
}
🌸🌼🌺
更多推荐



所有评论(0)