鸿蒙滚动列表标题吸顶demo
·
import { hilog } from '@kit.PerformanceAnalysisKit'
@Entry
@Component
struct MicroApp {
private static readonly TITLE_BAR_HEIGHT: number = 50
@State currentTab: number = 0
@State scrollOffset: number = 0
@State isSticky: boolean = false
@State homeAppAreaHeight: number = 0
TAG = 'MyApp';
DOMAIN = 0x0001;
private categories: string[] = ['全部', '人事', '生产', '经营', '工具', '财务']
private homeApps: AppIcon[] = [
{ icon: $r('sys.media.AI_phone'), name: 'test' },
{ icon: $r('sys.media.AI_phone'), name: 'test' },
{ icon: $r('sys.media.AI_phone'), name: 'test' },
{ icon: $r('sys.media.AI_phone'), name: 'test' },
{ icon: $r('sys.media.AI_phone'), name: 'test' },
{ icon: $r('sys.media.AI_phone'), name: 'test' },
{ icon: $r('sys.media.AI_phone'), name: 'test' },
{ icon: $r('sys.media.AI_phone'), name: 'test' },
{ icon: $r('sys.media.AI_phone'), name: 'test' }
]
private scroller: Scroller = new Scroller();
aboutToAppear() {
const scrollOffsetInfo = this.scroller.currentOffset();
// hilog.info(this.DOMAIN, this.TAG, '初始滚动位置:%{public}s', JSON.stringify(scrollOffsetInfo));
}
build() {
Stack() {
if (this.isSticky) {
Column() {
Row() {
ForEach(this.categories, (category: string, index: number) => {
Text(category)
.fontSize(15)
.fontWeight(this.currentTab === index ? FontWeight.Medium : FontWeight.Normal)
.fontColor(this.currentTab === index ? '#007DFF' : '#333333')
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
.onClick(() => {
this.currentTab = index
})
}, (category: string, index: number) => index.toString())
}
.width('100%')
.backgroundColor('#ffffff')
Divider()
.color('#e0e0e0')
.strokeWidth(1)
}
.width('100%')
.height(50)
.position({ x: 0, y: 0 })
.zIndex(100)
}
Scroll(this.scroller) {
Column() {
Row() {
Text('应用')
.fontSize(20)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height(50)
.justifyContent(FlexAlign.Center)
.backgroundColor('#ffffff')
Column() {
Text('首页应用')
.fontSize(16)
.fontWeight(FontWeight.Medium)
.width('100%')
.padding({ left: 16, right: 16, top: 16, bottom: 12 })
Grid() {
ForEach(this.homeApps.slice(0, 9), (app: AppIcon, index: number) => {
GridItem() {
Column() {
Image(app.icon)
.width(48)
.height(48)
.objectFit(ImageFit.Contain)
Text(app.name)
.fontSize(12)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.margin({ top: 4 })
}
.width('100%')
.alignItems(HorizontalAlign.Center)
}
.aspectRatio(1)
}, (app: AppIcon, index: number) => index.toString())
}
.columnsTemplate(this.gridColumnsTemplate())
.rowsGap(16)
.columnsGap(8)
.padding({ left: 16, right: 16, top: 8, bottom: 16 })
}
.width('100%')
.backgroundColor('#f5f5f5')
.onAreaChange((area: Area) => {
this.homeAppAreaHeight = parseFloat(area.height.toString())
})
Column() {
Row() {
ForEach(this.categories, (category: string, index: number) => {
Text(category)
.fontSize(15)
.fontWeight(this.currentTab === index ? FontWeight.Medium : FontWeight.Normal)
.fontColor(this.currentTab === index ? '#007DFF' : '#333333')
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
.onClick(() => {
this.currentTab = index
})
}, (category: string, index: number) => index.toString())
}
.width('100%')
.backgroundColor('#ffffff')
.visibility(this.isSticky ? Visibility.Hidden : Visibility.Visible)
Divider()
.color('#e0e0e0')
.strokeWidth(1)
ForEach(this.categories.slice(1), (category: string, index: number) => {
Column() {
Text(category)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.width('100%')
.padding({ left: 16, right: 16, top: 16, bottom: 12 })
Grid() {
ForEach(this.getCategoryApps(category), (app: AppIcon, appIndex: number) => {
GridItem() {
Column() {
Image(app.icon)
.width(48)
.height(48)
.objectFit(ImageFit.Contain)
Text(app.name)
.fontSize(12)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.margin({ top: 4 })
}
.width('100%')
.alignItems(HorizontalAlign.Center)
}
.aspectRatio(1)
}, (app: AppIcon, appIndex: number) => appIndex.toString())
}
.columnsTemplate(this.gridColumnsTemplate())
.rowsGap(16)
.columnsGap(8)
.padding({ left: 16, right: 16, top: 8, bottom: 16 })
}
.width('100%')
}, (category: string, index: number) => index.toString())
}
.width('100%')
}
.width('100%')
}
.width('100%')
.height('100%')
.onScroll((xOffset: number, yOffset: number) => {
const currentOffset = this.scroller.currentOffset();
if (currentOffset) {
this.scrollOffset = currentOffset.yOffset;
hilog.info(this.DOMAIN, this.TAG, '累计 yOffset: %{public}f', currentOffset.yOffset);
this.isSticky = currentOffset.yOffset >= (MicroApp.TITLE_BAR_HEIGHT + this.homeAppAreaHeight);
hilog.info(this.DOMAIN, this.TAG, 'isSticky: %{public}b', this.isSticky);
}
})
.scrollBar(BarState.Auto)
}
.width('100%')
.height('100%')
}
gridColumnsTemplate(): string {
return '1fr 1fr 1fr 1fr 1fr'
}
getCategoryApps(category: string): AppIcon[] {
return this.homeApps.slice(0, 6)
}
}
interface AppIcon {
icon: Resource
name: string
}
更多推荐
所有评论(0)