首页、患者分组、审核、列表等

This commit is contained in:
xiaoxiao
2025-07-10 09:27:17 +08:00
parent 5954f51701
commit 4641e9ecee
136 changed files with 7577 additions and 171 deletions
+20
View File
@@ -0,0 +1,20 @@
import { PullStatus } from './PullStatus'
export interface PullDown {
/*是否是下拉*/
isPullDown: boolean
/*是否是上拉*/
isPullUp: boolean
/*是否触摸*/
isTouch: boolean
/*下拉距离*/
distance: number
/*上拉距离*/
distanceLoad: number
/*headerView高度*/
headerViewSize: number
/*footerView高度*/
footerViewSize: number
/*状态*/
status: PullStatus
}
+34
View File
@@ -0,0 +1,34 @@
export enum PullStatus {
/*0默认状态(无下拉距离)*/
DEF,
/***********************************下拉状态*******************************************/
/*1下拉状态*/
PullDown,
/*2下拉至可以刷新的状态(准备刷新)*/
PreRefresh,
/*3刷新中*/
Refresh,
/*4下拉超过刷新高度时准备打开其他页面*/
PreOpenPage,
/*5下拉超过刷新高度时松手打开其他页面*/
OpenPage,
/*6刷新成功*/
RefreshSuccess,
/*7刷新失败*/
RefreshError,
/***********************************上拉状态*******************************************/
/*8上拉状态*/
PullUp,
/*9上拉至可以加载的状态(准备加载)*/
PreLoad,
/*10加载中*/
Load,
/*11上拉超过加载高度时准备打开其他页面*/
PreLoadOpenPage,
/*12上拉超过加载高度时松手打开其他页面*/
LoadOpenPage,
/*13加载成功*/
LoadSuccess,
/*14加载失败*/
LoadError
}
@@ -0,0 +1,95 @@
export class PullToRefreshConfig {
/*刷新loading宽度*/
public refreshLoadingWidth: Length = 25
/*刷新loading高度*/
public refreshLoadingHeight: Length = 25
/*刷新loading颜色*/
public refreshLoadingColor: ResourceColor = "#333333"
/*下拉刷新箭头*/
public arrowImage: Resource = $r("app.media.icon_refresh_arrow")
/*下拉刷新箭头颜色*/
public arrowImageColor: ResourceColor = "#333333"
/*下拉刷新箭头宽度*/
public arrowImageWidth: Length = 20
/*下拉刷新箭头高度*/
public arrowImageHeight: Length = 20
/*上拉刷新箭头*/
public arrowLoadImage: Resource = $r("app.media.icon_refresh_arrow")
/*上拉刷新箭头颜色*/
public arrowLoadImageColor: ResourceColor = "#333333"
/*上拉刷新箭头宽度*/
public arrowLoadImageWidth: Length = 20
/*上拉刷新箭头高度*/
public arrowLoadImageHeight: Length = 20
/*暂无更多提示*/
public noMoreTips: string | Resource = $r("app.string.zr_load_no_more")
/*暂无更多提示大小*/
public noMoreTipsSize: number | string | Resource = 13
/*暂无更多提示颜色*/
public noMoreTipsColor: ResourceColor = "#666666"
/*暂无更多提示——横向列表*/
public noMoreTipsHorizontal: string | Resource = $r("app.string.h_zr_load_no_more")
/*是否显示刷新时间*/
public showRefreshTime: boolean = false
/*刷新时间tips大小*/
public refreshTimeTipsSize: number | string | Resource = 11
/*刷新时间tips颜色*/
public refreshTimeTipsColor: ResourceColor = "#999999"
/*下拉刷新提示*/
public pullDownTips: string | Resource = $r("app.string.zr_pull_down_to_refresh")
/*下拉刷新提示——横向列表*/
public pullDownTipsHorizontal: string | Resource = $r("app.string.h_zr_pull_down_to_refresh")
/*下拉刷新提示大小*/
public pullDownTipsSize: number | string | Resource = 13
/*下拉刷新提示颜色*/
public pullDownTipsColor: ResourceColor = "#666666"
/*释放立即刷新tips*/
public releaseRefreshTips: string | Resource = $r("app.string.zr_release_to_refresh")
/*释放立即刷新tips——横向列表*/
public releaseRefreshTipsHorizontal: string | Resource = $r("app.string.h_zr_release_to_refresh")
/*正在刷新tips*/
public refreshTips: string | Resource = $r("app.string.zr_refreshing")
/*正在刷新tips——横向列表*/
public refreshTipsHorizontal: string | Resource = $r("app.string.h_zr_refreshing")
/*刷新成功tips*/
public refreshSuccessTips: string | Resource = $r("app.string.zr_refresh_success")
/*刷新成功tips——横向列表*/
public refreshSuccessTipsHorizontal: string | Resource = $r("app.string.h_zr_refresh_success")
/*刷新失败tips*/
public refreshErrorTips: string | Resource = $r("app.string.zr_refresh_error")
/*刷新失败tips——横向列表*/
public refreshErrorTipsHorizontal: string | Resource = $r("app.string.h_zr_refresh_error")
/*下拉打开其他页面tips*/
public pullOpenPageTips: string | Resource = $r("app.string.zr_release_to_open_age")
/*下拉打开其他页面tips——横向列表*/
public pullOpenPageTipsHorizontal: string | Resource = $r("app.string.h_zr_release_to_open_age")
/*上拉加载提示*/
public pullUpTips: string | Resource = $r("app.string.zr_pull_up_to_load")
/*上拉加载提示——横向列表*/
public pullUpTipsHorizontal: string | Resource = $r("app.string.h_zr_pull_up_to_load")
/*上拉加载提示大小*/
public pullUpTipsSize: number | string | Resource = 13
/*上拉加载提示颜色*/
public pullUpTipsColor: ResourceColor = "#333333"
/*释放立即加载tips*/
public releaseLoadTips: string | Resource = $r("app.string.zr_release_to_load")
/*释放立即加载tips——横向列表*/
public releaseLoadTipsHorizontal: string | Resource = $r("app.string.h_zr_release_to_load")
/*正在加载tips*/
public loadTips: string | Resource = $r("app.string.zr_loading")
/*正在加载tips——横向列表*/
public loadTipsHorizontal: string | Resource = $r("app.string.h_zr_loading")
/*加载成功tips*/
public loadSuccessTips: string | Resource = $r("app.string.zr_load_success")
/*加载成功tips——横向列表*/
public loadSuccessTipsHorizontal: string | Resource = $r("app.string.h_zr_load_success")
/*加载失败tips*/
public loadErrorTips: string | Resource = $r("app.string.zr_load_error")
/*加载失败tips——横向列表*/
public loadErrorTipsHorizontal: string | Resource = $r("app.string.h_zr_load_error")
/*下拉打开其他页面tips*/
public loadOpenPageTips: string | Resource = $r("app.string.zr_release_to_open_age")
}
@@ -0,0 +1,806 @@
import { PullDown } from './PullDown';
import { PullStatus } from './PullStatus';
import { RefreshController } from './RefreshController';
import { RefreshLayout } from './RefreshLayout';
import { RefreshLayoutConfig } from './RefreshLayoutConfig';
import { _ContentView } from './RefreshLayoutHelper';
import web from '@ohos.web.webview';
import preferences from '@ohos.data.preferences';
import { PullToRefreshConfig } from './PullToRefreshConfig';
@ComponentV2
export struct PullToRefreshLayout {
/*下拉箭头旋转角度*/
@Local arrowRotate: number = 0;
/*上拉箭头旋转角度*/
@Local arrowRotateLoad: number = 180;
@Local status: PullStatus = PullStatus.DEF
/********************************************************************************************************/
@Param public pullConfig: PullToRefreshConfig = new PullToRefreshConfig()
/*记录组件刷新时间*/
@Param public viewKey: string = ""
@Param public scroller: Scroller | undefined = undefined
@Param public webviewController: web.WebviewController | undefined = undefined
@Param public controller: RefreshController = new RefreshController()
/*是否可以下拉*/
@Param public onCanPullRefresh: () => boolean = () => true
/*是否可以下拉*/
@Param public onCanPullLoad: () => boolean = () => false
/*刷新通知*/
@Param public onRefresh: () => void = () => {
}
/*刷新通知*/
@Param public onLoad: () => void = () => {
}
/*打开页面通知*/
@Param public onOpenPage: () => void = () => {
}
/*打开页面通知*/
@Param public onLoadOpenPage: () => void = () => {
}
/*下拉状态监听*/
@Param public onPullListener: (pullDown: PullDown) => void = () => {
}
//内容视图
@BuilderParam contentView: () => void = _ContentView
//loading视图
@BuilderParam headerLoadIngView?: () => void
//loading视图
@BuilderParam footerLoadIngView?: () => void
/*下拉刷新配置*/
@Param public config: RefreshLayoutConfig = new RefreshLayoutConfig()
//正在加载视图
@BuilderParam viewLoading?: () => void
//空视图
@BuilderParam viewEmpty?: () => void
//加载错误视图
@BuilderParam viewError?: () => void
//无网络视图
@BuilderParam viewNoNetwork?: () => void
/********************************************************************************************************/
aboutToAppear(): void {
this.resetArrowRotate()
this.resetArrowRotateLoad()
}
/*************垂直列表和水平列表feader视图箭头角度**************/
private isPullRotate(): boolean {
if (this.isVerticalLayout()) {
return this.arrowRotate == 0
} else {
return this.arrowRotate == -90
}
}
private isPreRefreshRotate(): boolean {
if (this.isVerticalLayout()) {
return this.arrowRotate == 180
} else {
return this.arrowRotate == 90
}
}
private setPreRefreshRotate() {
if (this.isVerticalLayout()) {
this.arrowRotate = 180
} else {
this.arrowRotate = 90
}
}
private resetArrowRotate() {
if (this.isVerticalLayout()) {
this.arrowRotate = 0
} else {
this.arrowRotate = -90
}
}
/*************垂直列表和水平列表footer视图箭头角度**************/
private isPullLoadRotate(): boolean {
if (this.isVerticalLayout()) {
return this.arrowRotateLoad == 180
} else {
return this.arrowRotateLoad == 90
}
}
private isPreLoadRotate(): boolean {
if (this.isVerticalLayout()) {
return this.arrowRotateLoad == 0
} else {
return this.arrowRotateLoad == -90
}
}
private setPreLoadRotate() {
if (this.isVerticalLayout()) {
this.arrowRotateLoad = 180
} else {
this.arrowRotateLoad = 90
}
}
private resetArrowRotateLoad() {
if (this.isVerticalLayout()) {
this.arrowRotateLoad = 0
} else {
this.arrowRotateLoad = -90
}
}
build() {
RefreshLayout({
scroller: this.scroller,
webviewController: this.webviewController,
controller: this.controller,
config: this.config,
headerView: () => {
if (this.isVerticalLayout()) {
this.defHeaderView()
} else {
this.defHeaderViewHorizontal()
}
},
onCanPullRefresh: () => {
return this.onCanPullRefresh()
},
onCanPullLoad: () => {
return this.onCanPullLoad()
},
onRefresh: () => {
this.onRefresh()
},
onLoad: () => {
this.onLoad()
},
onOpenPage: () => {
this.onOpenPage()
},
onLoadOpenPage: () => {
this.onLoadOpenPage()
},
contentView: () => {
this.contentView()
},
loadView: () => {
if (this.isVerticalLayout()) {
this.defFooterView()
} else {
this.defFooterViewHorizontal()
}
},
noMoreView: () => {
if (this.isVerticalLayout()) {
this.defFooterNoMoreView()
} else {
this.defFooterNoMoreViewHorizontal()
}
},
onPullListener: (pullDown: PullDown) => {
this.status = pullDown.status
this.updateRefreshTime(this.status)
this.onPullListener?.(pullDown)
if (this.config.pullHeaderHeightRefresh <= pullDown.headerViewSize) {
this.config.pullHeaderHeightRefresh = pullDown.headerViewSize * 1.5
}
if (this.config.pullHeaderHeightOpenPage <= this.config.pullHeaderHeightRefresh) {
this.config.pullHeaderHeightOpenPage = pullDown.headerViewSize * 2.6
}
if (this.config.pullFooterHeightLoad <= pullDown.footerViewSize) {
this.config.pullFooterHeightLoad = pullDown.footerViewSize * 1.1
}
if (this.config.pullFooterHeightOpenPage <= this.config.pullFooterHeightLoad) {
this.config.pullFooterHeightOpenPage = pullDown.footerViewSize * 2.6
}
if (this.status == PullStatus.PullDown) {
if (this.isPullRotate()) {
return
}
/*进入下拉状态*/
animateTo({ duration: 10, curve: Curve.Linear }, () => {
this.resetArrowRotate()
})
} else if (this.status == PullStatus.PreRefresh) {
if (this.isPreRefreshRotate()) {
return
}
/*进入释放刷新状态*/
animateTo({ duration: 150, curve: Curve.Linear }, () => {
this.setPreRefreshRotate()
})
} else if (this.status == PullStatus.PullUp) {
if (this.isPullLoadRotate()) {
return
}
/*进入上拉状态*/
animateTo({ duration: 10, curve: Curve.Linear }, () => {
this.setPreLoadRotate()
})
} else if (this.status == PullStatus.PreLoad) {
if (this.isPreLoadRotate()) {
return
}
/*进入释放加载状态*/
animateTo({ duration: 150, curve: Curve.Linear }, () => {
this.resetArrowRotateLoad()
})
}
},
/*正在加载视图*/
viewLoading: this.viewLoading,
/*空数据视图*/
viewEmpty: this.viewEmpty,
/*加载失败视图*/
viewError: this.viewError,
/*无网络视图*/
viewNoNetwork: this.viewNoNetwork
}).clip(true)
}
private isVerticalLayout(): boolean {
return (this.config.isVertical || this.config.horizontalMode == 1 || this.config.horizontalMode == 2)
}
@Local private zrLastUpdate: string = getContext().resourceManager.getStringByNameSync(("zr_last_update"))
@Builder
defHeaderViewHorizontal() {
RelativeContainer() {
Stack() {
Image(this.pullConfig.arrowImage)
.width(this.pullConfig.arrowImageWidth)
.height(this.pullConfig.arrowImageHeight)
.visibility(this.getPullArrowVisibility())
.fillColor(this.pullConfig.arrowImageColor)
.margin({ top: 5 })
.rotate({
x: 0,
y: 0,
z: 1,
angle: this.arrowRotate
})
if (this.headerLoadIngView) {
Stack() {
this.headerLoadIngView()
}
.visibility(this.getRefreshVisibility())
} else {
LoadingProgress()
.color(this.pullConfig.refreshLoadingColor)
.width(this.pullConfig.refreshLoadingWidth)
.height(this.pullConfig.refreshLoadingHeight)
.visibility(this.getRefreshVisibility())
}
}.alignRules({
top: { anchor: "title", align: VerticalAlign.Bottom },
middle: { anchor: "__container__", align: HorizontalAlign.Center }
}).id("arrow")
Row() {
Text(this.getTips())
.fontSize(this.pullConfig.pullDownTipsSize)
.fontColor(this.pullConfig.pullDownTipsColor)
.textAlign(TextAlign.Center)
Text(this.zrLastUpdate)
.fontSize(this.pullConfig.refreshTimeTipsSize)
.fontColor(this.pullConfig.refreshTimeTipsColor)
.margin({ left: 2 })
.visibility(this.pullConfig.showRefreshTime ? this.getTimeTipsVisibility() : Visibility.None)
.textAlign(TextAlign.Center)
}.id("title").alignRules({
middle: { anchor: "__container__", align: HorizontalAlign.Center },
center: { anchor: "__container__", align: VerticalAlign.Center }
}).alignItems(VerticalAlign.Center)
}.width(50).height("100%")
}
@Builder
defHeaderView() {
RelativeContainer() {
Stack() {
Image(this.pullConfig.arrowImage)
.width(this.pullConfig.arrowImageWidth)
.height(this.pullConfig.arrowImageHeight)
.visibility(this.getPullArrowVisibility())
.fillColor(this.pullConfig.arrowImageColor)
.margin({ right: 10 })
.rotate({
x: 0,
y: 0,
z: 1,
angle: this.arrowRotate
})
if (this.headerLoadIngView) {
Stack() {
this.headerLoadIngView()
}
.visibility(this.getRefreshVisibility())
} else {
LoadingProgress()
.color(this.pullConfig.refreshLoadingColor)
.width(this.pullConfig.refreshLoadingWidth)
.height(this.pullConfig.refreshLoadingHeight)
.visibility(this.getRefreshVisibility())
}
}.alignRules({
right: { anchor: "title", align: HorizontalAlign.Start },
center: { anchor: "__container__", align: VerticalAlign.Center }
}).id("arrow")
Column() {
Text(this.getTips()).fontSize(this.pullConfig.pullDownTipsSize)
.fontColor(this.pullConfig.pullDownTipsColor)
Text(this.zrLastUpdate).fontSize(this.pullConfig.refreshTimeTipsSize)
.fontColor(this.pullConfig.refreshTimeTipsColor).margin({ top: 2 })
.visibility(this.pullConfig.showRefreshTime ? this.getTimeTipsVisibility() : Visibility.None)
}.id("title").alignRules({
middle: { anchor: "__container__", align: HorizontalAlign.Center },
center: { anchor: "__container__", align: VerticalAlign.Center }
}).constraintSize({ minWidth: 80 }).alignItems(HorizontalAlign.Center)
}.height(50).width("100%")
}
@Builder
defFooterViewHorizontal() {
RelativeContainer() {
Stack() {
Image(this.pullConfig.arrowLoadImage)
.width(this.pullConfig.arrowLoadImageWidth)
.height(this.pullConfig.arrowLoadImageHeight)
.visibility(this.getPullUpArrowVisibility())
.fillColor(this.pullConfig.arrowLoadImageColor)
.margin({ top: 5 })
.rotate({
x: 0,
y: 0,
z: 1,
angle: this.arrowRotateLoad
})
if (this.footerLoadIngView) {
Stack() {
this.footerLoadIngView()
}
.visibility(this.getLoadVisibility())
} else {
LoadingProgress()
.color(this.pullConfig.refreshLoadingColor)
.width(this.pullConfig.refreshLoadingWidth)
.height(this.pullConfig.refreshLoadingHeight).visibility(this.getLoadVisibility())
}
}.alignRules({
top: { anchor: "title", align: VerticalAlign.Bottom },
middle: { anchor: "__container__", align: HorizontalAlign.Center }
}).id("arrow")
Row() {
Text(this.getLoadTips())
.fontSize(this.pullConfig.pullUpTipsSize)
.fontColor(this.pullConfig.pullUpTipsColor)
.textAlign(TextAlign.Center)
}.id("title").alignRules({
middle: { anchor: "__container__", align: HorizontalAlign.Center },
center: { anchor: "__container__", align: VerticalAlign.Center }
}).alignItems(VerticalAlign.Center)
}.width(50).height("100%")
}
@Builder
defFooterNoMoreViewHorizontal() {
Text(this.pullConfig.noMoreTipsHorizontal)
.textAlign(TextAlign.Center)
.height("100%")
.width(50)
.fontSize(this.pullConfig.noMoreTipsSize)
.fontColor(this.pullConfig.noMoreTipsColor)
}
@Builder
defFooterView() {
RelativeContainer() {
Stack() {
Image(this.pullConfig.arrowLoadImage)
.width(this.pullConfig.arrowLoadImageWidth)
.height(this.pullConfig.arrowLoadImageHeight)
.visibility(this.getPullUpArrowVisibility())
.fillColor(this.pullConfig.arrowLoadImageColor)
.margin({ right: 10 })
.rotate({
x: 0,
y: 0,
z: 1,
angle: this.arrowRotateLoad
})
if (this.footerLoadIngView) {
Stack() {
this.footerLoadIngView()
}
.visibility(this.getLoadVisibility())
} else {
LoadingProgress()
.color(this.pullConfig.refreshLoadingColor)
.width(this.pullConfig.refreshLoadingWidth)
.height(this.pullConfig.refreshLoadingHeight)
.visibility(this.getLoadVisibility())
}
}.alignRules({
right: { anchor: "title", align: HorizontalAlign.Start },
center: { anchor: "__container__", align: VerticalAlign.Center }
}).id("arrow")
Column() {
Text(this.getLoadTips()).fontSize(this.pullConfig.pullUpTipsSize).fontColor(this.pullConfig.pullUpTipsColor)
}.id("title").alignRules({
middle: { anchor: "__container__", align: HorizontalAlign.Center },
center: { anchor: "__container__", align: VerticalAlign.Center }
}).constraintSize({ minWidth: 80 }).alignItems(HorizontalAlign.Center)
}.height(50).width("100%")
}
@Builder
defFooterNoMoreView() {
Text(this.pullConfig.noMoreTips)
.textAlign(TextAlign.Center)
.height(50)
.width("100%")
.fontSize(this.pullConfig.noMoreTipsSize)
.fontColor(this.pullConfig.noMoreTipsColor)
}
private getTips(): Resource | string {
// todo
if (!this.config.isVertical && this.config.horizontalMode != 1 && this.config.horizontalMode != 2) {
switch (this.status) {
case PullStatus.DEF:
case PullStatus.PullDown:
return this.pullConfig.pullDownTipsHorizontal
case PullStatus.PreRefresh:
return this.pullConfig.releaseRefreshTipsHorizontal
case PullStatus.Refresh:
return this.pullConfig.refreshTipsHorizontal
case PullStatus.PreOpenPage:
case PullStatus.OpenPage:
return this.pullConfig.pullOpenPageTipsHorizontal
case PullStatus.RefreshSuccess:
if (this.controller.getConfig().refreshShowSuccess) {
return this.pullConfig.refreshSuccessTipsHorizontal
} else {
/*如果不显示刷新成功的视图*/
return this.pullConfig.refreshTipsHorizontal
}
case PullStatus.RefreshError:
if (this.controller.getConfig().refreshShowError) {
return this.pullConfig.refreshErrorTipsHorizontal
} else {
/*如果不显示刷新失败的视图*/
return this.pullConfig.refreshTipsHorizontal
}
default:
return this.pullConfig.pullDownTipsHorizontal
}
}
switch (this.status) {
case PullStatus.DEF:
case PullStatus.PullDown:
return this.pullConfig.pullDownTips
case PullStatus.PreRefresh:
return this.pullConfig.releaseRefreshTips
case PullStatus.Refresh:
return this.pullConfig.refreshTips
case PullStatus.PreOpenPage:
case PullStatus.OpenPage:
return this.pullConfig.pullOpenPageTips
case PullStatus.RefreshSuccess:
if (this.controller.getConfig().refreshShowSuccess) {
return this.pullConfig.refreshSuccessTips
} else {
/*如果不显示刷新成功的视图*/
return this.pullConfig.refreshTips
}
case PullStatus.RefreshError:
if (this.controller.getConfig().refreshShowError) {
return this.pullConfig.refreshErrorTips
} else {
/*如果不显示刷新失败的视图*/
return this.pullConfig.refreshTips
}
default:
return this.pullConfig.pullDownTips
}
}
private getLoadTips(): Resource | string {
if (!this.config.isVertical && this.config.horizontalMode != 1 && this.config.horizontalMode != 2) {
switch (this.status) {
case PullStatus.DEF:
case PullStatus.PullUp:
return this.pullConfig.pullUpTipsHorizontal
case PullStatus.PreLoad:
return this.pullConfig.releaseLoadTipsHorizontal
case PullStatus.Load:
return this.pullConfig.loadTipsHorizontal
case PullStatus.PreLoadOpenPage:
case PullStatus.LoadOpenPage:
return this.pullConfig.pullOpenPageTipsHorizontal
case PullStatus.LoadSuccess:
if (this.controller.getConfig().loadShowSuccess) {
return this.pullConfig.loadSuccessTipsHorizontal
} else {
/*如果不显示刷新成功的视图*/
return this.pullConfig.loadTipsHorizontal
}
case PullStatus.LoadError:
if (this.controller.getConfig().loadShowError) {
return this.pullConfig.loadErrorTipsHorizontal
} else {
/*如果不显示刷新失败的视图*/
return this.pullConfig.loadTipsHorizontal
}
default:
return this.pullConfig.pullUpTipsHorizontal
}
}
switch (this.status) {
case PullStatus.DEF:
case PullStatus.PullUp:
return this.pullConfig.pullUpTips
case PullStatus.PreLoad:
return this.pullConfig.releaseLoadTips
case PullStatus.Load:
return this.pullConfig.loadTips
case PullStatus.PreLoadOpenPage:
case PullStatus.LoadOpenPage:
return this.pullConfig.loadOpenPageTips
case PullStatus.LoadSuccess:
if (this.controller.getConfig().loadShowSuccess) {
return this.pullConfig.loadSuccessTips
} else {
/*如果不显示刷新成功的视图*/
return this.pullConfig.loadTips
}
case PullStatus.LoadError:
if (this.controller.getConfig().loadShowError) {
return this.pullConfig.loadErrorTips
} else {
/*如果不显示刷新失败的视图*/
return this.pullConfig.loadTips
}
default:
return this.pullConfig.pullUpTips
}
}
/*下拉箭头显示逻辑*/
private getPullArrowVisibility(): Visibility {
switch (this.status) {
case PullStatus.DEF:
case PullStatus.PullDown:
case PullStatus.PreRefresh:
return Visibility.Visible
}
return Visibility.Hidden
}
private getRefreshVisibility(): Visibility {
switch (this.status) {
case PullStatus.Refresh:
return Visibility.Visible
case PullStatus.RefreshSuccess:
if (this.controller.getConfig().refreshShowSuccess) {
return Visibility.Hidden
} else {
/*如果不显示刷新成功的视图*/
return Visibility.Visible
}
case PullStatus.RefreshError:
if (this.controller.getConfig().refreshShowError) {
return Visibility.Hidden
} else {
/*如果不显示刷新失败的视图*/
return Visibility.Visible
}
}
return Visibility.Hidden
}
private getPullUpArrowVisibility(): Visibility {
switch (this.status) {
case PullStatus.DEF:
case PullStatus.PullUp:
case PullStatus.PreLoad:
return Visibility.Visible
}
return Visibility.Hidden
}
private getLoadVisibility(): Visibility {
switch (this.status) {
case PullStatus.Load:
return Visibility.Visible
case PullStatus.LoadSuccess:
if (this.controller.getConfig().loadShowSuccess) {
return Visibility.Hidden
} else {
/*如果不显示刷新成功的视图*/
return Visibility.Visible
}
case PullStatus.LoadError:
if (this.controller.getConfig().loadShowError) {
return Visibility.Hidden
} else {
/*如果不显示刷新失败的视图*/
return Visibility.Visible
}
}
return Visibility.Hidden
}
private getTimeTipsVisibility(): Visibility {
switch (this.status) {
case PullStatus.Refresh:
case PullStatus.PreOpenPage:
case PullStatus.OpenPage:
case PullStatus.RefreshSuccess:
case PullStatus.RefreshError:
return Visibility.None
}
if (this.getLastRefreshTime() <= 0) {
return Visibility.None
}
return Visibility.Visible
}
private sp: preferences.Preferences | undefined = undefined
private lastRefreshTime: number | undefined = undefined
private getLastRefreshTime(): number {
if (!this.sp) {
this.sp = preferences.getPreferencesSync(getContext(), {
name: "PullToRefreshLayoutTime"
})
}
if (this.lastRefreshTime) {
return this.lastRefreshTime
}
let preTime: number = this.sp.getSync("lastRefreshTimeKey" + this.viewKey, 0) as number
this.lastRefreshTime = preTime
return preTime;
}
private saveRefreshTime() {
if (!this.sp) {
this.sp = preferences.getPreferencesSync(getContext(), {
name: "PullToRefreshLayoutTime"
})
}
this.lastRefreshTime = new Date().getTime()
this.sp.put("lastRefreshTimeKey" + this.viewKey, this.lastRefreshTime)
this.sp.flush()
}
private lineBreak(): string {
if (this.isVerticalLayout()) {
return ""
} else {
return "\n"
}
}
private getLastFormatRefreshTime(): string {
const time = this.getLastRefreshTime();
if (time <= 0) {
return ""
}
const currentTime = new Date().getTime()
const timeIntervalSecond = Math.floor(((currentTime - time) / 1000))
let timeFormat: string = ""
if (!this.zr_last_update) {
if (this.isVerticalLayout()) {
this.zr_last_update = getContext().resourceManager.getStringByNameSync(("zr_last_update"))
} else {
this.zr_last_update = "\n" + getContext().resourceManager.getStringByNameSync(("h_zr_last_update"))
}
}
timeFormat = timeFormat + this.zr_last_update
if (timeIntervalSecond < 60) {
timeFormat = timeFormat + this.lineBreak() + timeIntervalSecond;
if (!this.zr_seconds_ago) {
if (this.isVerticalLayout()) {
this.zr_seconds_ago = getContext().resourceManager.getStringByNameSync(("zr_seconds_ago"))
} else {
this.zr_seconds_ago = "\n" + getContext().resourceManager.getStringByNameSync(("h_zr_seconds_ago"))
}
}
timeFormat = timeFormat + this.zr_seconds_ago
} else if (timeIntervalSecond < 3600) {
/*小于一小时*/
timeFormat = timeFormat + this.lineBreak() + Math.floor((timeIntervalSecond / 60));
if (!this.zr_minutes_ago) {
if (this.isVerticalLayout()) {
this.zr_minutes_ago = getContext().resourceManager.getStringByNameSync(("zr_minutes_ago"))
} else {
this.zr_minutes_ago = "\n" + getContext().resourceManager.getStringByNameSync(("h_zr_minutes_ago"))
}
}
timeFormat = timeFormat + this.zr_minutes_ago
} else if (timeIntervalSecond < 86400) {
/*小于一天*/
timeFormat = timeFormat + this.lineBreak() + Math.floor((timeIntervalSecond / 3600));
if (!this.zr_hours_ago) {
if (this.isVerticalLayout()) {
this.zr_hours_ago = getContext().resourceManager.getStringByNameSync(("zr_hours_ago"))
} else {
this.zr_hours_ago = "\n" + getContext().resourceManager.getStringByNameSync(("h_zr_hours_ago"))
}
}
timeFormat = timeFormat + this.zr_hours_ago
} else {
/*大于一天*/
timeFormat = timeFormat + this.lineBreak() + Math.floor((timeIntervalSecond / 86400));
if (!this.zr_days_ago) {
if (this.isVerticalLayout()) {
this.zr_days_ago = getContext().resourceManager.getStringByNameSync(("zr_days_ago"))
} else {
this.zr_days_ago = "\n" + getContext().resourceManager.getStringByNameSync(("h_zr_days_ago"))
}
}
timeFormat = timeFormat + this.zr_days_ago
}
return timeFormat
}
private zr_last_update: string | undefined = undefined
private zr_seconds_ago: string | undefined = undefined
private zr_minutes_ago: string | undefined = undefined
private zr_hours_ago: string | undefined = undefined
private zr_days_ago: string | undefined = undefined
private isUpdateTime = false;
private updateRefreshTime(status: PullStatus) {
if (status == PullStatus.RefreshSuccess) {
this.saveRefreshTime()
}
if (status == PullStatus.PullDown || status == PullStatus.PreRefresh) {
if (this.isUpdateTime) {
return;
}
this.isUpdateTime = true
setTimeout(() => {
this.zrLastUpdate = this.getLastFormatRefreshTime()
this.startUpdateTime();
})
} else {
this.stopUpdateTime();
}
}
private startUpdateTime() {
if (!this.isUpdateTime) {
return
}
setTimeout(() => {
this.zrLastUpdate = this.getLastFormatRefreshTime()
// console.log(this.zrLastUpdate + "=======startUpdateTime=====" + (1000 - new Date().getTime() % 1000));
this.startUpdateTime();
}, 1000 - new Date().getTime() % 1000)
}
private stopUpdateTime() {
this.isUpdateTime = false
}
}
@@ -0,0 +1,80 @@
import { PullStatus } from './PullStatus'
import { RefreshLayoutConfig } from './RefreshLayoutConfig'
export enum ViewState{
success=0,
loading,
empty,
error,
noNetwork
}
export class RefreshController {
/*刷新成功*/
refreshSuccess: (ignoreViewTips?:boolean) => void = (ignoreViewTips?:boolean) => {
}
/*刷新失败*/
refreshError: () => void = () => {
}
/*刷新完成,true:成功,false:失败*/
refreshComplete: (isSuccess: boolean,ignoreViewTips?:boolean) => void = (isSuccess: boolean,ignoreViewTips?:boolean) => {
}
/*取消刷新*/
refreshCancel: () => void = () => {
}
/*加载成功*/
loadSuccess: (hasMore?: boolean) => void = (hasMore?: boolean) => {
}
/*加载失败*/
loadError: () => void = () => {
}
/*加载完成,true:成功,false:失败*/
loadComplete: (isSuccess: boolean, hasMore?: boolean) => void = (isSuccess: boolean, hasMore?: boolean) => {
}
/*取消加载*/
loadCancel: () => void = () => {
}
/*显示加载中*/
viewLoading: () => void = () => {
this.viewState=ViewState.loading
}
/*显示空布局*/
viewEmpty: () => void = () => {
this.viewState=ViewState.empty
}
/*显示加载失败布局*/
viewError: () => void = () => {
this.viewState=ViewState.error
}
/*显示无网络布局*/
viewNoNetwork: () => void = () => {
this.viewState=ViewState.noNetwork
}
/**/
/*获取当前状态*/
getStatus: () => PullStatus = () => PullStatus.DEF
/*设置是否还有更多数据*/
hasMore: (hasMore: boolean) => void = (hasMore: boolean) => {
}
/*手动触发下拉刷新*/
refresh: () => void = () => {
}
/*手动触发上拉*/
load: () => void = () => {
}
/*下拉刷新开关是否打开*/
refreshIsEnable: () => boolean = () => true
/*下拉刷新开关是否打开*/
loadIsEnable: () => boolean = () => false
/*设置配置*/
/*由于v2装饰器@Param限制原因,setConfig方法在v2版本上不提供*/
/*@Param装饰的变量在子组件中无法进行修改。但当装饰的变量类型为对象时,在子组件中修改对象中属性是允许的。*/
// setConfig: (config: RefreshLayoutConfig) => void = () => {}
/*获取配置*/
getConfig: () => RefreshLayoutConfig = () => new RefreshLayoutConfig()
/*webview专用*/
onWebviewScroll: (xOffset: number, yOffset: number) => void = (xOffset: number, yOffset: number) => {
}
private viewState:ViewState=ViewState.success
public getViewState():ViewState{
return this.viewState
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,68 @@
export class RefreshLayoutConfig {
/*是否是垂直列表*/
public isVertical: boolean = true
/*横向模式0:正常横向布局,1:header和footer逆时针旋转90度,2header和footer顺时针旋转90度*/
public horizontalMode: number = 0
/*是否打开刷新*/
public pullRefreshEnable: boolean = true
/*是否打开加载更多*/
public pullLoadEnable: boolean = true
/*******************************刷新配置*******************************************/
/*true:释放刷新,false下拉到一定距离刷新*/
public releaseRefresh: boolean = true
/*下拉最大距离*/
public pullMaxDistance: number = 500
/*下拉阻力*/
public pullRefreshResistance: number = 0.5
/*下拉距离超过多少时达到刷新条件*/
public pullHeaderHeightRefresh: number = 0
/*下拉打开其他页面开关*/
public pullRefreshOpenPageEnable: boolean = false
/*下拉距离超过多少时达到打开其他页面条件*/
public pullHeaderHeightOpenPage: number = 0
/*释放刷新时,回弹至headerView高度的时间*/
public durationToHeader: number = 250
/*头布局刷新结束时回弹的时间*/
public durationCloseHeader: number = 200
/*需要打开其他页面时,头布局的回弹时间*/
public durationCloseForOpenPage: number = 180
/*刷新时是否显示头view*/
public refreshKeepHeader: boolean = true
/*是否显示刷新成功状态的view*/
public refreshShowSuccess: boolean = true;
/*是否显示刷新失败状态的view*/
public refreshShowError: boolean = true;
/*刷新结果view显示持续时间*/
public refreshResultDurationTime: number = 600
/*******************************加载更多配置*******************************************/
/*true:释放加载,false下拉到一定距离加载*/
public releaseLoad: boolean = true
/*上拉最大距离*/
public pullLoadMaxDistance: number = 500
/*上拉阻力*/
public pullLoadResistance: number = 0.5
/*上拉距离超过多少时达到刷新条件*/
public pullFooterHeightLoad: number = 0
/*上拉打开其他页面开关*/
public pullLoadOpenPageEnable: boolean = false
/*上拉距离超过多少时达到打开其他页面条件*/
public pullFooterHeightOpenPage: number = 0
/*释放刷新时,回弹至footerView高度的时间*/
public durationToFooter: number = 250
/*footer布局刷新结束时回弹的时间*/
public durationCloseFooter: number = 200
/*需要打开其他页面时,头布局的回弹时间*/
public durationCloseLoadForOpenPage: number = 180
/*刷新时是否显示footerView*/
public loadKeepFooter: boolean = true
/*是否显示刷新成功状态的view*/
public loadShowSuccess: boolean = true;
/*是否显示刷新失败状态的view*/
public loadShowError: boolean = true;
/*刷新结果view显示持续时间*/
public loadResultDurationTime: number = 600
}
@@ -0,0 +1,67 @@
import { AnimatorOptions } from '@kit.ArkUI';
@Builder
export function _headerView() {
Text("headerView:()=>{your @Builder View}")
}
@Builder
export function _ContentView() {
Text("contentView:()=>{your @Builder View}")
}
@Builder
export function _loadMoreView() {
Text("loadView:()=>{your @Builder View}")
}
@Builder
export function _noMoreView() {
Text("noMoreView:()=>{your @Builder View}")
}
export class RefreshLayoutHelper {
private log(str: string, tag: string = "RefreshLayout") {
console.debug(tag + "==" + str)
}
/*记录列表滑动到底部的偏移量*/
public scrollerOffset: number = 0;
/*下拉刷新*/
public preOffset: number = 0;
public totalOffset: number = 0;
/*上拉加载*/
// public preOffsetLoad: number = 0;
public totalOffsetLoad: number = 0;
public headerSize: number = 0;
public footerSize: number = 0;
public isPressDown: boolean = false
public options: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Down | PanDirection.Up })
/*不是释放刷新*/
public notReleaseRefresh: boolean = false
/*不是释放加载*/
public notReleaseLoad: boolean = false
public animOptions: AnimatorOptions = {
duration: 250,
easing: "fast-out-linear-in",
delay: 0,
fill: "forwards",
direction: "normal",
iterations: 1,
begin: 0,
end: 1
}
public animLoadOptions: AnimatorOptions = {
duration: 250,
easing: "fast-out-linear-in",
delay: 0,
fill: "forwards",
direction: "normal",
iterations: 1,
begin: 0,
end: 1
}
/*webview滑动偏移量*/
public webViewXOffset: number = 0
public webViewYOffset: number = 0
}
+11
View File
@@ -0,0 +1,11 @@
{
"module": {
"name": "refreshlib",
"type": "har",
"deviceTypes": [
"default",
"tablet",
"2in1"
]
}
}
@@ -0,0 +1,72 @@
{
"string": [
{
"name": "zr_pull_down_to_refresh",
"value": "下拉刷新"
},
{
"name": "zr_release_to_refresh",
"value": "释放立即刷新"
},
{
"name": "zr_release_to_open_age",
"value": "释放打开其他页面"
},
{
"name": "zr_refreshing",
"value": "正在刷新..."
},
{
"name": "zr_refresh_success",
"value": "刷新完成"
},
{
"name": "zr_refresh_error",
"value": "刷新失败"
},
{
"name": "zr_last_update",
"value": "上次更新:"
},
{
"name": "zr_seconds_ago",
"value": " 秒之前"
},
{
"name": "zr_minutes_ago",
"value": " 分钟之前"
},
{
"name": "zr_hours_ago",
"value": " 小时之前"
},
{
"name": "zr_days_ago",
"value": " 天之前"
},
{
"name": "zr_pull_up_to_load",
"value": "上拉加载"
},
{
"name": "zr_release_to_load",
"value": "释放立即加载"
},
{
"name": "zr_loading",
"value": "正在加载..."
},
{
"name": "zr_load_success",
"value": "加载完成"
},
{
"name": "zr_load_error",
"value": "加载失败"
},
{
"name": "zr_load_no_more",
"value": "暂无更多"
}
]
}
@@ -0,0 +1,72 @@
{
"string": [
{
"name": "h_zr_pull_down_to_refresh",
"value": "右\n拉\n刷\n新"
},
{
"name": "h_zr_release_to_refresh",
"value": "释\n放\n立\n即\n刷\n新"
},
{
"name": "h_zr_release_to_open_age",
"value": "释\n放\n打\n开\n其\n他\n页\n面"
},
{
"name": "h_zr_refreshing",
"value": "正\n在\n刷\n新\n..."
},
{
"name": "h_zr_refresh_success",
"value": "刷\n新\n完\n成"
},
{
"name": "h_zr_refresh_error",
"value": "刷\n新\n失\n败"
},
{
"name": "h_zr_last_update",
"value": "上\n次\n更\n新"
},
{
"name": "h_zr_seconds_ago",
"value": "秒\n之\n前"
},
{
"name": "h_zr_minutes_ago",
"value": "分\n钟\n之\n前"
},
{
"name": "h_zr_hours_ago",
"value": "小\n时\n之\n前"
},
{
"name": "h_zr_days_ago",
"value": "天\n之\n前"
},
{
"name": "h_zr_pull_up_to_load",
"value": "左\n拉\n加\n载"
},
{
"name": "h_zr_release_to_load",
"value": "释\n放\n立\n即\n加\n载"
},
{
"name": "h_zr_loading",
"value": "正\n在\n加\n载\n..."
},
{
"name": "h_zr_load_success",
"value": "加\n载\n完\n成"
},
{
"name": "h_zr_load_error",
"value": "加\n载\n失\n败"
},
{
"name": "h_zr_load_no_more",
"value": "暂\n无\n更\n多"
}
]
}
@@ -0,0 +1,7 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="0"
width="64" height="64" >
<path d="M641.774 783.11L382.209 783.11c-26.078 0-47.1785-21.1016-47.1785-47.1785l23.5877-330.373c0-26.078 21.1016-47.1785 47.1795-47.1785L618.183 358.38c26.077 0 47.2205 21.1006 47.2205 47.1785l23.5877 330.373c0 26.077-21.1415 47.1784-47.2184 47.1785Zm-35.3631-471.951L417.61299999 311.159c-19.5678 0-35.4043-15.8357-35.40429999-35.4043L382.208 252.166c0-19.52679999 15.8357-35.40540001 35.4043-35.4054l188.798 0c19.52679999 0 35.3634 15.8796 35.3634 35.4054l0 23.5894c-0.00106066 19.5677-15.8377 35.4034-35.3644 35.4033Zm-11.8155-141.57700001L429.386 169.582c-13.0165 0-23.5882-10.5708-23.5882-23.5882l0-23.6322c0-13.0165 10.5718-23.58820001 23.5882-23.5882l165.208 0c13.0185 0 23.58820001 10.5718 23.5882 23.5882l0 23.63219999c0.00101823 13.0185-10.5697 23.5882-23.5872 23.58820001ZM571.00600001 51.596L453.018 51.596c-13.0594 0-23.6312-10.5728-23.6312-23.5903 0-13.05739999 10.5718-23.62919999 23.6312-23.6292l117.988 0c13.0165 0 23.58820001 10.5718 23.5882 23.6292 0.0010253 13.0165-10.5708 23.5903-23.58819999 23.5903Zm284.687 626.294L537.508 1008.759c-6.92267 7.21328-15.5041 10.8614-25.4967 10.8614-10.03150001 0-18.572-3.64811-25.5366-10.8614L168.29 677.89c-10.0744-10.4868-12.7299-25.0393-7.04851-38.4303 5.68037-13.349 18.0337-21.515 32.5851-21.51499999l636.372-1e-8c14.5504 0 26.8628 8.16701 32.5442 21.515 5.72027 13.39 3.02493001 27.9434-7.04957 38.4303Z"
fill="#333333"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -0,0 +1,8 @@
{
"string": [
{
"name": "page_show",
"value": "page from package"
}
]
}
@@ -0,0 +1,8 @@
{
"string": [
{
"name": "page_show",
"value": "page from package"
}
]
}
@@ -0,0 +1,35 @@
import { hilog } from '@kit.PerformanceAnalysisKit';
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function abilityTest() {
describe('ActsAbilityTest', () => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
})
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
})
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
})
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
})
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
})
})
}
@@ -0,0 +1,5 @@
import abilityTest from './Ability.test';
export default function testsuite() {
abilityTest();
}
+13
View File
@@ -0,0 +1,13 @@
{
"module": {
"name": "refreshlib",
"type": "feature",
"deviceTypes": [
"default",
"tablet",
"2in1"
],
"deliveryWithInstall": true,
"installationFree": false
}
}
+5
View File
@@ -0,0 +1,5 @@
import localUnitTest from './LocalUnit.test';
export default function testsuite() {
localUnitTest();
}
+33
View File
@@ -0,0 +1,33 @@
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function localUnitTest() {
describe('localUnitTest', () => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
});
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
});
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
});
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
});
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
});
});
}