美文网首页
Android MarqueeTextView : 轻松实现文本

Android MarqueeTextView : 轻松实现文本

作者: FindUById | 来源:发表于2021-07-26 19:49 被阅读0次

    前言

    Android 的 TextView 虽然有属性 android:ellipsize="marquee"有文字滚动效果,但是坑多,比如焦点变化了就不动了,而且不能控制滚动的速度,在RecyclerView里的表现更是灾难级的。为了解决以上问题,所以就有了MarqueeTextView:一个由 Kotlin 实现的文本滚动自定义 View。MarqueeTextView: Kotlin 实现文本横向滚动,跑马灯效果。 (gitee.com)

    demo.jpg

    相关属性

    xml 属性

    属性 说明
    android:textSize 文字大小
    android:textColor 文字颜色
    android:text 文本内容
    marqueeRepeat 循环模式:singe-单次执行;singleLoop-单项循环;fillLoop-填充循环
    marqueeItemDistance 每个item之间的距离, marqueeRepeat=fillLoop 有效
    marqueeStartLocationDistance 开始的起始位置 按距离控件左边的百分比 0~1之间
    marqueeSpeed 文字滚动速度
    marqueeResetLocation 重新改变内容的时候 , 是否初始化 位置,默认为true,改变

    主要方法

    • start : 滚动开始
    • stop : 滚动停止
    • toggle : 切换滚动开始/停止

    使用方式

    <com.xin.marquee.text.view.MarqueeTextView
        android:id="@+id/tv1"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginStart="20dp"
        android:layout_marginEnd="20dp"
        android:layout_marginBottom="16dp"
        android:text="Kotlin 实现文本横向滚动,跑马灯效果。"
        android:textSize="14dp"
        app:marqueeRepeat="fillLoop"
        app:marqueeSpeed="5" />
    

    代码里调用start方法

    具体实现

    让文字滚动起来其实就是定时在短时间内把文来,这样看着就会有连续滚动的感觉。
    下面仅说明实现效果的核心方法,源码自取:MarqueeTextView: Kotlin 实现文本横向滚动,跑马灯效果。 (gitee.com)

    1. 核心类:android.text.TextPaintandroid.os.handler
    2. 获取绘制文本的宽度
    private fun getTextWidth(text: String?): Float {
        if (text.isNullOrEmpty()) {
            return 0f
        }
        return textPaint.measureText(text)
    }
    
    1. 填充循环模式下的文本拼接
    if (repeat == REPEAT_FILL_LOOP) {
        mFinalDrawText = ""
        //计算文本的宽度
        mSingleContentWidth = getTextWidth(targetContent)
        if (mSingleContentWidth > 0) {
            // 最大可见内容项数
            val maxVisibleCount = ceil(width / mSingleContentWidth.toDouble()).toInt() + 1
            repeat(maxVisibleCount) {
                mFinalDrawText += targetContent
            }
        }
        contentWidth = getTextWidth(mFinalDrawText)
    } 
    
    1. 绘制文本内容
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        // 忽略部分代码 ...
        // 绘制文本
        if (mFinalDrawText.isNotBlank()) {
            canvas.drawText(mFinalDrawText, xLocation, height / 2 + textHeight / 2, textPaint)
        }
    }
    
    1. 定时绘制内容——滚起来
    override fun handleMessage(msg: Message) {
        super.handleMessage(msg)
        if (msg.what == WHAT_RUN) {
            mRef.get()?.apply {
                if (speed > 0) {
                    xLocation -= speed
                    invalidate()
                    // 50 毫秒绘制一次
                    sendEmptyMessageDelayed(WHAT_RUN, 50)
                }
            }
        }
    }
    

    总结

    整个实现下来总的来说还是比较简单的,能够满足平时文本滚动(跑马灯)效果的需求了。代码量很少的,也比较清晰,大家看下源码应该就清楚了。有不清楚的欢迎交流。

    相关文章

      网友评论

          本文标题:Android MarqueeTextView : 轻松实现文本

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