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

背景

原生的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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android跑马灯MarqueeView源码解析

    跑马灯效果,大家可以去原作者浏览https://github.com/sfsheng0322/MarqueeView 下面看自定义控件的代码 public class MarqueeView extends ViewFlipper { private Context mContext; private List<String> notices; private boolean isSetAnimDuration = false; private OnItemClickListener onIt

  • Android实现图文垂直跑马灯效果

    最近在维护老项目,老项目有一个地方需要修改,就是垂直跑马灯的问题,之前的垂直跑马灯是只有文字跑马灯,新版需要加上. 之前是用的MarqueeView,看了下源代码是只支持文字的,于是我就改了下原作者的源代码. MarqueeView类之前作者的 // 创建ViewFlipper下的TextView private TextView createTextView(CharSequence text, int position) { TextView tv = new TextView(mConte

  • Android中使用TextView实现文字跑马灯效果

    通常情况下我们想实现文字的走马灯效果需要在xml文件中这样设置 <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:ellipsize="marquee" android:focusable="true" android:

  • Android自定义View实现竖直跑马灯效果案例解析

    首先给出跑马灯效果图 中间的色块是因为视频转成GIF造成的失真,自动忽略哈. 大家知道,横向的跑马灯android自带的TextView就可以实现,详情请百度[Android跑马灯效果].但是竖直的跑马灯效果原生Android是不支持的.网上也有很多网友实现了自定义的效果,但是我一贯是不喜欢看别人的代码,所以这篇博客的思路完全是我自己的想法哈. 首先,我们需要给自定义的控件梳理一下格局,如下图所示: 1.首先我们将控件分为三个区块,上面绿色部分为消失不可见的块,中间黑色部分为可见区域,下面红色部

  • Android基于TextView不获取焦点实现跑马灯效果

    本文实例讲述了Android基于TextView不获取焦点实现跑马灯效果.分享给大家供大家参考,具体如下: 1. 写一个类继承TextView package com.example.tt; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import android.widget.TextView; public class ScrollingText

  • android自定义View实现跑马灯效果

    android自带的TextView可以实现跑马灯效果,但是有很多的局限性:比如需要设置ellipsize="marquee",获取 focusable="true",设置singleLine="true",控件里的内容需要超过控件本身的长度,无法控制滚动速度和滚动暂停和继续滚动功能,各种限制导致用起来特别不顺手,几乎无法使用到生产环境中,在此背景下,需要自定义View实现跑马灯效果. 使用主要方法:自定义View重写onDraw方法,通过can

  • Android 中TextView中跑马灯效果的实现方法

     条件: 1.android:ellipsize="marquee" 2.TextView必须单行显示,即内容必须超出TextView大小 3.TextView要获得焦点才能滚动 mTVText.setText("超过文本长度的数据"); mTVText.setSingleLine(true);设置单行显示 mTVText.setEllipsize(TruncateAt.MARQUEE);设置跑马灯显示效果 TextView.setHorizontallyScrol

  • Android TextView实现跑马灯效果的方法

    本文为大家分享一个非常简单但又很常用的控件,跑马灯状态的TextView.当要显示的文本长度太长,又不想换行时用它来显示文本,一来可以完全的显示出文本,二来效果也挺酷,实现起来超级简单,所以,何乐不为.先看下效果图: 代码实现 TextView自带了跑马灯功能,只要把它的ellipsize属性设置为marquee就可以了.但有个前提,就是TextView要处于被选中状态才能有效果,看到这,我们就很自然的自定义一个控件,写出以下代码: public class MarqueeTextView ex

  • Android实现跑马灯效果的方法

    本文实例讲述了Android实现跑马灯效果的方法.分享给大家供大家参考.具体如下: 运行效果截图如下: 直接在布局里写代码就好了: <TextView android:id="@+id/menu_desc" android:layout_width="300dip" android:layout_height="wrap_content" android:text="温馨提示:左右滑动更改菜单,点击进入" android

  • Android自定义textview实现竖直滚动跑马灯效果

    本文实例为大家分享了Android自定义textview实现跑马灯效果的具体代码,供大家参考,具体内容如下 xml布局 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.c

随机推荐