HarmonyOS APP开发—"新鲜事"社交动态App,需要用到这个库

做一个社交动态 App,信息流要下拉刷新最新动态、上拉加载历史内容。ArkUI 原生 List 不带这套交互——@ohos/pulltorefresh 一个组件包住 List,下拉上拉全搞定,还支持自定义动画。

📦 仓库地址:https://gitcode.com/CPF-ApplicationTPC/ohos_pull_to_refresh | 安装:ohpm install @ohos/pulltorefresh


写在前面

"新鲜事"是一个社交动态 App,核心页面就是信息流:用户下拉刷新看最新动态,滑到底部上拉加载更早的内容。这个交互在微信朋友圈、微博、抖音里都是标配。

但 ArkUI 原生的 List / Scroll / Grid / WaterFlow 组件本身不带下拉刷新和上拉加载能力。如果你自己监听手势 + 写动画 + 处理数据加载,每个列表都要重复写一遍。

@ohos/pulltorefresh 用一个组件把你的列表"包"起来:

  • 下拉刷新onRefresh 回调返回 Promise,resolve 后动画收起
  • 上拉加载onLoadMore 回调返回 Promise,resolve 后加载状态消失
  • 5 大容器支持:List / Scroll / Tabs / Grid / WaterFlow
  • 自定义动画:内置精美动画,也可以完全自定义刷新/加载视图
  • LazyForEach 兼容:长列表懒加载性能不打折

这篇文章聊什么

  1. 基础信息流——PullToRefresh + List + 下拉/上拉
  2. 自定义动画——替换内置刷新动画
  3. V2 组件——@ComponentV2 新写法

下拉

滑到底部

信息流页面

PullToRefresh 包住 List

用户手势

onRefresh 回调

请求最新动态

resolve 收起动画

更新列表数据

onLoadMore 回调

请求历史动态

resolve 收起加载

追加到列表尾部


第一步:安装

ohpm install @ohos/pulltorefresh

第二步:信息流下拉刷新 + 上拉加载

import { PullToRefresh } from '@ohos/pulltorefresh'

@Entry
@Component
struct FeedPage {
  private scroller: Scroller = new Scroller()
  @State feedList: string[] = ['动态1', '动态2', '动态3']
  private page: number = 1

  build() {
    PullToRefresh({
      // 必传:列表数据
      data: $feedList,
      // 必传:列表容器
      scroller: this.scroller,
      // 必传:自定义主体布局
      customList: () => { this.getListView() },

      // 下拉刷新
      onRefresh: () => {
        return new Promise<string>((resolve) => {
          // 请求最新动态
          fetchLatestFeed().then((data) => {
            this.feedList = data  // 替换列表
            this.page = 1
            resolve('刷新成功')     // 收起刷新动画
          })
        })
      },

      // 上拉加载更多
      onLoadMore: () => {
        return new Promise<string>((resolve) => {
          this.page++
          fetchMoreFeed(this.page).then((data) => {
            this.feedList = this.feedList.concat(data) // 追加到尾部
            resolve('')
          })
        })
      },
    })
  }

  @Builder
  getListView() {
    List({ scroller: this.scroller }) {
      ForEach(this.feedList, (item: string) => {
        ListItem() {
          // 每条动态的 UI
          Column({ space: 8 }) {
            Text(item).fontSize(16)
            Text('来自新鲜事').fontSize(12).fontColor('#999')
          }
          .width('100%').padding(16)
        }
      }, (item: string) => item)
    }
    .edgeEffect(EdgeEffect.None) // ⚠️ 必须设置!
  }
}

关键点

  • onRefresh / onLoadMore 都返回 Promise——组件内部根据 resolve 自动收/放动画
  • 容器的 edgeEffect 必须设为 EdgeEffect.None(否则弹簧效果冲突)
  • data 绑定让组件感知列表数据变化

第三步:自定义刷新动画

内置动画够用,但你也可以完全自定义:

PullToRefresh({
  data: $feedList,
  scroller: this.scroller,
  customList: () => { this.getListView() },
  onRefresh: () => { /* ... */ },
  onLoadMore: () => { /* ... */ },

  // 自定义下拉刷新视图(替换内置动画)
  customRefresh: () => {
    this.CustomRefreshView()
  },
  // 自定义上拉加载视图
  customLoad: () => {
    this.CustomLoadView()
  },
})

@Builder
CustomRefreshView() {
  Row({ space: 8 }) {
    LoadingProgress().width(24).height(24)
    Text('正在刷新新鲜事...').fontSize(14).fontColor('#4ECDC4')
  }
  .height(60)
  .justifyContent(FlexAlign.Center)
}

第四步:V2 组件写法(@ComponentV2)

鸿蒙新推荐 @ComponentV2 写法,PullToRefresh 也支持:

import { PullToRefreshV2 } from '@ohos/pulltorefresh'

@Entry
@ComponentV2
struct FeedPageV2 {
  private scroller: Scroller = new Scroller()
  @Local feedList: string[] = []

  build() {
    PullToRefreshV2({
      data: this.feedList,
      scroller: this.scroller,
      customList: () => { this.listView() },
      onRefresh: () => { /* ... */ },
      onLoadMore: () => { /* ... */ },
    })
  }

  @Builder
  listView() {
    List({ scroller: this.scroller }) {
      ForEach(this.feedList, (item: string) => {
        ListItem() { Text(item).height(80) }
      }, (item: string) => item)
    }
    .edgeEffect(EdgeEffect.None)
  }
}

为什么"新鲜事"选了 pulltorefresh?

需求自己手写@ohos/pulltorefresh
下拉刷新手势监听+动画✅ onRefresh 一行
上拉加载滚动监听+判断✅ onLoadMore 一行
List/Grid/WaterFlow每个容器各写✅ 5 大容器通用
自定义动画手写✅ customRefresh
LazyForEach需适配✅ 完美兼容
V2 组件✅ PullToRefreshV2

总结

"新鲜事"这个场景里,@ohos/pulltorefresh 解决了三件事:

  1. 下拉刷新——onRefresh 返回 Promise,请求完成自动收起动画
  2. 上拉加载——onLoadMore 返回 Promise,加载完成自动收起状态
  3. 5 大容器通用——List / Scroll / Tabs / Grid / WaterFlow 一个组件全包

如果你也在做信息流、商品列表、聊天记录等任何"滚动 + 分页"的场景,@ohos/pulltorefresh 让你 5 分钟搞定刷新加载,把精力留给内容本身。

Logo

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

更多推荐