Android Banner – ViewPager 02

yizhihongxing

Android Banner - ViewPager 02

现在来给viewpager实现的banenr加上自动轮播

自动轮播的原理,使用handler的延迟消息来实现。

自动轮播实现如下内容

  1. 开始轮播&停止轮播

  2. 可配置轮播时长、轮播方向

  3. 通过自定义属性来配置轮播时长,方向

  4. 感知生命周期,可见时开始轮播,不可见时停止轮播

  5. 感知手指触摸,触摸按下时停止轮播,抬起重新计时

开始&停止轮播

banner对外提供接口,开始轮播

fun startLoop(){
}
fun stopLoop(){
}

定义handler实现轮播

    // 创建handler
    fun startLoop() {
        if (loopHandler == null) {
            loopHandler = Handler(Looper.getMainLooper()) { message ->
                return@Handler when (message.what) {
                    LOOP_NEXT -> {
                        // 定义消息处理
                        loopNext()
                        true
                    }
                    else -> false
                }
            }
        }
        // 移除正在轮播的消息
        loopHandler?.removeMessages(LOOP_NEXT)
        // 发送延迟轮播的消息
        loopHandler?.sendEmptyMessageDelayed(LOOP_NEXT, mLoopDuration)
    }

    private fun loopNext() {
        val count = adapter?.count ?: 0
        // 当pager数量为0或者1时,不用轮播
        if (count in 0..1) return
        val curr = when (currentItem) {
            in 0..count - 2 -> {
                currentItem + 1
            }
            count - 1 -> 0
            else -> 0
        }
        setCurrentItem(curr, true)
        loopHandler?.sendEmptyMessageDelayed(LOOP_NEXT, mLoopDuration)
    }

可配置轮播时长、轮播方向

定义接口

    /**
     * 设置轮播时长,有效数据必须大于0,否则使用默认数据5S
     * @param duration Long
     */
    fun setLoopDuration(duration: Long) {
        if (duration < 0) {
            // 小于0的数据认为是非法数据,使用默认设置
            return
        }
        this.mLoopDuration = duration
    }

    /**
     * 设置轮播方向,默认[LoopOrientation.LTR]
     * @param orientation Int
     */
    fun setLoopOrientation(@LoopOrientation orientation: Int) {
        this.mLoopOrientation = orientation
    }

轮播处理参数

    private fun loopNext() {
        val count = adapter?.count ?: 0
        // 当pager数量为0或者1时,不用轮播
        if (count in 0..1) return
        val curr = when (mLoopOrientation) {
            LoopOrientation.RTL -> {
                when (currentItem) {
                    in 1..count - 1 -> {
                        currentItem - 1
                    }
                    else -> count - 1 // 0
                }
            }
            else -> {
                when (currentItem) {
                    in 0..count - 2 -> {
                        currentItem + 1
                    }
                    else -> 0 // count - 1
                }
            }
        }
        setCurrentItem(curr, true)
        mLoopHandler?.sendEmptyMessageDelayed(LOOP_NEXT, mLoopDuration)
    }

通过自定义属性来配置轮播时长,方向

<resources>
    <declare-styleable name="VPBanner">
        <attr name="vp_loop_duration" format="integer" />
        <attr name="vp_loop_orientation" format="enum" >
            <enum name="ltr" value="1" />
            <enum name="rtl" value="0" />
        </attr>
        <attr name="vp_auto_loop" format="boolean" />
    </declare-styleable>
</resources>

读取属性

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        // 读取自定义的属性
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.VPBanner)
        this.mLoopDuration = typedArray.getInt(
            R.styleable.VPBanner_vp_loop_duration,
            DEFAULT_LOOP_DURATION
        ).toLong()
        this.mAutoLoop = typedArray.getBoolean(R.styleable.VPBanner_vp_auto_loop, false)
        this.mLoopOrientation =
            typedArray.getInt(R.styleable.VPBanner_vp_loop_orientation, LoopOrientation.LTR)

        Log.d("VPBanner","ld:${this.mLoopDuration},al:$mAutoLoop,lo:$mLoopOrientation")

        typedArray?.recycle()
    }

感知生命周期,可见时开始轮播,不可见时停止轮播

实现生命周期感知

class VPBanner : ViewPager, DefaultLifecycleObserver {
    override fun onResume(owner: LifecycleOwner) {
        Log.d(TAG, "onResume")
        if (this.mAutoLoop) {
            startLoop()
        }
    }

    override fun onPause(owner: LifecycleOwner) {
        Log.d(TAG, "onResume")
        stopLoop()
    }
}

感知手指触摸,触摸按下时停止轮播,抬起重新计时

重写onTouchEvent方法

   override fun onTouchEvent(ev: MotionEvent?): Boolean {
        when (ev?.action) {
            MotionEvent.ACTION_DOWN -> stopLoop()
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                prepareLoop()
            }
        }
        return super.onTouchEvent(ev)
    }

    private fun prepareLoop() {
        if (this.mAutoLoop && this.mResumed) {
            startLoop()
        }
    }

原文链接:https://www.cnblogs.com/android-lol/p/17291146.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android Banner – ViewPager 02 - Python技术站

(0)
上一篇 2023年4月17日
下一篇 2023年4月17日

相关文章

  • 【FAQ】申请运动健康服务验证环节常见问题及解答

    华为 HMS Core 运动健康服务(HUAWEI Health Kit)提供原子化数据开放。应用在获取用户数据授权后,可通过接口访问运动健康数据,对用户数据进行读写等操作,为用户提供运动健康类数据服务。 开发者应用在开发和测试阶段访问用户运动或健康数据时,会有100个用户的数量限制,需要通过“申请验证”来解除此限制。本文汇总了申请验证的相关问题,并给出了详…

    Android 2023年4月18日
    00
  • Android报”IllegalStateException”如何解决?

    下面我将详细讲解Android报”IllegalStateException”异常的原因和解决办法。 异常原因 “IllegalStateException”异常表示当前的操作状态不合法,通常是由于程序在使用某个资源时,资源的状态发生了不合法的变化导致的。在Android开发中,常见的”IllegalStateException”异常包括: Fragment…

    Android 2023年4月3日
    00
  • 关于移动开发平台,你想知道的这些事

    近年来,移动开发平台如雨后春笋般蓬勃发展。这诸多的移动开发平台常常令人面临选择恐惧。今天就来同大家一块盘点一下,看看这些移动开发平台都有什么特点与优势,希望为有需要的开发者提供一定的参考。   需要特别说明的是,这里提到的移动开发平台与 Flutter、React Native 等移动开发框架还有一定的区别,更多是指为开发者提供从开发、测试、发布和运营整个生…

    Android 2023年4月18日
    00
  • react-native-web跨平台实战

    1.背景  随着对用户体验要求的提高,产品要求提升用户体验,多端体验一致。随着多端相同的业务也越来越多,需要投入IOS,Android,Web多端开发人员。这就迫切的需要一种一次开发同时使用在Android ,IOS ,Web的解决方案。达到降本增效的目的。在几个小业面尝试,总结经验后,我们采用react-native-web多端适配。   2.问题 a.对…

    Android 2023年4月18日
    00
  • 鲸鸿动能流量变现服务中国大陆地区测试流程

    一、鲸鸿动能流量变现服务前置说明 1.接入鲸鸿动能平台的应用需在应用市场上架。 2.与华为联运的游戏应用和快游戏禁止接入鲸鸿动能以外的其他广告内容/插件/SDK等。 3.中国大陆地区仅支持企业认证用户使用流量变现服务。 4.支持的设备限制: 5.媒体接入流程: 二、媒体服务平台 数据管理 【首页】或【我的报表】,支持查看预估收益以及广告展示数据。 流量变现服…

    Android 2023年4月18日
    00
  • Android报”ConcurrentModificationException”如何解决?

    针对Android应用中出现”ConcurrentModificationException”异常的原因和解决办法,我来进行详细的讲解。 原因 该异常通常在同时操作同一个数据结构(如List、Map、Set等)时出现,因为在多线程操作时,如果数据结构正在被一个线程修改,而另一个线程正在尝试遍历它,那么就会引发”ConcurrentModificationEx…

    Android 2023年4月3日
    00
  • Android报”NoClassDefFoundError”如何解决?

    “NoClassDefFoundError”异常表示在运行时,Java Virtual Machine(JVM)试图根据一个类型的信息加载类,但是该类在编译时存在,而在运行时却无法被找到。这个异常通常表示在编译阶段和运行阶段之间出现了不匹配的问题,例如将JAR文件添加到build path中,但该JAR文件中的某些类在应用程序运行时无法找到。 以下是两种可能…

    Android 2023年4月3日
    00
  • 免费广告效果监测服务,实现全链路营销效果跟踪

    广告主们都希望以低预算获得更高的广告投放收益,在投放广告后,想要了解高回报的渠道,往往需要收集并分析繁杂的数据,耗时耗力。通过广告监测,广告主可以准确的追溯用户渠道来源,看到不同流量的用户价值,分析广告投放效果,从而指导广告的出价和投放素材的优化,把预算花在刀刃上。 针对广告主们广告监测的需求,华为分析服务提供免费的广告监测能力,为有广告监测需求的广告主节省…

    Android 2023年4月17日
    00
合作推广
合作推广
分享本页
返回顶部