Android自定义可控制速度的跑马灯

作者: Android师哥 | 来源:发表于2020-02-06 13:50 被阅读0次
    NightRain.png

    背景

    原生的TextView是支持跑马灯效果的,但是在项目中实际用了之后,达不到需求,原因是内容滚动太慢,速度无法调节。因此,需要自定义一个可以调节速度的跑马灯。

    思路

    目前实现的思路是对文本内容不断地重绘,同时改变每次重绘的坐标,来在视觉上达到内容在滚动的效果。缺点是如果每次改变的坐标差值太大,会有明显的卡顿效果。经过调试,下面源码中的速度感觉还可以接受,如果有特殊需求,自行在调试一下。

    源码

    class CustomMarqueeView : AppCompatTextView {
        companion object {
            val SPEED_FAST = 9
            val SPEED_MEDIUM = 6
            val SPEED_SLOW = 3
        }
    
        //View宽度
        private var mViewWidth = 0
        private var mViewHeight = 0
        private var mScrollX = 0F
        private var mMarqueeMode = 3
        private val rect = Rect()
    
        constructor(context: Context) : this(context, null)
        constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
        constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
            context,
            attrs,
            defStyleAttr
        ) {
            includeFontPadding = false
            initAttrs(context, attrs)
        }
    
        fun setScrollSpeed(speed: Int) {
            if (speed == SPEED_FAST || speed == SPEED_MEDIUM || speed == SPEED_SLOW) {
                mMarqueeMode = speed
            }
        }
    
    
        override fun onDraw(canvas: Canvas?) {
            val textContentText = text.toString().trim()
            if (TextUtils.isEmpty(textContentText)) {
                return
            }
            val x = mViewWidth - mScrollX
            val y = mViewHeight / 2F + getTextContentHeight() / 2
            canvas?.drawText(textContentText, x, y, paint)
            mScrollX += mMarqueeMode
            if (mScrollX >= (mViewWidth + getTextContentWdith())) {
                mScrollX = 0F
            }
            invalidate()
        }
    
        override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
            mViewWidth = MeasureSpec.getSize(widthMeasureSpec)
            mViewHeight = MeasureSpec.getSize(heightMeasureSpec)
        }
        
        override fun setTextColor(color: Int) {
            super.setTextColor(color)
            paint.setColor(color)
        }
    
        private fun initAttrs(context: Context, attrs: AttributeSet?) {
            val typeArray = context.obtainStyledAttributes(attrs, R.styleable.CustomMarqueeView)
            mMarqueeMode =
                typeArray.getInt(R.styleable.CustomMarqueeView_customScrollSpeed, mMarqueeMode)
            typeArray.recycle()
        }
    
        /**
         * 测量文字宽度
         * @return 文字宽度
         */
        private fun getTextContentWdith(): Int {
            val textContent = text.toString().trim()
            if (!TextUtils.isEmpty(textContent)) {
                paint.getTextBounds(textContent, 0, textContent.length, rect)
                return rect.width()
            }
            return 0
        }
    
        /**
         * 测量文字高度
         * @return 文字高度
         */
        private fun getTextContentHeight(): Int {
            val textContent = text.toString().trim()
            if (!TextUtils.isEmpty(textContent)) {
                paint.getTextBounds(textContent, 0, textContent.length, rect)
                return rect.height()
            }
            return 0
        }
    }
    
    • 自定义属性
        <declare-styleable name="CustomMarqueeView">
            <attr name="customScrollSpeed">
                <enum name="fast" value="9" />
                <enum name="medium" value="6" />
                <enum name="slow" value="3" />
            </attr>
        </declare-styleable>
    

    相关文章

      网友评论

        本文标题:Android自定义可控制速度的跑马灯

        本文链接:https://www.haomeiwen.com/subject/tooyxhtx.html