HarmonyOS 鸿蒙Next中用Swiper实现List优先滑动的实例
HarmonyOS 鸿蒙Next中用Swiper实现List优先滑动的实例 方便大家,使用直接复制过去就能使用.
一、配置route_map.json,增加下面内容
{
"name": "SwiperListPage",
"pageSourceFile": "src/main/ets/pages/SwiperListPage.ets",
"buildFunction": "SwiperListPageBuilder",
"data": {
"description": "this is SwiperListPage"
}
}
二、在pages目录新建一个SwiperListPage.ets文件,文件内容如下 :
@Builder
export function SwiperListPageBuilder() {
SwiperListPage();
}
// 标题数据类型
interface TestTitleBean {
title: string;
id: string;
}
// 测试数据类型
interface TDMzicEpsData {
imageUrl?: string;
title?: string;
}
@Entry
@Component
struct SwiperListPage {
private titleListScroller: Scroller = new Scroller();
private swiperController: SwiperController = new SwiperController();
// 当前激活的索引(标题和Swiper共用)
@State activeIndex: number = 0;
// 标题数据
private titleData: TestTitleBean[] = [];
// 所有分组的测试数据(每个标题对应一组测试)
private groupDatas: TDMzicEpsData[][] = [];
aboutToAppear(): void {
// 初始化标题数据
this.titleData = [
{ title: '标题1', id: '1' },
{ title: '标题2', id: '2' },
{ title: '标题3', id: '3' },
{ title: '标题4', id: '4' },
{ title: '标题5', id: '5' }
];
// 初始化每个分组的测试数据
for (let i = 0; i < 5; i++) {
const videos: TDMzicEpsData[] = [];
for (let j = 0; j < 10; j++) {
videos.push({
imageUrl: `http://example.com/group${i}_video${j}.png`,
title: `组${i + 1}-测试${j + 1}`
});
}
this.groupDatas.push(videos);
}
}
scrollToIndex(): void {
if (this.titleListScroller) {
this.titleListScroller.scrollToIndex(this.activeIndex, false, ScrollAlign.CENTER);
}
}
// 标题视图
@Builder
titleView(item: TestTitleBean, index: number) {
Text(item.title)
.fontSize(16)
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
.backgroundColor(this.activeIndex === index ? '#409eff' : '#f5f5f5')
.fontColor(this.activeIndex === index ? '#fff' : '#333')
.borderRadius(4)
.onClick(() => {
this.activeIndex = index;
this.swiperController.changeIndex(index); // 点击标题,Swiper切换到对应页
});
}
build() {
Column() {
List({ scroller: this.titleListScroller }) {
ForEach(this.titleData, (item: TestTitleBean, index: number) => {
ListItem() {
this.titleView(item, index)
}
}, (item: TestTitleBean, index: number) => `${item.id}_${index}`)
}
.listDirection(Axis.Horizontal)
.scrollBar(BarState.Off)
.alignSelf(ItemAlign.Start)
.width('100%')
.height(50)
.margin({ bottom: 10 })
.onAppear(() => {
this.scrollToIndex()
})
Swiper(this.swiperController) {
ForEach(this.groupDatas, (datas: TDMzicEpsData[], _groupIndex: number) => {
// 每个Swiper页面对应一个List,显示该分组的测试数据
List({ space: 10 }) {
ForEach(datas, (item: TDMzicEpsData, _index: number) => {
ListItem() {
Stack({ alignContent: Alignment.TopEnd }) {
Stack() {
Image('https://via.placeholder.com/100x50')
.width(100)
.height(50)
.borderRadius(4)
Text(item.title || '测试A')
.fontSize(15)
.fontWeight(FontWeight.Medium)
.maxLines(1)
}
.height('100%')
//.aspectRatio(1)
}
.width(100)
.height(50)
.backgroundColor(Color.Gray)
.borderRadius(4)
.margin({ bottom: 10 })
}
})
}
.width('100%')
.height(80)
.listDirection(Axis.Horizontal)
.scrollBar(BarState.Off)
.friction(1.5)
.lanes(1)
.padding(10)
.edgeEffect(EdgeEffect.None)
.nestedScroll({
scrollForward: NestedScrollMode.SELF_FIRST,
scrollBackward: NestedScrollMode.SELF_FIRST
})
})
}
.vertical(false)
.indicator(false)
.loop(false)
.onChange((index: number) => {
this.activeIndex = index;
// 滑动Swiper,对应的标题居中
this.titleListScroller.scrollToIndex(index, true, ScrollAlign.CENTER);
})
.index(this.activeIndex)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Start)
.padding(16)
}
}
上面的核心代码是:
.nestedScroll({
scrollForward: NestedScrollMode.SELF_FIRST,
scrollBackward: NestedScrollMode.SELF_FIRST
})
它是负责Swiper中的List优先滑动的,不然后会出现数据显示不完整的冲突.
三.在 Index.ets文件中随便找个元素,加入点击功能即可
Text("点我用Swiper实现List优先滑动的实例 ")
.onClick(() => {
this.pathStack.pushPathByName('SwiperListPage', null);
})
到此,你可以把它用在你的项目上了.
更多关于HarmonyOS 鸿蒙Next中用Swiper实现List优先滑动的实例的实战教程也可以访问 https://www.itying.com/category-93-b0.html
学习了,
更多关于HarmonyOS 鸿蒙Next中用Swiper实现List优先滑动的实例的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
学习
在HarmonyOS Next中,Swiper组件默认会拦截触摸事件。要实现List优先滑动,可以使用onTouch事件监听。在Swiper的onTouch事件中,通过事件对象的stopPropagation方法阻止事件冒泡,同时结合List组件的滚动状态进行判断。当List处于可滚动状态时,阻止Swiper的默认滑动行为,使触摸事件优先传递给List。具体实现需在Swiper组件上设置onTouch回调,并在回调中根据条件调用event.stopPropagation()。
这是一个非常典型的在HarmonyOS Next中实现Swiper内嵌List且优先处理List滚动的解决方案。您提供的代码清晰地展示了如何通过nestedScroll属性来解决嵌套滚动冲突问题。
核心要点分析:
-
嵌套滚动配置是关键:
.nestedScroll({ scrollForward: NestedScrollMode.SELF_FIRST, scrollBackward: NestedScrollMode.SELF_FIRST })这个配置确保了当用户在水平List上滑动时,List会优先消耗滚动事件,只有在List滚动到边界后,Swiper才会响应切换页面的操作。
-
双向联动机制:
- 标题List与Swiper通过
activeIndex状态保持同步 - 点击标题时,通过
swiperController.changeIndex(index)切换Swiper页面 - 滑动Swiper时,通过
onChange回调更新标题位置并居中显示
- 标题List与Swiper通过
-
滚动控制优化:
- 使用
Scroller控制标题List的滚动位置 - 设置
friction(1.5)增加List滚动手感 edgeEffect(EdgeEffect.None)禁用边缘效果避免干扰
- 使用
这种实现方式适用于需要横向分类浏览内容的场景,如商品分类浏览、视频分类等。代码结构清晰,组件职责明确,是一个很好的参考示例。

