鸿蒙JavaUI:PageSlider组件,实现左右无限循环轮播图

deanyuancn
发布于 2021-5-7 18:32
1.9w浏览
0收藏

一、要点:


1. PageSlider: 提供左右滑动功能。注:目前该组件暂不支持内容循环,该功能需要手动实现。
2. PageSliderProvider: 为PageSlider组件提供页面适配器。


二、实现无限循环的思路
在代码层面,无限循环实际是伪循环。即,尾部拼接一个第一个内容组件,首部拼接一个最后一个内容组件。滑动到首部/尾部时,立刻切换到相应位置。由于速度为非常快,肉眼无法看出,才在应用层面感觉是无限循环。


三、功能拆解
假设:我们有三个图片需要轮播展示,按照顺序应是如下配置:鸿蒙JavaUI:PageSlider组件,实现左右无限循环轮播图 -鸿蒙开发者社区

1.  手指向右滑动,内容向右滚动,实现“左”方向的无限循环

第一步: 在轮播图内容左侧,手动拼接一个“轮播图3”。这样,再继续向右滑动时,给人一种“已经”循环的感觉。注:如果继续滑动,内容时不会动的。

鸿蒙JavaUI:PageSlider组件,实现左右无限循环轮播图 -鸿蒙开发者社区

第二步: 使用PageSlider.PageChangedListener监听,获取当前内容的坐标。当坐标为0时,说明已经滚动到了拼接的“轮播图3_拼接”,此时需要立刻切换到“轮播图3”对应的坐标。至此,在理论上,“左”方向的无限循环已经实现。鸿蒙JavaUI:PageSlider组件,实现左右无限循环轮播图 -鸿蒙开发者社区

2. 手指向左滑动动,内容向左滚动,实现“右”方向的无限循环

第一步:在“左”方向无限循环内容拼接的基础上,在右侧手动拼接一个“轮播图1”。这样,向左滑动到“轮播图3”时,再继续滑动,滑动到“轮播图1_拼接”。鸿蒙JavaUI:PageSlider组件,实现左右无限循环轮播图 -鸿蒙开发者社区第二步: 使用PageSlider.PageChangedListener监听,获取当前内容的坐标。当坐标为内容Size - 1时,说明已经滚动到了拼接的“轮播图1_拼接”,此时需要立刻切换到“轮播图1”对应的坐标。至此,在理论上,双向的无限循环已经实现。鸿蒙JavaUI:PageSlider组件,实现左右无限循环轮播图 -鸿蒙开发者社区

3. 单方向自动轮播


自动轮播需要在手指滑动轮播图时,停止轮播,避免与手指滑动发生冲突。当停止手指离开屏幕时,再启动自动轮播。

关键点:

1. 使用定时任务,定时切换PageSlider内容。定时任务需要延迟启动,否则刚加载完成就切换PageSlider内容,有悖常理。

2. 借助Component.TouchEventListener - 触摸监听,该监听可以提供手指按下、多指按下、最后一根手指离开屏幕(关键点)等信息提示。当第一根手指触摸屏幕时,需要关闭定时任务。当最后一根手指离开屏幕时,开启定时任务。实现手动和自动轮播的切换。

 

四、代码实现

 

1. xml中添加PageSlider组件

<!-- 顶部轮播图 -->
<PageSlider
    ohos:id="$+id:shoot_ability_page_slider"
    ohos:height="300vp"
    ohos:width="match_content"
    />
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

 

2.  继承PageSliderProvider类

PageSliderProvider的createPageInContainer方法,在PageSlider初始化时调用。因此,需要重写该方法,将我们的组件添加到参数componentContainer中。

import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.Image;
import ohos.agp.components.PageSliderProvider;

import java.util.List;

/**
 * Image组件适配器
 *
 * @author      殷冬
 * @date        2021-02-19
 * @version     1.0.0
 */
public class BannerProvider extends PageSliderProvider {

    private List<Image> listData;


    public BannerProvider(List<Image> listData) {
        this.listData = listData;
    }

    @Override
    public int getCount() {
        return listData.size();
    }


    @Override
    public Object createPageInContainer(ComponentContainer componentContainer, int i) {
        Object obj = listData.get(i);
        componentContainer.addComponent((Component) obj);
        return obj;
    }

    @Override
    public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) {
        componentContainer.removeComponent(listData.get(i));
    }

    @Override
    public boolean isPageMatchToObject(Component component, Object o) {
        return component == o;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.

 

3.  组装PageSliderProvider继承类数据 - 轮播图内容

这里需要组装内容前后的拼接内容。

/**
 * 添加数据
 *
 * @param  imageId      图片资源Id
 */
public ShootMainTopBanner setImages(Integer ... imageId){
    List<Image> data = new ArrayList<>();
    for(Integer id : imageId){
        Image image = new Image(abilitySlice.getContext());
        // 设置image的宽高,并且图片充满整个image
        image.setLayoutConfig(new ComponentContainer.LayoutConfig(ScreenPixelsUtil.getDisplayWidthInPx(abilitySlice.getContext()), ComponentContainer.LayoutConfig.MATCH_PARENT));
        image.setScaleMode(Image.ScaleMode.STRETCH);
        image.setPixelMap(id);
        data.add(image);
    }
    // 组装数据,格式 3 1 2 3 1, 实现自动单向滚动和手动双向滚动逻辑,中间123是展示数据,左右3 1 为实现连续滚动的效果数据
    images.add(data.get(data.size() - 1));
    images.addAll(data);
    images.add(data.get(0));
    this.dataSize = images.size();
    return this;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.

 

4. 配置PageSlider组件属性  

这里需要初始化PageSlider组件的一些属性。

 

有两个关键点:

1. PageSlider.setCurrentPage(index, true) : 在初始化时调用该方法,组件加载完毕会直接显示指定index的内容,不会有滚动动画。当手动调用时,第二个参数为true,会根据设置的切换时间进行滚动。当第二个参数为false时,会立刻切换到指定的index,不会有滚动动画,这里也是实现首尾接续的关键点。

2. addPageChangedListener: 添加PageSlider组件内容切换监听。

/**
 * 初始化轮播图
 */
public void start(){
    globalTaskDispatcher = abilitySlice.getGlobalTaskDispatcher(TaskPriority.DEFAULT);
    BannerProvider bannerProvider = new BannerProvider(images);
    pageSlider = (PageSlider) abilitySlice.findComponentById(ResourceTable.Id_shoot_ability_page_slider);
    pageSlider.setProvider(bannerProvider);
    // 设置初始页面平滑滚动
    pageSlider.setCurrentPage(index, true);
    // 设置滚动方向
    pageSlider.setOrientation(Component.HORIZONTAL);
    // 设置切换时间,值越大切换速度越慢
    pageSlider.setPageSwitchTime(pageSwitchTime);
    // 启用页面滑动
    pageSlider.setSlidingPossible(true);
    // 添加监听
    pageSlider.addPageChangedListener(new ChangedListener());
    // 启动自动切换
    this.startPlaying();
    // 添加监听
    this.addTouchEventListener(pageSlider);
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.

 

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_拼接”。

/**
 * 切换监听
 */
class ChangedListener implements PageSlider.PageChangedListener{

    /**
     *  选择新页面的回调
     *
     * @param i     指示所显示页的位置索引。
     * @param v     指示页的位置偏移量。值范围是(0,1]。0表示显示相同的页面; 1表示显示目标页面。
     * @param i1    指示所显示页面的位置偏移像素数。
     */
    @Override
    public void onPageSliding(int i, float v, int i1) {
        HiLog.info(LOG, "--------------------onPageSliding:  i: %{public}s; v: %{public}s; i1: %{public}s;", i, v, i1);
    }

    /**
     * 页面幻灯片状态更改时回调
     * @param i     指示页面状态。该值可以是0、1或2,分别表示页处于空闲状态、拖动状态或滑动状态。
     */
    @Override
    public void onPageSlideStateChanged(int i) {
        HiLog.info(LOG, "--------------------onPageSlideStateChanged:   i: %{public}s", i);
    }

    /**
     * 页面滑动时回调
     *
     * @param i     指示所选页的索引。
     */
    @Override
    public void onPageChosen(int i) {
        HiLog.info(LOG, "--------------------onPageChosen: i: %{public}s", i);
        // 更新index
        index = i;
        // 处理手动滑动逻辑
        if(! isAutoSlide){
            // 向左滑动,轮播图向右滚动
            if(index == dataSize - 1){
                index = 1;
                pageSlider.setCurrentPage(index, false);
            }
            // 向右滑动,轮播图向左滚动
            if(index == 0){
                index = images.size() - 2;
                pageSlider.setCurrentPage(index, false);
            }
        }
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.

 

6. 定时任务实现自动轮播

使用Executors.newSingleThreadScheduledExecutor();延迟线程池,延迟启动轮播任务,避免第一次加载就切换轮播图内容。

 

关键点:

1. Componet.TouchEventListener(): 通过触摸事件,当有手指触摸组件时,停止轮播任务。当最后一根手指离开屏幕时,重新创建轮播任务,继续自动轮播;

2. 动画切换:setCurrentPage(index, true);这里需要有切换动画,true;

/**
 * 定时器,自动切换图片
 */
private void startPlaying(){
    // 初始化线程池
    this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
    // 设置线程池
    this.scheduledExecutorService.scheduleWithFixedDelay(automaticSwitching, TIME_INTERVAL, TIME_INTERVAL, TimeUnit.MILLISECONDS);
}

/**
 * 停止轮播释放资源
 */
public void stopPlaying() {
    scheduledExecutorService.shutdown();
}

/**
 * 轮播图触摸事件
 *
 * @param pageSlider
 */
public void addTouchEventListener(PageSlider pageSlider){
    pageSlider.setTouchEventListener(new Component.TouchEventListener() {
        @Override
        public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
            int action = touchEvent.getAction();
            // 最后一根手指抬起、取消、没有触摸活动时, 启动定时器
            if(action == PRIMARY_POINT_UP || action == CANCEL || action == NONE) {
                isAutoSlide = true;
                startPlaying();
            } else if (action == PRIMARY_POINT_DOWN) {
                isAutoSlide = false;
                // 存在触摸时,停止自动切换
                stopPlaying();
            }
            return true;
        }
    });
}

/**
 * 切换轮播图内容
 */
class AutomaticSwitching implements Runnable{
    @Override
    public void run() {
        abilitySlice.getUITaskDispatcher().asyncDispatch(() -> {
            index++;
            pageSlider.setCurrentPage(index, true);
            if(index == dataSize - 1){
                // 切换到第一个位置, 且立即切换
                globalTaskDispatcher.asyncDispatch(new SlideShowTaskLast());
            }
        });
    }
}

class SlideShowTaskLast implements Runnable{
    @Override
    public void run() {
        try{
            Thread.sleep(pageSwitchTime);
        }catch (Exception e){

        }
        abilitySlice.getUITaskDispatcher().syncDispatch(() -> {
            index = 1;
            pageSlider.setCurrentPage(index, false);
        });
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.

 

7. 完整的代码


package com.yindong.splitlens.pageability.shoot.main;

import com.yindong.common.enums.HiLogEnum;
import com.yindong.common.utils.ScreenPixelsUtil;
import com.yindong.splitlens.ResourceTable;
import com.yindong.splitlens.pageability.shoot.main.components.BannerProvider;
import ohos.aafwk.ability.AbilitySlice;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.Image;
import ohos.agp.components.PageSlider;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.multimodalinput.event.TouchEvent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static ohos.multimodalinput.event.TouchEvent.*;
import static ohos.multimodalinput.event.TouchEvent.PRIMARY_POINT_DOWN;

/**
 * 顶部轮播图
 *
 * @author      殷冬
 * @date        2021-02-19
 * @version     1.0.0
 */
public class ShootMainTopBanner {

    private static final HiLogLabel LOG = new HiLogLabel(HiLog.LOG_APP, HiLogEnum.LOG_DOMAIN.getCode(), ShootMainTopBanner.class.getName());

    private AbilitySlice abilitySlice;

    /**
     * 处理轮播图收尾链接线程
     */
    private TaskDispatcher globalTaskDispatcher;

    /**
     * 线程池
     */
    private ScheduledExecutorService scheduledExecutorService;

    /**
     * 默认展示第一个, 跳过第一个虚拟展示数据
     */
    private Integer index = 1;

    /**
     * 自动切换时间
     */
    private static final Integer TIME_INTERVAL = 5000;

    /**
     * 切换过程时间,单位毫秒
     */
    private Integer pageSwitchTime = 500;

    /**
     * 轮播数据长度
     */
    private Integer dataSize;

    /**
     * 轮播图片内容
     */
    private List<Image> images = new ArrayList<>();

    private PageSlider pageSlider;

    /**
     * 是否处于自动轮播状态
     */
    private boolean isAutoSlide = true;

    /**
     * 自动切换任务
     */
    private AutomaticSwitching automaticSwitching = new AutomaticSwitching();

    public ShootMainTopBanner(AbilitySlice abilitySlice){
        this.abilitySlice = abilitySlice;
    }

    /**
     * 添加数据
     *
     * @param  imageId      图片资源Id
     */
    public ShootMainTopBanner setImages(Integer ... imageId){
        List<Image> data = new ArrayList<>();
        for(Integer id : imageId){
            Image image = new Image(abilitySlice.getContext());
            // 设置image的宽高,并且图片充满整个image
            image.setLayoutConfig(new ComponentContainer.LayoutConfig(ScreenPixelsUtil.getDisplayWidthInPx(abilitySlice.getContext()), ComponentContainer.LayoutConfig.MATCH_PARENT));
            image.setScaleMode(Image.ScaleMode.STRETCH);
            image.setPixelMap(id);
            data.add(image);
        }
        // 组装数据,格式 3 1 2 3 1, 实现自动单向滚动和手动双向滚动逻辑,中间123是展示数据,左右3 1 为实现连续滚动的效果数据
        images.add(data.get(data.size() - 1));
        images.addAll(data);
        images.add(data.get(0));
        this.dataSize = images.size();
        return this;
    }

    /**
     * 初始化轮播图
     */
    public void start(){
        globalTaskDispatcher = abilitySlice.getGlobalTaskDispatcher(TaskPriority.DEFAULT);
        BannerProvider bannerProvider = new BannerProvider(images);
        pageSlider = (PageSlider) abilitySlice.findComponentById(ResourceTable.Id_shoot_ability_page_slider);
        pageSlider.setProvider(bannerProvider);
        // 设置初始页面平滑滚动
        pageSlider.setCurrentPage(index, true);
        // 设置滚动方向
        pageSlider.setOrientation(Component.HORIZONTAL);
        // 设置切换时间,值越大切换速度越慢
        pageSlider.setPageSwitchTime(pageSwitchTime);
        // 启用页面滑动
        pageSlider.setSlidingPossible(true);
        // 添加监听
        pageSlider.addPageChangedListener(new ChangedListener());
        // 启动自动切换
        this.startPlaying();
        // 添加监听
        this.addTouchEventListener(pageSlider);
    }

    /**
     * 定时器,自动切换图片
     */
    private void startPlaying(){
        // 初始化线程池
        this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        // 设置线程池
        this.scheduledExecutorService.scheduleWithFixedDelay(automaticSwitching, TIME_INTERVAL, TIME_INTERVAL, TimeUnit.MILLISECONDS);
    }

    /**
     * 停止轮播释放资源
     */
    public void stopPlaying() {
        scheduledExecutorService.shutdown();
    }

    /**
     * 轮播图触摸事件
     *
     * @param pageSlider
     */
    public void addTouchEventListener(PageSlider pageSlider){
        pageSlider.setTouchEventListener(new Component.TouchEventListener() {
            @Override
            public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                int action = touchEvent.getAction();
                // 最后一根手指抬起、取消、没有触摸活动时, 启动定时器
                if(action == PRIMARY_POINT_UP || action == CANCEL || action == NONE) {
                    isAutoSlide = true;
                    startPlaying();
                } else if (action == PRIMARY_POINT_DOWN) {
                    isAutoSlide = false;
                    // 存在触摸时,停止自动切换
                    stopPlaying();
                }
                return true;
            }
        });
    }

    /**
     * 切换轮播图内容
     */
    class AutomaticSwitching implements Runnable{
        @Override
        public void run() {
            abilitySlice.getUITaskDispatcher().asyncDispatch(() -> {
                index++;
                pageSlider.setCurrentPage(index, true);
                if(index == dataSize - 1){
                    // 切换到第一个位置, 且立即切换
                    globalTaskDispatcher.asyncDispatch(new SlideShowTaskLast());
                }
            });
        }
    }

    class SlideShowTaskLast implements Runnable{
        @Override
        public void run() {
            try{
                Thread.sleep(pageSwitchTime);
            }catch (Exception e){

            }
            abilitySlice.getUITaskDispatcher().syncDispatch(() -> {
                index = 1;
                pageSlider.setCurrentPage(index, false);
            });
        }
    }

    /**
     * 切换监听
     */
    class ChangedListener implements PageSlider.PageChangedListener{

        /**
         *  选择新页面的回调
         *
         * @param i     指示所显示页的位置索引。
         * @param v     指示页的位置偏移量。值范围是(0,1]。0表示显示相同的页面; 1表示显示目标页面。
         * @param i1    指示所显示页面的位置偏移像素数。
         */
        @Override
        public void onPageSliding(int i, float v, int i1) {
            HiLog.info(LOG, "--------------------onPageSliding:  i: %{public}s; v: %{public}s; i1: %{public}s;", i, v, i1);
        }

        /**
         * 页面幻灯片状态更改时回调
         * @param i     指示页面状态。该值可以是0、1或2,分别表示页处于空闲状态、拖动状态或滑动状态。
         */
        @Override
        public void onPageSlideStateChanged(int i) {
            HiLog.info(LOG, "--------------------onPageSlideStateChanged:   i: %{public}s", i);
        }

        /**
         * 页面滑动时回调
         *
         * @param i     指示所选页的索引。
         */
        @Override
        public void onPageChosen(int i) {
            HiLog.info(LOG, "--------------------onPageChosen: i: %{public}s", i);
            // 更新index
            index = i;
            // 处理手动滑动逻辑
            if(! isAutoSlide){
                // 向左滑动,轮播图向右滚动
                if(index == dataSize - 1){
                    index = 1;
                    pageSlider.setCurrentPage(index, false);
                }
                // 向右滑动,轮播图向左滚动
                if(index == 0){
                    index = images.size() - 2;
                    pageSlider.setCurrentPage(index, false);
                }
            }
        }
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.
  • 248.
  • 249.
  • 250.
  • 251.
  • 252.
  • 253.
  • 254.
  • 255.
  • 256.
  • 257.
  • 258.
  • 259.
  • 260.
  • 261.
  • 262.
  • 263.

 

8. 调用方式

// 初始化轮播图
ShootMainTopBanner shootMainTopBanner = new ShootMainTopBanner(abilitySlice);
shootMainTopBanner.setImages(ResourceTable.Media_shoot_main_banner_1,
        ResourceTable.Media_shoot_main_banner_2,
        ResourceTable.Media_shoot_main_banner_3)
        .start();
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

 

9. 工具类

/**
 * 获取屏幕真实宽度
 *
 * @param context       上下文
 * @return
 */
public static int getDisplayWidthInPx(Context context) {
    Display display = DisplayManager.getInstance().getDefaultDisplay(context).get();
    Point point = new Point();
    display.getRealSize(point);
    return (int) point.getPointX();
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

 

已于2021-5-7 18:32:44修改
收藏
回复
举报


回复
    相关推荐