HarmonyOS 鸿蒙Next中如何自定义上拉加载功能

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

HarmonyOS 鸿蒙Next中如何自定义上拉加载功能 希望可以自定义上滑加载功能 需求:页面支持下拉放大背景图+上滑加载更多数据。UI结构如下

  • List
  • ListItem(背景图)
  • ListItem(用户信息)
  • ListItem
  • Tabs组件
  • TabContent
  • Grid

部分代码

Refresh({ refreshing: $$this.isRefresh, offset: 0, builder: EmptyRefreshLoadingBuilder() }) {

  List({ scroller: this.listScroller }) {
    // 封面图,用于跟随页面向上滚动消失
    if (this.myModel!.userInfoData.cover_img_url) {

      ListItem() {
        Image()
          .size({ height: this.topRectHeight + 100, width: '100%' })
          .objectFit(ImageFit.Cover)
          .margin({ top: -20 })
          .visibility(this.showScrollBgImage ? Visibility.Visible : Visibility.Hidden)
      }
    }

    ListItem() {
      UserInfoView({
        userInfo: this.myModel!.userInfoData,
        userSummary: this.myModel!.userSummaryData
      })
        .margin({ top: -45 })
    }

    ListItem() {
      TabsView({
        model: this.myModel!,
      })
    }
  }
  .nestedScroll(this.myModel?.nestedScroll)
  .edgeEffect(EdgeEffect.None)
  .onScrollFrameBegin((offset) => {
    const yOffset: number = this.listScroller.currentOffset().yOffset;
    this.scrollYOffset = yOffset;
    return {
      offsetRemain: offset
    }
  })
  .onScrollStop(() => {
    const yOffset: number = this.listScroller.currentOffset().yOffset;
    this.scrollYOffset = yOffset;
  })
}
.height('100%')
.width('100%')
.onRefreshing(async () => {
  // 下拉不需要执行操作,直接关闭下拉状态
  this.isRefresh = false
})
.onOffsetChange((value: number) => {
  this.refreshYOffset = value;
})
.visibility(this.myModel!.loadingStatus === LoadingStatus.SUCCESS ? Visibility.Visible : Visibility.Hidden)

下拉放大背景图功能,通过Refresh的onOffsetChange事件实现了。

但是上滑加载更多数据不知道怎么实现。

尝试过使用@ohos/pulltorefresh和@abner/refresh,都无法满足需求。

希望提供一份实现上滑加载功能的UI和逻辑demo。


更多关于HarmonyOS 鸿蒙Next中如何自定义上拉加载功能的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

可以参考一下下面的demo

import { PullToRefresh, PullToRefreshConfigurator } from '@ohos/pulltorefresh'

const tabsList = ["能源", "化工", "塑料", "化纤", "聚氨酯"]

@Entry
@Component
struct KeyboadPage {
  private refreshScroller: Scroller = new Scroller();
  private refreshConfigurator: PullToRefreshConfigurator = new PullToRefreshConfigurator();
  @State list: Array<string> =
    ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t"]

  @State listH: number = 0

  onPageShow(): void {
    this.listH = this.list.length * 50 + 50
  }

  build() {
    Column() {
      PullToRefresh({
        // 必传项,列表组件所绑定的数据
        data: $list,
        refreshConfigurator: this.refreshConfigurator,
        // 必传项,需绑定传入主体布局内的列表或宫格组件
        scroller: this.refreshScroller,
        // 必传项,自定义主体布局,内部有列表或宫格组件
        customList: () => {
          // 一个用@Builder修饰过的UI方法
          this.getListView();
        },
        // 可选项,下拉刷新回调
        onRefresh: () => {
          return new Promise<(resolve, reject) => {
            // 模拟网络请求操作,请求网络2秒后得到数据,通知组件,变更列表数据
            setTimeout(() => {
              resolve('刷新成功');
              console.info('刷新成功');
            }, 2000);
          });
        },

        // 可选项,上拉加载更多回调
        onLoadMore: () => {
          return new Promise<(resolve, reject) => {
            // 模拟网络请求操作,请求网络2秒后得到数据,通知组件,变更列表数据
            setTimeout(() => {
              resolve('');
              console.info('加载成功');
            }, 2000);
          });
        },
        customLoad: null,
        customRefresh: null,
      })
        .layoutWeight(1)

    }
  }

  @Builder
  getListView() {

    Column() {
      List({ scroller: this.refreshScroller }) {
        ListItem() {
          Text("第一条")
            .width("100%")
            .height(300)
            .backgroundColor(Color.Red)
        }

        ListItem() {
          Text("第二条")
            .width("100%")
            .height(500)
            .backgroundColor(Color.Yellow)
        }

        ListItem() {
          Text("第三条")
            .width("100%")
            .height(200)
            .backgroundColor(Color.Green)
        }
      }
      .edgeEffect(EdgeEffect.None)
      .nestedScroll({
        scrollForward: NestedScrollMode.PARENT_FIRST,
        scrollBackward: NestedScrollMode.SELF_FIRST
      })
    }
  }

  @Builder
  watchingTabBuilder(index: number, item: string) {
    Text(item)
      .fontSize(16)
      .fontColor("#121212")
      .padding({
        left: 15,
        right: 15,
        top: 12,
        bottom: 12
      })
      .borderRadius(5)
  }
}

更多关于HarmonyOS 鸿蒙Next中如何自定义上拉加载功能的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS(鸿蒙Next)中,自定义上拉加载功能可以通过使用ListContainer组件和ScrollView组件来实现。首先,确保你已经导入了相关的鸿蒙开发库。

  1. 使用ListContainer组件:

    • ListContainer组件支持分页加载。你可以通过监听ListContainer的滚动事件来判断是否到达底部,然后触发加载更多数据的操作。
    • ListContaineronScrollStateChanged回调中,判断当前滚动状态是否为SCROLL_STATE_IDLE,并且判断是否已经滚动到底部。如果满足条件,则可以执行加载更多数据的逻辑。
  2. 使用ScrollView组件:

    • ScrollView组件也可以实现上拉加载。你可以在ScrollView的子布局中添加一个加载更多的视图,并通过监听ScrollView的滚动事件来判断是否到达底部。
    • ScrollViewonScrollChanged回调中,判断当前滚动位置是否接近底部。如果接近底部,则可以触发加载更多数据的操作。
  3. 自定义加载视图:

    • 你可以在布局文件中定义一个加载更多的视图,例如一个ProgressBar和一个TextView,用于显示加载中的状态。
    • 在代码中,通过控制这个视图的显示和隐藏,来实现加载更多数据时的UI反馈。
  4. 数据加载逻辑:

    • 在触发加载更多数据时,通常需要在后台线程中执行网络请求或数据库查询操作,然后将新数据添加到现有的数据集合中。
    • 在数据加载完成后,通知UI线程更新ListContainerScrollView的内容。

通过以上步骤,你可以在HarmonyOS中实现自定义的上拉加载功能。

在HarmonyOS鸿蒙Next中,自定义上拉加载功能可以通过ListContainerRecyclerView组件实现。首先,监听滚动事件,当用户滚动到底部时触发加载操作。可以使用OnScrollListener检测滚动位置,结合RecyclerView.Adapter动态加载更多数据并更新UI。同时,建议添加加载动画或提示,提升用户体验。具体实现可参考以下步骤:

  1. RecyclerViewListContainer中设置OnScrollListener
  2. 判断是否滚动到底部,触发加载逻辑。
  3. Adapter中处理数据加载,并调用notifyDataSetChanged()更新列表。
  4. 添加加载动画或提示信息。
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!