关于HarmonyOS 开发中鸿蒙的无线轮播功能(效果图如下)是一个很常见的功能,在鸿蒙中怎么实现呢?今天写一个demo来记录一下该功能的实现,主要分为“准备工作”,“图片轮播”,“无线轮播”,“运行效果”四个方面进行实现
1. 准备工作
1.1想要实现无线轮播功能需要查看PageSlider和“线程管理”,“线程通信”这个几个知识的准备这个几个知识的准备
1.2图片准备
我们从网上下载几张图片放在resources/base/media目录下(如下如所示)
2. 图片轮播
2.1xml 布局书写
我们新建一个AbilitySlice的界面然后在他的layout布局代码如下
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical">
<PageSlider
ohos:top_margin="10vp"
ohos:id="$+id:page_slider"
ohos:height="300vp"
ohos:width="300vp"
ohos:layout_alignment="horizontal_center"/>
</DirectionalLayout>
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<Integer> list;
private Context mContext;
public TestPageProvider(List<Integer> list, Context context) {
this.list = list;
this.mContext = context;
}
public int getCount() {
return list.size();
}
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;
}
public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) {
componentContainer.removeComponent((Component) o);
}
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<Integer> getData() {
ArrayList<Integer> 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<Integer> list;
private Context mContext;
public TestPageProvider(List<Integer> 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代码
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical">
<PageSlider
ohos:top_margin="10vp"
ohos:id="$+id:page_slider"
ohos:height="300vp"
ohos:width="300vp"
ohos:layout_alignment="horizontal_center"/>
</DirectionalLayout>
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};
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 指示所显示页面的位置偏移像素数。
*/
public void onPageSliding(int i, float v, int i1) {//
}
/**
* 页面幻灯片状态更改时回调
* @param i 指示页面状态。该值可以是0、1或2,分别表示页处于空闲状态、拖动状态或滑动状态。
*/
public void onPageSlideStateChanged(int i) {
}
/**
* 页面滑动时回调
*
* @param i 指示所选页的索引。
*/
public void onPageChosen(int i) {
pos=i;
}
});
}
private ArrayList<Integer> getData() {
ArrayList<Integer> 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);
}
public void processEvent(InnerEvent event) {
getUITaskDispatcher().asyncDispatch(new Runnable() {
public void run() {
pageSlider.setCurrentPage(pos+1);//让pageSlider滑到下一个
InnerEvent normalInnerEvent = InnerEvent.get(0, 0, null);
handler.sendEvent(normalInnerEvent, 1000);//Todo 隔一秒 发送一个消息
}
});
}
}
}
4.4效果如下