HarmonyOS 鸿蒙Next--自定义ListStatusView:含首次进入骨架屏、空数据屏、错误重新请求屏、下拉加载、上拉刷新
HarmonyOS 鸿蒙Next–自定义ListStatusView:含首次进入骨架屏、空数据屏、错误重新请求屏、下拉加载、上拉刷新
0、自定义ListStatusView:含首次进入骨架屏、空数据屏、错误重新请求屏、下拉加载、上拉刷新
1、代码
```javascript
import { PullToRefresh } from '[@ohos](/user/ohos)/pulltorefresh';
import { R } from '[@ohos](/user/ohos)/res';
import { Constants } from '../../constants/Constants';
import { StyleConstants } from '../../constants/StyleConstants';
import { LoadingStatus } from '../../viewmodel/CommonEnums';
import { toast } from '../../utils/ToastUtils';
import { Logger } from '../../utils/Logger';
[@Component](/user/Component)
export struct ListStatusView {
[@Link](/user/Link) [@Watch](/user/Watch)("listDataChange") listData: object[];
[@Link](/user/Link) loadingStatus: LoadingStatus;
[@BuilderParam](/user/BuilderParam) customSkeletonView: () => void = this.baseSkeletonView;
[@BuilderParam](/user/BuilderParam) customFailureView: () => void = this.baseFailureView;
[@BuilderParam](/user/BuilderParam) customEmptyView: () => void = this.baseEmptyView;
[@BuilderParam](/user/BuilderParam) listView: () => void;
listScroller: Scroller = new Scroller();
[@State](/user/State) currentPage: number = 1;
getList?: (page: number) => void;
[@State](/user/State) columnOpacity: number = 1;
resolve: ((value: string | PromiseLike<string>) => void) | undefined = undefined;
aboutToAppear(): void {
if (this.getList) {
this.currentPage = 1
this.getList(this.currentPage)
}
}
listDataChange() {
setTimeout(() => {
if (this.resolve) {
this.resolve(this.currentPage === 1 ? '刷新完成了' : '')
}
}, 100)
}
startAnimation(): void {
animateTo(Constants.SKELETON_ANIMATION, () => {
this.columnOpacity = 0.5;
});
}
[@Builder](/user/Builder)
baseSkeletonView() {
Column() {
Text("AI-ERP")
.fontColor(R.color.color_ECECEC)
.fontSize(R.float.vp40)
.fontWeight(FontWeight.Bold)
}
.opacity(this.columnOpacity)
.onAppear(() => {
this.startAnimation();
})
}
[@Builder](/user/Builder)
baseFailureView() {
Row() {
Column() {
Image($r('app.media.ic_failure'))
.width(R.float.vp120)
.height(R.float.vp120)
Text(R.string.str_load_failed)
.fontColor(R.color.color_reload_title_color)
.fontFamily(StyleConstants.HARMONY_HEI_TI_FONT_FAMILY)
.fontSize(R.float.fp14)
.margin({ top: R.float.vp8 })
Button(R.string.str_reload)
.height(R.float.vp32)
.fontColor(R.color.color_main_red_color)
.fontFamily(StyleConstants.HARMONY_HEI_TI_FONT_FAMILY)
.fontSize(R.float.fp12)
.backgroundColor(Color.Transparent)
.margin({ top: R.float.vp8 })
.borderWidth(1)
.borderColor(R.color.color_main_red_color)
.borderRadius(R.float.vp16)
.onClick(() => {
if (this.getList) {
this.currentPage = 1;
this.getList(this.currentPage)
}
})
}
}
.justifyContent(FlexAlign.Center)
}
[@Builder](/user/Builder)
baseEmptyView() {
List({ space: 0, scroller: this.listScroller }) {
ListItem() {
Column() {
Image(R.media.ic_empty)
.size({ width: R.float.vp120, height: R.float.vp120 })
Text(R.string.str_empty_data)
.fontColor("#DCDBDB")
.fontSize(R.float.fp18)
.margin({
top: 10
})
}
.justifyContent(FlexAlign.Center)
}
.width(Constants.FULL_PARENT)
.height(Constants.FULL_PARENT)
}
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.None) // 必须设置列表为滑动到边缘无效果
.backgroundColor(R.color.colorPageBG)
.width(Constants.FULL_PARENT)
.layoutWeight(1)
}
build() {
Stack() {
if (this.loadingStatus === LoadingStatus.LOADING) {
this.customSkeletonView() // 骨架屏
}
if (this.loadingStatus === LoadingStatus.FAILED) {
this.customFailureView() // 错误屏
}
if (this.loadingStatus === LoadingStatus.SUCCESS || this.loadingStatus === LoadingStatus.NO_MORE) { // 加载完成或者是最后一页
PullToRefresh({
data: this.listData,
scroller: this.listScroller,
customList: () => {
if (this.listData.length === 0) {
this.customEmptyView() //
} else {
this.listView()
}
},
onRefresh: () => {
return new Promise<void>((resolve, reject) => {
this.currentPage = 1;
if (this.getList) {
this.getList(this.currentPage)
}
this.resolve = resolve
});
},
onLoadMore: () => {
return new Promise<void>((resolve, reject) => {
if (this.loadingStatus === LoadingStatus.NO_MORE) {
setTimeout(() => {
toast("没有更多数据了")
resolve('')
}, 500)
return
}
this.currentPage += 1;
if (this.getList) {
this.getList(this.currentPage)
}
this.resolve = resolve
});
},
customLoad: null,
customRefresh: null,
})
.width(StyleConstants.FULL_PERCENT)
.layoutWeight(1)
}
}
.layoutWeight(1)
}
}
1、调用
ListStatusView({
loadingStatus: this.loadingStatus,
listData: this.listData,
getList: (page): void => {
// 请求列表数据
this.workModel.getCCList(page)
.then((res: ApplyListBean[]) => {
this.listData = res
this.loadingStatus = this.workModel.loadingStatus
})
},
listView: () => {
this.listViewBuilder();
},
listScroller: this.scroller
})
更多关于HarmonyOS 鸿蒙Next--自定义ListStatusView:含首次进入骨架屏、空数据屏、错误重新请求屏、下拉加载、上拉刷新的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS 鸿蒙Next--自定义ListStatusView:含首次进入骨架屏、空数据屏、错误重新请求屏、下拉加载、上拉刷新的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
针对帖子标题“HarmonyOS 鸿蒙Next–自定义ListStatusView:含首次进入骨架屏、空数据屏、错误重新请求屏、下拉加载、上拉刷新”的问题,以下回答专注于鸿蒙系统相关的技术实现,不涉及Java或C语言内容:
在HarmonyOS中自定义一个包含首次进入骨架屏、空数据屏、错误重新请求屏、下拉加载和上拉刷新功能的ListStatusView,可以通过以下步骤实现:
-
定义自定义组件:首先,创建一个自定义组件类,继承自合适的容器组件,如
DependentLayout
。 -
状态管理:在自定义组件内部,定义一个枚举或常量类来表示不同的状态(骨架屏、空数据、错误、正常)。
-
布局管理:根据当前状态,动态显示或隐藏相应的布局。例如,首次进入时显示骨架屏布局,数据为空时显示空数据布局,请求出错时显示错误布局。
-
事件监听:为下拉刷新和上拉加载功能添加事件监听器,当用户触发这些动作时,调用相应的方法来处理数据加载。
-
数据请求与更新:在数据请求成功后,更新组件状态并刷新数据列表;在请求失败时,显示错误布局并提供重新请求的接口。
-
动画效果:为骨架屏添加动画效果以提升用户体验。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html,