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

Olinda ·
更新时间:2024-11-14
· 656 次阅读

背景

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

思路

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

源码(Kotlin) 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

需要 登录 后方可回复, 如果你还没有账号请 注册新账号