
鸿蒙JavaUI:PageSlider组件,实现左右无限循环轮播图
一、要点:
1. PageSlider: 提供左右滑动功能。注:目前该组件暂不支持内容循环,该功能需要手动实现。
2. PageSliderProvider: 为PageSlider组件提供页面适配器。
二、实现无限循环的思路
在代码层面,无限循环实际是伪循环。即,尾部拼接一个第一个内容组件,首部拼接一个最后一个内容组件。滑动到首部/尾部时,立刻切换到相应位置。由于速度为非常快,肉眼无法看出,才在应用层面感觉是无限循环。
三、功能拆解
假设:我们有三个图片需要轮播展示,按照顺序应是如下配置:
1. 手指向右滑动,内容向右滚动,实现“左”方向的无限循环
第一步: 在轮播图内容左侧,手动拼接一个“轮播图3”。这样,再继续向右滑动时,给人一种“已经”循环的感觉。注:如果继续滑动,内容时不会动的。
第二步: 使用PageSlider.PageChangedListener监听,获取当前内容的坐标。当坐标为0时,说明已经滚动到了拼接的“轮播图3_拼接”,此时需要立刻切换到“轮播图3”对应的坐标。至此,在理论上,“左”方向的无限循环已经实现。
2. 手指向左滑动动,内容向左滚动,实现“右”方向的无限循环
第一步:在“左”方向无限循环内容拼接的基础上,在右侧手动拼接一个“轮播图1”。这样,向左滑动到“轮播图3”时,再继续滑动,滑动到“轮播图1_拼接”。第二步: 使用PageSlider.PageChangedListener监听,获取当前内容的坐标。当坐标为内容Size - 1时,说明已经滚动到了拼接的“轮播图1_拼接”,此时需要立刻切换到“轮播图1”对应的坐标。至此,在理论上,双向的无限循环已经实现。
3. 单方向自动轮播
自动轮播需要在手指滑动轮播图时,停止轮播,避免与手指滑动发生冲突。当停止手指离开屏幕时,再启动自动轮播。
关键点:
1. 使用定时任务,定时切换PageSlider内容。定时任务需要延迟启动,否则刚加载完成就切换PageSlider内容,有悖常理。
2. 借助Component.TouchEventListener - 触摸监听,该监听可以提供手指按下、多指按下、最后一根手指离开屏幕(关键点)等信息提示。当第一根手指触摸屏幕时,需要关闭定时任务。当最后一根手指离开屏幕时,开启定时任务。实现手动和自动轮播的切换。
四、代码实现
1. xml中添加PageSlider组件
2. 继承PageSliderProvider类
PageSliderProvider的createPageInContainer方法,在PageSlider初始化时调用。因此,需要重写该方法,将我们的组件添加到参数componentContainer中。
3. 组装PageSliderProvider继承类数据 - 轮播图内容
这里需要组装内容前后的拼接内容。
4. 配置PageSlider组件属性
这里需要初始化PageSlider组件的一些属性。
有两个关键点:
1. PageSlider.setCurrentPage(index, true) : 在初始化时调用该方法,组件加载完毕会直接显示指定index的内容,不会有滚动动画。当手动调用时,第二个参数为true,会根据设置的切换时间进行滚动。当第二个参数为false时,会立刻切换到指定的index,不会有滚动动画,这里也是实现首尾接续的关键点。
2. addPageChangedListener: 添加PageSlider组件内容切换监听。
5. PageChangedListener回调中,实现手指无限循环滑动
在onPageChosen回调中,实现切换逻辑。
关键点:
1. 立即切换: setCurrentPage(index, false); false false false....;
1. 由于自动切换中,调用setCurrentPage方法,也会触发回调。需要添加一个boolean类型变量,区分是手动滑动还是自动轮播;
2. 这里不需要判断滑动方向,通过index的极限值[0, size - 1],来切换到对应的内容。
① i = 0: 说明已经滑动到最左侧,需要立刻切换到最后一个内容,即index = size - 1 - 1;注:size - 1: 最后面拼接的第一个内容“轮播图1_拼接”。 size - 1 - 1: 真实的最后一个内容;
② i = size - 1: 说明已经滑动到最右侧,需要立刻切换到第一个内容,即index = 1;注: 0的位置,是拼接的最后一个内容“轮播图3_拼接”。
6. 定时任务实现自动轮播
使用Executors.newSingleThreadScheduledExecutor();延迟线程池,延迟启动轮播任务,避免第一次加载就切换轮播图内容。
关键点:
1. Componet.TouchEventListener(): 通过触摸事件,当有手指触摸组件时,停止轮播任务。当最后一根手指离开屏幕时,重新创建轮播任务,继续自动轮播;
2. 动画切换:setCurrentPage(index, true);这里需要有切换动画,true;
7. 完整的代码
8. 调用方式
9. 工具类
