赞
踩
本示例展示手机阅读时左右翻页,上下翻页,覆盖翻页的功能。
本例涉及的关键特性和实现方案如下:
swiper
+lazyforeach
+cachecount
实现按需加载。实现步骤:
aboutToAppear()
方法中通过pushItem
向后加载数据,addItem
向前加载数据。Swiper
组件和LazyForEach
将数据源中的每条数据存放于Text组件中,Swiper
向左或向右滑动的效果就是左右翻页的效果。BasicDataSource
的getData
方法中进行。当index等于0向前申请网络数据,当index
等于this.totalCount() - 1时向后请求网络数据。push
方法将数据插入到队尾,通过unshift
插入到队头,具体可参考BasicDataSource
的pushItem
和addItem
方法。Swiper(this.swiperController) { /** * TODO: 高性能知识点: 使用了cachedCount设置预加载的Text的数量,只在LazyForEach中生效,设置该属性后会缓存cachedCount个Text,LazyForEach超出显示和缓存范围的Text会被释放。 * 使用cachedCount参数的例子:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/ui-ts-performance-improvement-recommendation-0000001477981001-V2 */ LazyForEach(this.data, (item: string) => { Text($r(item)) ... }, (item: string) => item) } // TODO:知识点:index设置当前在容器中显示的子组件的索引值。设置小于0或大于等于子组件数量时,按照默认值0处理。 .index(this.currentPageNum - CONFIGURATION.PAGEFLIPPAGECOUNT) .width($r('app.string.pageflip_full_size')) .height($r('app.string.pageflip_full_size')) .indicator(false) .cachedCount(CONFIGURATION.PAGEFLIPCACHECOUNT) ...
aboutToAppear(): void {
/**
* 请求网络数据之后可以通过this.data.addItem(new Item('app.string.content' + i.toString()));的方法插入到数据源的开头形成新的数据源。
* 请求网络数据之后可以通过this.data.pushItem(new Item('app.string.content' + i.toString()));的方法插入到数据源的末尾形成新的数据源。
*/
for (let i = CONFIGURATION.PAGEFLIPPAGESTART; i <= CONFIGURATION.PAGEFLIPPAGEEND; i++) {
this.data.pushItem(STRINGCONFIGURATION.PAGEFLIPRESOURCE + i.toString());
}
}
public getData(index: number): string {
/**
* TODO:知识点:1.当index等于this.totalCount() - 1时向后请求网络数据。当index等于0时向前请求网络数据。
* TODO:知识点:2.新请求到的数据可以通过push插入到队尾,通知listeners刷新添加可参考pushItem方法。如果想要插到队头可以通过unshift插入到队头,通知listeners刷新添加可参考addItem方法。
*/
return this.elements[index];
}
list
+lazyforeach
+cachecount
实现按需加载。实现步骤:
aboutToAppear()
方法中通过pushItem
向后加载数据,addItem
向前加载数据。List
组件和LazyForEach
将数据源中的每条数据存放于Text组件中,List
向上或向下滑动的效果就是上下翻页的效果。BasicDataSource
的getData
方法中进行。当index等于0向前申请网络数据,当index
等于this.totalCount() - 1时向后请求网络数据。push
方法将数据插入到队尾,通过unshift
插入到队头,具体可参考BasicDataSource
的pushItem
和addItem
方法。// TODO:知识点:initialIndex设置为负数或超过了当前List最后一个item的索引值时视为无效取值,无效取值按默认值0显示。 List({ initialIndex: this.currentPageNum - CONFIGURATION.PAGEFLIPPAGECOUNT }) { /** * TODO: 高性能知识点: 使用了cachedCount设置预加载的ListItem的数量,只在LazyForEach中生效,设置该属性后会缓存cachedCount个ListItem,LazyForEach超出显示和缓存范围的ListItem会被释放。 * 使用cachedCount参数的例子:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/ui-ts-performance-improvement-recommendation-0000001477981001-V2 */ LazyForEach(this.data, (item: string) => { ListItem() { Text($r(item)) ... } }, (item: string) => item) } .width($r('app.string.pageflip_bottomview_row_text_width')) .height($r('app.string.pageflip_full_size')) .scrollBar(BarState.Off) .cachedCount(CONFIGURATION.PAGEFLIPCACHECOUNT) .onScrollIndex((firstIndex: number) => { this.currentPageNum = firstIndex + CONFIGURATION.PAGEFLIPPAGECOUNT; // 通过onScrollIndex监听当前处于第几页。 })
aboutToAppear(): void {
/**
* 请求网络数据之后可以通过this.data.addItem(new Item('app.string.content' + i.toString()));的方法插入到数据源的开头形成新的数据源。
* 请求网络数据之后可以通过this.data.pushItem(new Item('app.string.content' + i.toString()));的方法插入到数据源的末尾形成新的数据源。
*/
for (let i = CONFIGURATION.PAGEFLIPPAGESTART; i <= CONFIGURATION.PAGEFLIPPAGEEND; i++) {
this.data.pushItem(STRINGCONFIGURATION.PAGEFLIPRESOURCE + i.toString());
}
}
public getData(index: number): string {
/**
* TODO:知识点:1.当index等于this.totalCount() - 1时向后请求网络数据。当index等于0时向前请求网络数据。
* TODO:知识点:2.新请求到的数据可以通过push插入到队尾,通知listeners刷新添加可参考pushItem方法。如果想要插到队头可以通过unshift插入到队头,通知listeners刷新添加可参考addItem方法。
*/
return this.elements[index];
}
Stack
组件通过滑动+动画+改变组件内容实现效果。实现步骤:
Stack
组件中布局三个ReaderPage
,midPage
位于中间可以根据this.offsetX实时translate自己的位置。rightPage
。leftPage
向右滑动。isClick
来判断是点击翻页还是滑动翻页,由isLeft
来判断点击翻页中是向左翻页还是向右翻页。this.currentPageNum
加一或减一,根据相应的页数来加载三个content
相应的内容。Stack() { ReaderPage({ content: this.rightPageContent }); // 当midPage向左滑时,rightPage开始显现。 ReaderPage({ content: this.midPageContent }) /** TODO: 知识点: * 当this.offsetX<0时,translate的x为this.offsetX,midPage向左移动,显现rightPage。 * 当this.offsetX>0,translate的x为CONFIGURATION.PAGEFLIPZERO,midPage不动,leftPage向右滑动。 */ .translate({ x: this.offsetX >= CONFIGURATION.PAGEFLIPZERO ? CONFIGURATION.PAGEFLIPZERO : this.offsetX, y: CONFIGURATION.PAGEFLIPZERO, z: CONFIGURATION.PAGEFLIPZERO }) .width(this.screenW); ReaderPage({ content: this.leftPageContent }) // TODO: 知识点:在midPage的左边,当向右滑时,跟随this.offsetX向右滑动。 .translate({ x: -this.screenW + this.offsetX }); }
private clickAnimateTo(isClick: boolean, isLeft?: boolean) { animateTo({ duration: CONFIGURATION.PAGEFLIPTOASTDURATION, curve: Curve.EaseOut, onFinish: () => { /** TODO: 知识点:this.currentPageNum加一或者减一后修改组件的内容。 * 右滑:1. 恢复页面原始状态 2. 修改组件的内容为 page1 = content1-1, page2 = content2-1,page3 = content3-1 * 左滑:1. 恢复页面原始状态 2. 修改组件的内容为 page1 = content1+1, page2 = content2+1,page3 = content3+1 */ if (this.offsetX > CONFIGURATION.PAGEFLIPRIGHTFLIPOFFSETX && this.currentPageNum !== CONFIGURATION.PAGEFLIPPAGESTART) { this.currentPageNum -= CONFIGURATION.PAGEFLIPPAGECOUNT; } else if (this.offsetX < CONFIGURATION.PAGEFLIPLEFTFLIPOFFSETX && this.currentPageNum !== CONFIGURATION.PAGEFLIPPAGEEND) { this.currentPageNum += CONFIGURATION.PAGEFLIPPAGECOUNT; } this.offsetX = CONFIGURATION.PAGEFLIPZERO; this.simulatePageContent(); } }, () => { if (isClick) { // 是否为点击翻页 if (isLeft) { this.offsetX = this.screenW; // TODO: 知识点:右滑距离变为一个屏幕宽度,ReaderPage就会向右移动一个屏幕宽度,加上动画,形成了覆盖翻页的效果。 } else { this.offsetX = -this.screenW; // TODO: 知识点:左滑距离变为一个屏幕宽度,ReaderPage就会向左移动一个屏幕宽度,加上动画,形成了覆盖翻页的效果。 } } else { // 滑动翻页 if (this.offsetX > CONFIGURATION.PAGEFLIPRIGHTFLIPOFFSETX && this.currentPageNum !== CONFIGURATION.PAGEFLIPPAGESTART) { this.offsetX = this.screenW; } else if (this.offsetX < CONFIGURATION.PAGEFLIPLEFTFLIPOFFSETX && this.currentPageNum !== CONFIGURATION.PAGEFLIPPAGEEND) { this.offsetX = -this.screenW; } else { this.offsetX = CONFIGURATION.PAGEFLIPZERO; // 当位于第一页和末尾页,移动距离设为0,无法翻页。 } } }); }
// 模拟书页内容,可以在此进行网络请求。
simulatePageContent() {
this.leftPageContent = STRINGCONFIGURATION.PAGEFLIPRESOURCE + (this.currentPageNum - CONFIGURATION.PAGEFLIPPAGECOUNT).toString();
this.midPageContent = STRINGCONFIGURATION.PAGEFLIPRESOURCE + (this.currentPageNum).toString();
this.rightPageContent = STRINGCONFIGURATION.PAGEFLIPRESOURCE + (this.currentPageNum + CONFIGURATION.PAGEFLIPPAGECOUNT).toString();
}
pageflip // har包
|---common
| |---Constants.ets // 常量
|---components
| |---mainpage
| |---PageFlip.ets // 主页面
|---datasource
| |---BasicDataSource.ets // Basic数据控制器
|---view
| |---BottomView.ets // 底部菜单视图
| |---CoverFlipPage.ets // 覆盖翻页视图
| |---LeftRightFlipPage.ets // 左右翻页视图
| |---TopView.ets // 顶部菜单视图
| |---UpDownFlipPage.ets // 上下翻页视图
本例使用了onActionUpdate函数。该函数是系统高频回调函数,避免在函数中进行冗余或耗时操作,例如应该减少或避免在函数打印日志,会有较大的性能损耗。
本示例使用了LazyForEach进行数据懒加载,List布局时会根据可视区域按需创建ListItem组件,并在ListItem滑出可视区域外时销毁以降低内存占用。
本示例使用了cachedCount设置预加载的ListItem的数量,只在LazyForEach中生效,设置该属性后会缓存cachedCount个ListItem,LazyForEach超出显示和缓存范围的ListItem会被释放。
为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05
https://qr21.cn/FV7h05
https://qr21.cn/FV7h05
https://qr21.cn/FV7h05
https://qr18.cn/F781PH
https://qr18.cn/F781PH
1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。