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
}

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐