文章目录
一、加载更多
借助List
的onReachEnd
方法,实现加载更多功能,效果如下:
ts
@Component
export struct HPList {
// 数据源
@Prop dataSource: object[] = []
// 加载更多是否ing
@State isLoadingMore: boolean = false
// 是否还有更多
@Prop hasMore: boolean = false
// 渲染Item
@BuilderParam renderItem: (item: object) => void
// 加载更多回调
onLoadMore: () => void = () => {
}
// 加载更多文案
loadingMoreText: string = '加载中...'
// 没有更多文案
noMoreDataText: string = '没有更多啦'
@Builder
getLoadMoreView() {
Row() {
if (!this.hasMore) {
Text(this.noMoreDataText)
.fontSize(14)
.fontColor($r('app.color.text_secondary'))
} else {
Row({ space: 8 }) {
LoadingProgress()
.width(30)
.height(30)
.color(Color.Orange)
Text(this.loadingMoreText)
.fontSize(14)
.fontColor($r('app.color.text_secondary'))
}
}
}
.height(60)
.width('100%')
.justifyContent(FlexAlign.Center)
}
build() {
List() {
ForEach(this.dataSource, (item: object) => {
ListItem() {
if (this.renderItem) {
this.renderItem(item)
}
}
})
// 加载更多view
ListItem() {
this.getLoadMoreView()
}
}
.onReachEnd(async () => {
if (!this.isLoadingMore && this.hasMore) {
this.isLoadingMore = true
await this.onLoadMore()
this.isLoadingMore = false
}
})
}
}
使用:
ts
import { HPList } from '@hp/basic'
import { promptAction } from '@kit.ArkUI'
@Preview
@Component
export struct Task {
// 模拟数据
@State dataList: Person[] = [{
name: '1'
}, {
name: '2'
}, {
name: '3'
}, {
name: '4'
}, {
name: '5'
}, {
name: '6'
}, {
name: '7'
}, {
name: '8'
}, {
name: '9'
}, {
name: '10'
}, {
name: '11'
}, {
name: '12'
}]
@State hasMore: boolean = true
isFirstIn: boolean = true
@Builder
renderItem(item: object) {
Row() {
Text(JSON.stringify(item))
.fontSize(16)
.textAlign(TextAlign.Center)
}
.width('100%')
.height(80)
.borderRadius(15)
.backgroundColor(Color.Pink)
.justifyContent(FlexAlign.Center)
.margin({ bottom: 10 })
}
/**
* 加载更多
*/
async loadMore() {
// 首次渲染数据为空时,也会调loadMore
if (this.isFirstIn) {
this.isFirstIn = false
return
}
await new Promise<void>((resolve, reject) => {
setTimeout(() => {
// 模拟数据
this.dataList = this.dataList.concat(this.dataList.slice(5))
if (this.dataList.length > 30) {
this.hasMore = false
}
resolve()
}, 3000)
});
}
build() {
HPList({
dataSource: this.dataList,
hasMore: this.hasMore,
renderItem: (item: object) => {
this.renderItem(item)
},
onLoadMore: () => {
this.loadMore()
}
})
}
}
class Person {
name: string = ''
}
二、下拉刷新
通过Refresh
实现下拉刷新,并自定义头部,效果如下:
代码如下:
ts
import { promptAction } from '@kit.ArkUI'
@Component
export struct HPList {
// 数据源
@Prop dataSource: object[] = []
// 加载更多是否ing
@State isLoadingMore: boolean = false
// 是否还有更多
@Prop hasMore: boolean = false
// 渲染Item
@BuilderParam renderItem: (item: object) => void
// 加载更多回调
onLoadMore: () => void = () => {
}
// 加载更多文案
loadingMoreText: string = '加载中...'
// 没有更多文案
noMoreDataText: string = '没有更多啦'
// 是否下拉刷新ing
@State isRefreshing: boolean = false
// 下拉刷新回调
onRefresh: () => void = () => {
}
@State refreshState: RefreshStatus = RefreshStatus.Inactive
// 获取下拉文本
getStatusText() {
switch (this.refreshState) {
case RefreshStatus.Inactive:
return ""
case RefreshStatus.Drag:
return "继续下拉"
case RefreshStatus.OverDrag:
return "松开刷新"
case RefreshStatus.Refresh:
return "加载中"
}
return ""
}
@Builder
getRefreshView() {
Row({ space: 10 }) {
LoadingProgress()
.color($r('app.color.primary'))
.width(40)
.height(40)
Text(this.getStatusText())
.fontColor($r('app.color.text_secondary'))
.fontSize(14)
}
.justifyContent(FlexAlign.Center)
.height(50)
.width('100%')
}
@Builder
getLoadMoreView() {
Row() {
if (!this.hasMore) {
Text(this.noMoreDataText)
.fontSize(14)
.fontColor($r('app.color.text_secondary'))
} else {
Row({ space: 8 }) {
LoadingProgress()
.width(30)
.height(30)
.color(Color.Orange)
Text(this.loadingMoreText)
.fontSize(14)
.fontColor($r('app.color.text_secondary'))
}
}
}
.height(60)
.width('100%')
.justifyContent(FlexAlign.Center)
}
build() {
Refresh({ refreshing: $$this.isRefreshing, builder: this.getRefreshView() }) {
List() {
ForEach(this.dataSource, (item: object) => {
ListItem() {
if (this.renderItem) {
this.renderItem(item)
}
}
})
// 加载更多view
ListItem() {
this.getLoadMoreView()
}
}
.onReachEnd(async () => {
if (!this.isLoadingMore && this.hasMore) {
this.isLoadingMore = true
await this.onLoadMore()
this.isLoadingMore = false
}
})
}
.onStateChange(async (state) => {
this.refreshState = state
if (state === RefreshStatus.Refresh) {
await this.onRefresh()
this.isRefreshing = false
}
})
}
}
使用:
ts
import { HPList } from '@hp/basic'
import { promptAction } from '@kit.ArkUI'
@Preview
@Component
export struct Task {
// 模拟数据
@State dataList: Person[] = [{
name: '1'
}, {
name: '2'
}, {
name: '3'
}, {
name: '4'
}, {
name: '5'
}, {
name: '6'
}, {
name: '7'
}, {
name: '8'
}, {
name: '9'
}, {
name: '10'
}, {
name: '11'
}, {
name: '12'
}]
@State hasMore: boolean = true
isFirstIn: boolean = true
@Builder
renderItem(item: object) {
Row() {
Text(JSON.stringify(item))
.fontSize(16)
.textAlign(TextAlign.Center)
}
.width('100%')
.height(80)
.borderRadius(15)
.backgroundColor(Color.Pink)
.justifyContent(FlexAlign.Center)
.margin({ bottom: 10 })
}
async onRefresh() {
await new Promise<void>((resolve, reject) => {
setTimeout(() => {
this.dataList = [{
name: '旺财'
},
{
name: '张三'
}, {
name: '李四'
}, {
name: '王五'
},
{
name: '张三1'
}, {
name: '李四1'
}, {
name: '王五1'
},
{
name: '张三2'
}, {
name: '李四2'
}, {
name: '王五2'
}]
resolve()
}, 3000)
});
}
/**
* 加载更多
*/
async loadMore() {
// 首次渲染数据为空时,也会调loadMore
if (this.isFirstIn) {
this.isFirstIn = false
return
}
promptAction.showToast({ message: 'opppp' })
await new Promise<void>((resolve, reject) => {
setTimeout(() => {
// 模拟数据
this.dataList = this.dataList.concat(this.dataList.slice(5))
if (this.dataList.length > 30) {
this.hasMore = false
}
resolve()
}, 3000)
});
}
build() {
HPList({
dataSource: this.dataList,
hasMore: this.hasMore,
renderItem: (item: object) => {
this.renderItem(item)
},
onLoadMore:async () => {
await this.loadMore()
},
onRefresh: async () => {
await this.onRefresh()
}
})
}
}
class Person {
name: string = ''
}
三、小结
- 下拉刷新Refresh及自定义组件
- 加载更多及自定义组件