HarmonyOS 鸿蒙Next中关于应用接续长列表的
HarmonyOS 鸿蒙Next中关于应用接续长列表的 目前版本是最新版,我想问一下,长列表接续,就是我手机浏览到一般,接续到平板,平板可以直接从这一半中继续浏览,我想问一下,如果页面有两个滑动容器,外面Scroll,里面是List,然后我按照文档上把OnDidScroll和OnDidBuilde都配置到Scroll了,List我没配置,现在可以监听到Scroll滑动的距离,但是这个距离有最大值,我没搞懂,还有就是,手机看一般,平板并不能跳转到手机的对应位置,这怎么解决啊?
【背景知识】
应用接续,指当用户在一个设备上操作某个应用时,可以在另一个设备的同一个应用中快速切换,并无缝衔接上一个设备的应用体验。比如在用户使用过程中,使用情景发生了变化,之前使用的设备不再适合继续当前任务,或者周围有更合适的设备,此时用户可以选择使用新的设备来继续当前的任务。接续完成后,之前设备的应用可退出或保留,用户可以将注意力集中在被拉起的设备上,继续执行任务。
【解决方案】
Scroll嵌套List,浏览进度接续。
// EntryAbility.ets
// 冷启动取出浏览进度
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
if (launchParam.launchReason === AbilityConstant.LaunchReason.CONTINUATION) {
// 将上述的保存的数据取出恢复
if (want.parameters !== undefined) {
want.parameters.currentOffset && AppStorage.setOrCreate('continueOffset', want.parameters.currentOffset);
AppStorage.setOrCreate('setCurrentOffset', true);
}
// 触发页面恢复
this.context.restoreWindowStage(this.storage);
}
}
// EntryAbility.ets
// 热启动取出浏览进度
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
console.info(`EntryAbility onNewWant ${AbilityConstant.LaunchReason.CONTINUATION}`)
if (launchParam.launchReason === AbilityConstant.LaunchReason.CONTINUATION) {
// 将上述的保存的数据取出恢复
if (want.parameters !== undefined) {
want.parameters.currentOffset && AppStorage.setOrCreate('continueOffset', want.parameters.currentOffset);
AppStorage.setOrCreate('setCurrentOffset', true);
}
this.context.restoreWindowStage(this.storage);
}
}
// EntryAbility.ets
// 接续生命周期保存
onContinue(wantParam: Record<string, Object>) {
console.info('Ability onContinue');
// 迁移数据保存
let currentOffset = AppStorage.get('continueOffset') as number;
wantParam.currentOffset = currentOffset;
return AbilityConstant.OnContinueResult.AGREE;
}
// PageContinue.ets
@StorageLink('continueOffset') continueOffset: number = 0; // 接续偏移量
@StorageLink('setCurrentOffset') setCurrentOffset: boolean = false; // 是否启用设置偏移量
onDidBuild(): void {
if (this.setCurrentOffset) {
// 渲染前使用控制器调整滚动位置
this.scroller.scrollTo({ xOffset: 0, yOffset: this.continueOffset });
this.setCurrentOffset = false;
}
}
build() {
Scroll(this.scroller) {
List({ space: 20, initialIndex: 0 }) {
LazyForEach(this.arr, (item: number) => {
ListItem() {
Text('' + item)
}
}, (item: number) => item.toString())
}
.listDirection(Axis.Vertical) // 排列方向
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.Spring) // 边缘效果设置为Spring
.width('90%')
}
.onDidScroll((scrollOffset: number, scrollState: ScrollState) => {
if (!this.setCurrentOffset) {
this.continueOffset = this.scroller.currentOffset()?.yOffset;
}
})
.width('100%')
.height('100%')
}
更多关于HarmonyOS 鸿蒙Next中关于应用接续长列表的的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
两个设备上的接续都存在list的话楼主可以考虑这个回调来记录已经阅读到的位置,切换设备了过后结合scrollToItemInGroup
主动跳转到这个位置:
找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17
若仅监听外层Scroll的滚动事件,获取的滚动距离仅代表外层容器自身的滑动范围。当内层List产生独立滚动时,该数值无法覆盖内层滚动偏移量。List组件自带懒加载特性,与外层Scroll的滚动监听存在冲突,会导致位置计算不准确。试试下面的办法?
同时为外层Scroll和内层List配置onScroll事件,将内外层偏移量转换为全局坐标后存储
Scroll(this.outerScroller) {
List() {
// List内容
}
.onScroll((offset: number) => {
this.saveInnerOffset(offset)
})
}
.onScroll((offset: number) => {
this.saveOuterOffset(offset)
})
在保存滚动位置时需同时记录分页状态:
interface ContinueData {
scrollOffset: number; // 总滚动距离
pageIndex: number; // 当前页码
itemIndex: number; // 首条可见项索引
}
在目标设备恢复时需等待组件渲染完成:
aboutToAppear() {
setTimeout(() => { // 等待布局完成
this.outerScroller.scrollTo({
x: 0,
y: savedData.scrollOffset
})
}, 50)
}
在HarmonyOS Next中,应用接续长列表通过分布式数据管理和流转框架实现。系统利用分布式软总线技术,使应用在不同设备间无缝迁移并保持列表状态。通过统一的跨端数据管理机制,长列表数据可在多设备间同步,确保用户操作连续性。应用需使用ArkUI声明式开发范式,结合分布式数据对象与跨设备组件通信能力,实现列表状态实时同步与高效渲染。
问题可能出在内外滑动容器的联动处理上。Scroll和List都需要配置OnDidScroll和OnDidBuild,否则无法准确同步滚动位置。建议检查List是否遗漏了接续配置,并确保两个容器都正确注册了滑动事件。另外,最大距离限制可能是由于容器高度计算差异导致的,需要确认滚动位置传递逻辑是否一致。