FloatScreenView:适用于同时存在多种类型View的飘屏场景

项目中的飘屏场景比较多,但出现的数量一般,另外每个场景的view样式不统一,行数不统一,动画时间也不统一,所以对项目中所有飘屏相关做了重构,不管什么飘屏类型只需调用addFloatView即可

原文地址

支持单行飘屏setSingleLine
支持单一动画时间setSingleTime

Alt

/**
 * 飘屏view
 * @author https://github.com/lyldding
 */
class FloatScreenView : FrameLayout {
    private val times = arrayOf(3500, 4000, 4500, 5000, 5500)
    private var mRandom: Random = Random
    private var mIsSingleLine: Boolean = false
    private var mIsSingleTime: Boolean = false

    constructor(context: Context) : super(context)

    constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)

    constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(
        context,
        attributeSet,
        defStyleAttr
    )


    fun addFloatView(view: View) {
        if (measuredHeight <= 0 || measuredWidth <= 0) {
            LogUtils.e("还未初始化")
            return
        }
        if (view.layoutParams == null) {
            view.layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
            )
        }

        val viewSize = SizeUtils.measureView(view)
        val viewHeight = viewSize[1]
        val viewWidth = viewSize[0]

        if (viewHeight > measuredHeight) {
            LogUtils.e("viewHeight > measuredHeight : viewHeight = $viewHeight , measuredHeight = $measuredHeight")
            return
        }

        val top = getViewTop(viewHeight)
        val animX =
            ObjectAnimator.ofFloat(
                view,
                "translationX",
                measuredWidth.toFloat(),
                -viewWidth.toFloat()
            )
        val animY = ObjectAnimator.ofFloat(view, "translationY", top.toFloat(), top.toFloat())
        val animatorSet = AnimatorSet()
        animatorSet.playTogether(animX, animY)
        animatorSet.interpolator = LinearInterpolator()
        val duration = times[if (mIsSingleTime) 0 else mRandom.nextInt(times.size)]
        animatorSet.duration = (duration + duration * viewWidth / measuredWidth).toLong()
        animatorSet.addListener(object : Animator.AnimatorListener {
            override fun onAnimationCancel(animation: Animator?) {
                removeView(view)
            }

            override fun onAnimationEnd(animation: Animator?) {
                removeView(view)
            }

            override fun onAnimationRepeat(animation: Animator?) {
            }

            override fun onAnimationStart(animation: Animator?) {
            }
        })

        if (indexOfChild(view) != -1) {
            removeView(view)
        }
        addView(view)
        animatorSet.start()
    }

    private fun getViewTop(viewHeight: Int): Int {
        var top = 0
        if (mIsSingleLine) {
            top = (measuredHeight - viewHeight) / 2
        } else {
            val lines = measuredHeight / viewHeight
            top = if (lines > 1) (measuredHeight % viewHeight) / 2 else 0
            val lineIndex = mRandom.nextInt(lines)
            top += lineIndex * viewHeight
        }

        return top
    }

    /**
     * @param isSingleLine true 单行
     */
    fun setSingleLine(isSingleLine: Boolean) {
        mIsSingleLine = isSingleLine
    }

    /**
     * @param isSingleTime true 时间固定
     */
    fun setSingleTime(isSingleTime: Boolean) {
        mIsSingleTime = isSingleTime
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章