HarmonyOS Next 应用首页界面开发实践(二)

109 阅读2分钟
3. 分类标题构建

构建分类标题组件,包含多个分类标题和一个“更多”按钮,点击分类标题可切换选中状态。

@Builder
ClassifyTitle() {
  Flex({ justifyContent: FlexAlign.SpaceBetween }) {
    ForEach(classifyTitle, (item: Resource, index?: number) => {
      Text(item)
        .fontSize($r('app.float.middle_font_size'))
        .opacity(this.titleIndex === index ? StyleConstants.FULL_OPACITY : StyleConstants.EIGHTY_OPACITY)
        .fontWeight(this.titleIndex === index ? StyleConstants.FONT_WEIGHT_SEVEN : StyleConstants.FONT_WEIGHT_FOUR)
        .fontColor(Color.White)
        .onClick(() => {
          if (index !== undefined) {
            this.titleIndex = index;
          }
        })
    }, (item: Resource) => JSON.stringify(item))
    Row() {
      Image($r('app.media.ic_split_line'))
        .width($r('app.float.vp_one'))
        .height($r('app.float.vp_fourteen'))
      Image($r('app.media.ic_more'))
        .width($r('app.float.vp_sixteen'))
        .height($r('app.float.vp_sixteen'))
        .margin({
          left: $r('app.float.vp_two'),
          right: $r('app.float.vp_two')
        })
      Text($r('app.string.title_bar_classification'))
        .fontSize($r('app.float.middle_font_size'))
        .fontColor(Color.White)
        .opacity(this.titleIndex === undefined ? StyleConstants.FULL_OPACITY : StyleConstants.EIGHTY_OPACITY)
        .fontWeight(this.titleIndex === undefined ?
        StyleConstants.FONT_WEIGHT_SEVEN : StyleConstants.FONT_WEIGHT_FOUR)
    }
    .onClick(() => {
      this.titleIndex = 0;
    })
  }
  .margin({ top: $r('app.float.vp_eight') })
  .width(StyleConstants.FULL_WIDTH)
}
  • ForEach 循环:遍历分类标题列表,动态生成分类标题组件。
  • opacityfontWeight:根据 titleIndex 控制分类标题的透明度和字体粗细,实现选中状态的视觉效果。
  • onClick 事件:点击分类标题时,更新 titleIndex 的值。
4. 轮播图构建

构建轮播图组件,根据当前断点设置轮播图的显示数量、间距和指示器。

@Builder
CustomSwiper() {
  Swiper() {
    ForEach(swiperImage, (item: Resource) => {
      Image(item)
        .width(StyleConstants.FULL_WIDTH)
        .aspectRatio(StyleConstants.IMAGE_ASPECT_RATIO)
        .borderRadius($r('app.float.vp_sixteen'))
        .backgroundColor(Color.White)
    }, (item: Resource) => JSON.stringify(item))
  }
  .autoPlay(true)
  .itemSpace(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM ? 0 : StyleConstants.ITEM_SPACE)
  .width(StyleConstants.FULL_WIDTH)
  .indicator(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM ?
    new DotIndicator().selectedColor($r('app.color.indicator_select')) : false)
  .displayCount(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ? StyleConstants.DISPLAY_THREE :
    (this.currentBreakpoint === BreakpointConstants.BREAKPOINT_MD ? StyleConstants.DISPLAY_TWO :
    StyleConstants.DISPLAY_ONE))
  .margin({ top: $r('app.float.vp_twelve'), bottom: $r('app.float.vp_twelve') })
}
  • Swiper 组件:实现轮播图的自动播放和循环显示。
  • itemSpaceindicatordisplayCount:根据当前断点动态设置轮播图的间距、指示器和显示数量。
5. 活动标题构建

构建活动标题组件,包含多个活动标题和描述,点击活动标题可切换选中状态。

@Builder
ActivityTitle() {
  Flex({ justifyContent: FlexAlign.SpaceAround }) {
    ForEach(activityTitle, (item: ActivityTitleModel, index?: number) => {
      Flex({
        direction: FlexDirection.Column,
        justifyContent: FlexAlign.Center,
        alignItems: ItemAlign.Center
      }) {
        Text(item.title)
          .fontSize($r('app.float.small_font_size'))
          .fontWeight(StyleConstants.FONT_WEIGHT_FIVE)
          .fontColor(Color.Black)
        Text(item.desc)
          .fontSize($r('app.float.smaller_font_size'))
          .fontWeight(StyleConstants.FONT_WEIGHT_FOUR)
          .fontColor(this.activityTitleIndex === index ? $r('app.color.focus_color') : Color.Black)
          .opacity(this.activityTitleIndex === index ? StyleConstants.FULL_OPACITY : StyleConstants.SIXTY_OPACITY)
      }
      .onClick(() => {
        if (index !== undefined) {
          this.activityTitleIndex = index;
        }
      })
      .height(StyleConstants.FULL_HEIGHT)
    }, (item: ActivityTitleModel) => JSON.stringify(item))
  }
  .height($r('app.float.activity_title_height'))
  .width(StyleConstants.FULL_WIDTH)
  .padding($r('app.float.vp_twelve'))
  .margin({ bottom: $r('app.float.vp_six'), top: $r('app.float.vp_six') })
  .backgroundColor($r('app.color.page_background'))
  .borderRadius($r('app.float.vp_sixteen'))
}
  • ForEach 循环:遍历活动标题列表,动态生成活动标题组件。
  • opacityfontColor:根据 activityTitleIndex 控制活动描述的透明度和字体颜色,实现选中状态的视觉效果。
  • onClick 事件:点击活动标题时,更新 activityTitleIndex 的值。
6. 页面布局构建

使用 StackFlex 组件构建页面布局,包含背景图片、搜索标题、分类标题、轮播图、活动标题和商品列表。

build() {
  Stack({ alignContent: Alignment.Top }) {
    Image($r('app.media.ic_app_background'))
      .width(StyleConstants.FULL_WIDTH)
      .height($r('app.float.image_background_height'))
      .objectFit(ImageFit.Auto)
    Flex({ direction: FlexDirection.Column }) {
      this.SearchTitle()
      Scroll() {
        Column() {
          this.ClassifyTitle()
          this.CustomSwiper()
          this.ActivityTitle()

          CommodityList({
            commodityList: $commodityList,
            column: this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ? StyleConstants.DISPLAY_FOUR :
              (this.currentBreakpoint === BreakpointConstants.BREAKPOINT_MD ?
              StyleConstants.DISPLAY_THREE : StyleConstants.DISPLAY_TWO)
          })
        }
      }
      .scrollBar(BarState.Off)
    }
    .padding({ left: $r('app.float.vp_twelve'), right: $r('app.float.vp_twelve'), top: AppStorage.get<string>('topAvoid') || 0 })
  }
}
  • Stack 组件:用于叠加背景图片和其他组件。
  • Flex 组件:用于垂直排列其他组件。
  • Scroll 组件:实现页面内容的滚动显示。
  • CommodityList 组件:根据当前断点动态设置商品列表的列数。

总结

通过上述代码实现,我们在 HarmonyOS Next 中完成了一个功能丰富的首页界面开发。该界面包含搜索、分类、轮播图、活动标题和商品列表等功能,并且能够根据不同的断点进行自适应布局。开发者可以根据实际需求对代码进行扩展和优化,以满足不同应用场景的需求。