HarmonyOS 鸿蒙Next 滑动吸顶效果demo

发布于 1周前 作者 htzhanglong 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 滑动吸顶效果demo

scroll组件滑动时,吸顶效果的代码

4 回复
class DataItem {

  img: ResourceStr = ''

  title?: string = ''

  desc?: string = ''

  price?: string = ''

}

@Entry

@Component

struct CeilingEffect {

  private scrollerForScroll: Scroller = new Scroller()

  private scrollerForList: Scroller = new Scroller()

  private tabController: TabsController = new TabsController()

  private swiperController: SwiperController = new SwiperController()

  private hotSearchKeywords: string[] = ['烤肉', '火锅', '海底捞', '东北菜']

  @State listInfoItem: Array<DataItem> = [

    {

      img: $r('app.media.tipImg'),

      title: '【北京君安标准】HPV九价',

      desc: '仅适用18岁以上成年人接种该疫苗,如您不符合条件注射年龄,请勿购买',

      price: '¥4380'

    },

    {

      img: $r('app.media.tipImg'),

      title: '【北京君安标准】HPV九价',

      desc: '仅适用18岁以上成年人接种该疫苗,如您不符合条件注射年龄,请勿购买',

      price: '¥4380'

    },

    {

      img: $r('app.media.tipImg'),

      title: '【北京君安标准】HPV九价',

      desc: '仅适用18岁以上成年人接种该疫苗,如您不符合条件注射年龄,请勿购买',

      price: '¥4380'

    },

    {

      img: $r('app.media.tipImg'),

      title: '【北京君安标准】HPV九价',

      desc: '仅适用18岁以上成年人接种该疫苗,如您不符合条件注射年龄,请勿购买',

      price: '¥4380'

    },

    {

      img: $r('app.media.tipImg'),

      title: '【北京君安标准】HPV九价',

      desc: '仅适用18岁以上成年人接种该疫苗,如您不符合条件注射年龄,请勿购买',

      price: '¥4380'

    },

    {

      img: $r('app.media.tipImg'),

      title: '【北京君安标准】HPV九价',

      desc: '仅适用18岁以上成年人接种该疫苗,如您不符合条件注射年龄,请勿购买',

      price: '¥4380'

    },

    {

      img: $r('app.media.tipImg'),

      title: '【北京君安标准】HPV九价',

      desc: '仅适用18岁以上成年人接种该疫苗,如您不符合条件注射年龄,请勿购买',

      price: '¥4380'

    },

    {

      img: $r('app.media.tipImg'),

      title: '【北京君安标准】HPV九价',

      desc: '仅适用18岁以上成年人接种该疫苗,如您不符合条件注射年龄,请勿购买',

      price: '¥4380'

    }

  ]

  @State tabBarContent: Array<ResourceStr> = [$r('app.media.tab_barImg'), $r('app.media.tab_barImg2'), $r('app.media.tab_barImg3')]

  @Builder

  tabBuilder(item: ResourceStr) {

    Column(){

      Image(item)

        .width(100)

    }

    .width('100%')

  }

  @Builder

  tabContentData() {

    Grid(this.scrollerForList) {

      ForEach(this.listInfoItem, (item: DataItem) => {

        GridItem() {

          Column() {

            Image(item.img)

              .width('100%')

            Column() {

              Text(item.title)

                .fontSize(18)

                .fontWeight(FontWeight.Medium)

                .margin({ top: 4 })

                .maxLines(1)

                .textOverflow({

                  overflow: TextOverflow.Ellipsis

                })

                .fontColor($r('sys.color.ohos_id_color_text_primary'))

              Text(item.desc)

                .fontSize(14)

                .margin({ top: 4 })

                .maxLines(2)

                .textOverflow({

                  overflow: TextOverflow.Ellipsis

                })

                .fontColor($r('sys.color.ohos_id_color_text_secondary'))

              Text(item.price)

                .fontSize(18)

                .margin({ top: 8 })

                .fontColor(Color.Red)

                .fontWeight(FontWeight.Medium)

            }

            .padding({ left: 12, right: 12, top: 2, bottom: 12 })

            Button("立即购买")

              .height(40)

              .backgroundColor(Color.Orange)

              .width("80%")

              .margin({ bottom: 24 })

          }

          .width('100%')

          .borderRadius(12)

          .alignItems(HorizontalAlign.Center)

          .backgroundColor($r('sys.color.ohos_id_color_background'))

        }

      })

    }

    .columnsTemplate('1fr 1fr')

    .columnsGap(10)

    .rowsGap(10)

    .maxCount(20)

    .scrollBar(BarState.Off)

    .edgeEffect(EdgeEffect.None)

    .nestedScroll({

      scrollForward: NestedScrollMode.PARENT_FIRST,

      scrollBackward: NestedScrollMode.SELF_FIRST

    })

  }

  build() {

    Flex({ direction: FlexDirection.Column }) {

      Stack({ alignContent: Alignment.End }) {

        // 搜索框

        Row() {

          Row() {

            Text('北京市')

              .fontSize(16)

              .fontWeight(FontWeight.Medium)

              .fontColor($r('sys.color.ohos_id_color_text_primary'))

            Image($r('app.media.public_arrow_down'))

              .width(20)

              .margin({ left: 12, right: 12 })

              .objectFit(ImageFit.ScaleDown)

              .fillColor($r('sys.color.ohos_id_color_fourth'))

            Divider()

              .vertical(true)

              .height(25)

              .color($r('sys.color.ohos_id_color_fourth'))

          }

          Row() {

            Image($r('sys.media.ohos_ic_public_search_filled'))

              .width(15)

              .height(15)

              .fillColor($r('sys.color.ohos_id_color_fourth'))

            Swiper(this.swiperController) {

              ForEach(this.hotSearchKeywords, (item: string) => {

                Text(item)

                  .fontSize(12)

                  .margin({ left: 10 })

                  .fontColor($r('sys.color.ohos_id_color_text_tertiary'))

              })

            }

            .layoutWeight(1)

            .height('100%')

            .vertical(true) // 方向:纵向

            .autoPlay(true) // 自动播放

            .indicator(false) // 隐藏指示器

            .interval(3000) // 切换间隔时间3秒

          }

          .margin({ left: 25 })

        }

        .width('100%')

        .height('100%')

        .padding({ left: 20 })

        .alignItems(VerticalAlign.Center)

        .justifyContent(FlexAlign.Start)

        .border({ width: 2, color: Color.Red, radius: 24 })

        .backgroundColor($r('sys.color.ohos_id_color_background'))

        Button("搜索")

          .width(70)

          .height(39)

          .fontSize(16)

          .backgroundColor(Color.Orange)

          .fontColor(Color.White)

          .margin(3)

      }

      .width('100%')

      .height(45)

      .flexShrink(0)

      .margin({ top: 8, bottom: 8 })

      Scroll(this.scrollerForScroll) {

        Column() {

          Swiper() {

            ForEach(this.listInfoItem, (item: DataItem) => {

              Image(item.img)

                .width('100%')

            })

          }

          .height(250)

          .loop(true)

          .autoPlay(true)

          .interval(1000)

          Tabs({ barPosition: BarPosition.Start, index: 0, controller: this.tabController }) {

            ForEach(this.tabBarContent, (item: ResourceStr) => {

              TabContent() {

                this.tabContentData()

              }

              .tabBar(this.tabBuilder(item))

            })

          }

          .vertical(false)

          .barWidth('100%')

        }

      }

      .scrollBar(BarState.Off)

    }

    .width('100%')

    .height('100%')

    .padding({ left: 16, right: 16 })

    .backgroundColor($r('sys.color.ohos_id_color_sub_background'))

  }

}
思路的话,就是滑动的Y的数据到达一定的位置时,通过控制器拉顶,可以写个动画

针对HarmonyOS 鸿蒙Next的滑动吸顶效果,以下是一个简要的demo说明:

在HarmonyOS中,虽然没有原生的吸顶效果API,但可以通过组合使用Stack、Scroll等组件及滚动事件回调函数来实现。

首先,使用Stack组件构建多层次堆叠的视觉效果,将需要吸顶的组件放置在Stack的顶部。然后,利用Scroll组件的滚动事件(如onScroll或onDidScroll)来捕获滚动动作,并根据滚动的偏移量实时调整吸顶组件的位置或属性。

具体实现时,可以监听Scroll组件的滚动事件,获取滚动的Y轴偏移量,并根据该偏移量动态调整吸顶组件的高度或透明度,使其在用户滚动页面时始终保持在屏幕顶部。同时,可以利用.nestedScroll属性来控制父级与子级Scroll组件之间的嵌套滚动效果,确保在滚动过程中吸顶组件能够正确显示。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部