首页 > 滚动 > > 内容

Android Banner - ViewPager 02

发表时间:2023-04-05 22:35:59 来源:博客园
Android Banner - ViewPager 02

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

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

自动轮播实现如下内容


【资料图】

开始轮播&停止轮播

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

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

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

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

开始&停止轮播

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)    }
通过自定义属性来配置轮播时长,方向
                                                                

读取属性

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()        }    }
标签:

Copyright ©  2015-2022 西方产业网版权所有  备案号:沪ICP备2020036824号-7   联系邮箱:5 626 629 @qq.com