【Harmony OS】【JAVA UI】鸿蒙怎么实现无限轮播功能
关于HarmonyOS 开发中鸿蒙的无线轮播功能(效果图如下)是一个很常见的功能,在鸿蒙中怎么实现呢?今天写一个demo来记录一下该功能的实现,主要分为“准备工作”,“图片轮播”,“无线轮播”,“运行效果”四个方面进行实
1. 准备工作
1.1想要实现无线轮播功能需要查看PageSlider和“线程管理”,“线程通信”这个几个知识的准备
1.2图片准备
我们从网上下载几张图片放在resources/base/media目录下(如下如所示)
2. 图片轮播
2.1xml 布局书写
我们新建一个AbilitySlice的界面然后在他的layout布局代码如下
2.2书写TestPageProvider
这个可以参考HarmonyOS官网的TestPageProvider(具体代码如下)
package com.harmony.alliance.mydemo.adapter; import com.harmony.alliance.mydemo.ResourceTable;import ohos.agp.colors.RgbColor;import ohos.agp.components.*;import ohos.agp.components.element.ShapeElement;import ohos.agp.utils.Color;import ohos.agp.utils.TextAlignment;import ohos.app.Context; import java.util.List;public class TestPageProvider extends PageSliderProvider { // 数据源,每个页面对应list中的一项 private List list; private Context mContext; public TestPageProvider(List list, Context context) { this.list = list; this.mContext = context; } @Override public int getCount() { return list.size(); } @Override public Object createPageInContainer(ComponentContainer componentContainer, int i) { Image image = new Image(mContext); image.setPixelMap(list.get(i)); image. setLayoutConfig( new StackLayout.LayoutConfig( ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT )); image.setScaleMode(Image.ScaleMode.STRETCH); componentContainer.addComponent(image); return image; } @Override public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) { componentContainer.removeComponent((Component) o); } @Override public boolean isPageMatchToObject(Component component, Object o) { return true; }}
2.3写abilitySlice文件
在abilitySlice的Onstart的方中进行如下查找组件和初始化TestPageProvider和设置page缓存(具体代码如下)
protected void onStart(Intent intent) { super.onStart(intent); setUIContent(ResourceTable.Layout_ad_slot_pager); pageSlider = (PageSlider) findComponentById(ResourceTable.Id_page_slider);//查找组件 //todo 初始化mTestPageProvider TestPageProvider mTestPageProvider= new TestPageProvider(getData(), this); pageSlider.setProvider(mTestPageProvider); //todo 设置缓存page pageSlider.setPageCacheSize(4); eventRunner = EventRunner.create("TestRunner"); }//todo 设置数据源private ArrayList getData() { ArrayList dataItems = new ArrayList(); for(int i=0;i<1024*10;i++){ dataItems.add(images[i%4]); } return dataItems; }
效果图如下
3. 无限轮播
我们PagerSlider功能已经实现了,让PagerSlider进行滑动我们可以调用setCurrentPage的方法进行图片滑动,我们可以参考EventHandler这篇文章,没隔一秒钟进行处罚一下这个定时器,
3.1 实现EventHandler的类代码如下
private class TestEventHandler extends EventHandler { private TestEventHandler(EventRunner runner) { super(runner); } @Override public void processEvent(InnerEvent event) { getUITaskDispatcher().asyncDispatch(new Runnable() { @Override public void run() { pageSlider.setCurrentPage(pos+1);//让pageSlider滑到下一个 InnerEvent normalInnerEvent = InnerEvent.get(0, 0, null); handler.sendEvent(normalInnerEvent, 1000);//Todo 隔一秒 发送一个消息 } }); } }
3.2在Onstart中触发计时器功能
//创建EventRunner eventRunner = EventRunner.create("TestRunner"); //初始化TestEventHandler handler = new TestEventHandler(eventRunner); InnerEvent normalInnerEvent = InnerEvent.get(0, 0, null); handler.sendEvent(normalInnerEvent, 1000);//发送消息
3.3监听PagerSlider的滑动监听,当手动滑动的时候,重写统计一下索引(代码如下)
pageSlider.addPageChangedListener(new PageSlider.PageChangedListener() { /** * 选择新页面的回调 * * @param i 指示所显示页的位置索引。 * @param v 指示页的位置偏移量。值范围是(0,1]。0表示显示相同的页面; 1表示显示目标页面。 * @param i1 指示所显示页面的位置偏移像素数。 */ @Override public void onPageSliding(int i, float v, int i1) {// } /** * 页面幻灯片状态更改时回调 * @param i 指示页面状态。该值可以是0、1或2,分别表示页处于空闲状态、拖动状态或滑动状态。 */ @Override public void onPageSlideStateChanged(int i) { } /** * 页面滑动时回调 * * @param i 指示所选页的索引。 */ @Override public void onPageChosen(int i) { pos=i; } });
4. 运行效果图
4.1全部代码如下
TestPageProvider代码
package com.harmony.alliance.mydemo.adapter; import com.harmony.alliance.mydemo.ResourceTable;import ohos.agp.colors.RgbColor;import ohos.agp.components.*;import ohos.agp.components.element.ShapeElement;import ohos.agp.utils.Color;import ohos.agp.utils.TextAlignment;import ohos.app.Context; import java.util.List;public class TestPageProvider extends PageSliderProvider { // 数据源,每个页面对应list中的一项 private List list; private Context mContext; public TestPageProvider(List list, Context context) { this.list = list; this.mContext = context; } @Override public int getCount() { return list.size(); } @Override public Object createPageInContainer(ComponentContainer componentContainer, int i) { Image image = new Image(mContext); image.setPixelMap(list.get(i)); image. setLayoutConfig( new StackLayout.LayoutConfig( ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT )); image.setScaleMode(Image.ScaleMode.STRETCH); componentContainer.addComponent(image); return image; } @Override public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) { componentContainer.removeComponent((Component) o); } @Override public boolean isPageMatchToObject(Component component, Object o) { return true; }}
4.2xml代码
4.3abilitySlice代码如下
package com.harmony.alliance.mydemo.slice; import com.harmony.alliance.mydemo.ResourceTable;import com.harmony.alliance.mydemo.adapter.TestPageProvider;import com.harmony.alliance.mydemo.utils.HiLogUtils;import ohos.aafwk.ability.AbilitySlice;import ohos.aafwk.content.Intent;import ohos.agp.components.PageSlider;import ohos.eventhandler.EventHandler;import ohos.eventhandler.EventRunner;import ohos.eventhandler.InnerEvent; import java.util.ArrayList; public class AdSlotPager extends AbilitySlice { private PageSlider pageSlider; private int pos=0; private TestEventHandler handler; private EventRunner eventRunner; private Integer[] images=new Integer[]{ResourceTable.Media_once,ResourceTable.Media_two,ResourceTable.Media_three,ResourceTable.Media_four}; @Override protected void onStart(Intent intent) { super.onStart(intent); setUIContent(ResourceTable.Layout_ad_slot_pager); pageSlider = (PageSlider) findComponentById(ResourceTable.Id_page_slider);//查找组件 //todo 初始化mTestPageProvider TestPageProvider mTestPageProvider= new TestPageProvider(getData(), this); pageSlider.setProvider(mTestPageProvider); //todo 设置缓存page pageSlider.setPageCacheSize(4); //创建EventRunner eventRunner = EventRunner.create("TestRunner"); //初始化TestEventHandler handler = new TestEventHandler(eventRunner); InnerEvent normalInnerEvent = InnerEvent.get(0, 0, null); handler.sendEvent(normalInnerEvent, 1000);//发送消息 pageSlider.addPageChangedListener(new PageSlider.PageChangedListener() { /** * 选择新页面的回调 * * @param i 指示所显示页的位置索引。 * @param v 指示页的位置偏移量。值范围是(0,1]。0表示显示相同的页面; 1表示显示目标页面。 * @param i1 指示所显示页面的位置偏移像素数。 */ @Override public void onPageSliding(int i, float v, int i1) {// } /** * 页面幻灯片状态更改时回调 * @param i 指示页面状态。该值可以是0、1或2,分别表示页处于空闲状态、拖动状态或滑动状态。 */ @Override public void onPageSlideStateChanged(int i) { } /** * 页面滑动时回调 * * @param i 指示所选页的索引。 */ @Override public void onPageChosen(int i) { pos=i; } }); } private ArrayList getData() { ArrayList dataItems = new ArrayList(); for(int i=0;i<1024*10;i++){ dataItems.add(images[i%4]); } return dataItems; } private class TestEventHandler extends EventHandler { private TestEventHandler(EventRunner runner) { super(runner); } @Override public void processEvent(InnerEvent event) { getUITaskDispatcher().asyncDispatch(new Runnable() { @Override public void run() { pageSlider.setCurrentPage(pos+1);//让pageSlider滑到下一个 InnerEvent normalInnerEvent = InnerEvent.get(0, 0, null); handler.sendEvent(normalInnerEvent, 1000);//Todo 隔一秒 发送一个消息 } }); } } }
4.4效果如下
更多相关学习资料:
https://developer.huawei.com/consumer/cn/forum/topic/0202779034289830523?fid=0102683795438680754?ha_source=zzh