HarmonyOS 鸿蒙Next 滚动条组件ScrollBar滑动时跳动

发布于 1周前 作者 h691938207 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 滚动条组件ScrollBar滑动时跳动

滚动条组件ScrollBar配合可滚动组件List,通过懒加载实现List组件的ListItem子组件按需加载,滑动ScrollBar组件持续加载ListItem组件的过程,ScrollBar组件会跳动,需求是解决ScrollBar组件的跳动。

2 回复

可以参考以下代码

export class MyDataSource implements IDataSource {
dataArray: HSFileItemForOperation[] = [];
private listeners: DataChangeListener[] = []

public pushInitData(dataArray: HSFileItemForOperation[]) {
for (let i = 0; i < dataArray.length; i++) {
this.dataArray.push(dataArray[i])
}

this.notifyDataReload()
}

public getData(index: number): HSFileItemForOperation {
return this.dataArray[index]
}

// 数据源的数据总量
public totalCount(): number {
return this.dataArray.length;
}

notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded()
})
}

registerDataChangeListener(listener: DataChangeListener): void {
}

unregisterDataChangeListener(listener: DataChangeListener): void {
}
}

[@Observed](/user/Observed)
export class HSFileItemForOperation implements IDataSource {
dataArray: number[] = [];

public pushData(dataArray: number[]) {
for (let i = 0; i < dataArray.length; i++) {
this.dataArray.push(dataArray[i])
}
}

constructor(dataArray: number[]) {
this.dataArray = dataArray
}

// 返回指定索引位置的数据
public getData(index: number): number {
return this.dataArray[index];
}

// 数据源的数据总量
public totalCount(): number {
return this.dataArray.length;
}

registerDataChangeListener(listener: DataChangeListener): void {
}

unregisterDataChangeListener(listener: DataChangeListener): void {
}
}

// // 模拟数据
export const FILEITEM_LIST: HSFileItemForOperation[] = [
new HSFileItemForOperation([
0, 1, 2, 3, 4,
]),
new HSFileItemForOperation([
21, 22, 23,
24
]),
new HSFileItemForOperation([
31, 32, 33, 34, 35, 36, 37
]),
new HSFileItemForOperation(
[38, 39,])
]

[@Entry](/user/Entry)
[@Component](/user/Component)
struct Page {
private scroller: Scroller = new Scroller()

build() {
Column() {
Stack() {
Scroll(this.scroller) {
Column() {
TabsView()
}
}
.width('100%')
.height('100%')
.scrollable(ScrollDirection.Vertical)
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.None)
}
.width('100%')
.height('100%')
.alignContent(Alignment.Top)
}
}

[@Component](/user/Component)
export struct TabsView {
private tabController: TabsController = new TabsController()
private groups: MyDataSource = new MyDataSource();
private scroller: Scroller = new Scroller()
[@State](/user/State) childrenSize: ChildrenMainSize = new ChildrenMainSize(120)

aboutToAppear(): void {
this.childrenSize.splice(0, 3, [280, 160, 280, 160])
this.groups.pushInitData(FILEITEM_LIST)
}

build() {
Tabs({ controller: this.tabController }) {
TabContent() {
Stack({ alignContent: Alignment.End }) {
List({ scroller: this.scroller }) {
LazyForEach(this.groups, (headItem: HSFileItemForOperation, index: number) => {
ReusableListGroupComponent({
group: headItem,
index: index
})
}, (headItem: number) => headItem.toString() + Math.random() * 10)
}
.childrenMainSize(this.childrenSize)
.width('100%')
.height('100%')
.lanes(4)
.sticky(StickyStyle.Header)
.backgroundColor(Color.White)
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.SELF_FIRST
})
.edgeEffect(EdgeEffect.None)
.scrollBar(BarState.Off)

ScrollBar({ scroller: this.scroller, direction: ScrollBarDirection.Vertical, state: BarState.Auto }) {
Stack() {
Image($r('app.media.startIcon'))
.width(60)
.height(44)
.borderRadius({
topLeft: 22,
bottomLeft: 22
})
}
}
.backgroundColor(Color.Green)
.hitTestBehavior(HitTestMode.Transparent)
}
}.tabBar('test')
}
}

[@Component](/user/Component)
struct ReusableListGroupComponent {
[@ObjectLink](/user/ObjectLink) group: HSFileItemForOperation
[@Prop](/user/Prop) index: number
[@State](/user/State) childrenSize: ChildrenMainSize = new ChildrenMainSize(120)

[@Builder](/user/Builder)
itemHead(text: string) {
Text(text)
.fontSize(20)
.backgroundColor(0xAABBCC)
.width("100%")
.height(40)
}

build() {
ListItemGroup({ header: this.itemHead('group' + this.index.toString()) }) {
LazyForEach(this.group, (item: number, index: number) => {
ListItem() {
// 使用可复用自定义组件
ReusableChildComponent({ item: item })
.onAppear(() => {
console.log('ReusableChildComponent' + index)
})
}
}, (item: number) => item.toString() + Math.random())
}
.childrenMainSize(this.childrenSize)
}
}

[@Reusable](/user/Reusable)
[@Component](/user/Component)
struct ReusableChildComponent {
[@State](/user/State) item: number = 0;

aboutToReuse(params: Record<string, number>) {
this.item = params.item;
}

build() {
Column() {
Image($r('app.media.startIcon'))
.objectFit(ImageFit.Fill)
.layoutWeight(1)
Text(`图片${this.item}`)
.fontSize(16)
.textAlign(TextAlign.Center)
}
.width('100%')
.height(120)
.backgroundColor(0xF9CF93)
}
}

更多关于HarmonyOS 鸿蒙Next 滚动条组件ScrollBar滑动时跳动的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


针对HarmonyOS 鸿蒙Next中ScrollBar组件在滑动时出现跳动的问题,这通常与组件的渲染性能、事件处理或动画帧率有关。以下是一些可能的原因及解决方法(不涉及Java或C语言):

  1. 性能优化:检查ScrollBar所在的页面或组件是否有大量的渲染操作,如复杂的布局或频繁的数据更新。优化这些操作,减少渲染负担,可能有助于减少跳动。

  2. 事件处理:确保ScrollBar的滑动事件处理逻辑高效,避免在事件处理中进行耗时操作。此外,检查是否有多个事件监听器同时作用于ScrollBar,可能导致事件处理冲突。

  3. 动画帧率:检查系统的动画帧率设置,确保动画流畅运行。在鸿蒙系统中,可以通过调整动画相关设置来改善用户体验。

  4. 组件版本:确认你使用的ScrollBar组件是否为最新版本,或者是否存在已知的bug。查看鸿蒙系统的更新日志或开发者社区,了解是否有相关的修复或改进。

  5. 设备兼容性:测试在不同设备上的表现,以排除特定设备硬件或软件版本导致的问题。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部