textview 的跑马灯不用说了吧,大家肯定都知道这是个啥,但是呢我还是放个图吧:
232041141272978.gif
实现单个跑马灯
跑马灯的核心是这2个 xml 设置
android:ellipsize="marquee"
android:singleLine="true"
一定要用 singleLine 而不要用 lines
ellipsize 表示的是当 - 文字长度超过textview宽度时的显示方式,有几个配置:
- start:表示将文字开头省略,用“…”代替
- middle:表示将文字中间省略,用“…”代替
- end:表示将文字末尾省略,用“…”代替
- marquee:表示当文字一行展示不下时,以跑马灯滚动效果展示
- none:即默认,没有任何效果
若是这么简单的话我也没必要特意开篇幅来写这个啦,主要是因为蛋疼的我们配置完着2个 xml 属性后不管用...
这里面很多前人就去翻 textview 源码了,发现 textview 里面维护了文字宽度,若是 文字宽度 超过 textview 宽度就会进行相应处理,比如 ellipsize 属性设置为 marquee 跑马灯模式后就会进行滚动显示,看源码就是 canvas 的 translate 位移操作,操作画布
if (mMarquee != null && mMarquee.isRunning()) {
final float dx = -mMarquee.getScroll();
canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);
}
蛋疼的是还没完,textview 必须在获取焦点时才能就行canvas 的 translate 位移操作,所以我们还需要加上下面3个参数,获取焦点和跑马灯重复模式
android:focusable="true"
android:focusableInTouchMode="true"
android:marqueeRepeatLimit="marquee_forever""
好啦,这样 textview 就能跑马式的跑起来啦
实现多个跑马灯
然后蛋疼的又来啦,一个页面要是游多个跑马灯的 textview 就只能有一个起作用,就是我们配置了上面全部的 5 个 xml 属性都没用,因为系统默认同时只有一个 textview 能获取焦点
那怎么办,我翻了翻,经过前辈们不停的探寻,发现我们只要更改 textview 返回焦点值方法,返回值一直给 true 就行啦,所以我们得自定义一个 textview 啦,很简单的啦~
class MarqueeTextView : TextView {
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
// 重写这里即可
override fun isFocused(): Boolean {
return true
}
}
232057302214909.gif
这样就搞定啦,不难哦,大家快掌握~
网友评论