AndroidMarqueeTextView:轻松实现⽂本滚动(跑马灯)效果前⾔
Android 的TextView虽然有属性android:ellipsize="marquee"有⽂字滚动效果,但是坑多,⽐如焦点变化了就不动了,⽽且不能控制滚动的速度,在RecyclerView⾥的表现更是灾难级的。为了解决以上问题,所以就有了MarqueeTextView:⼀个由 Kotlin 实现的⽂本滚动⾃定义 View。
相关属性
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.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⽅法
具体实现
让⽂字滚动起来其实就是定时在短时间内把⽂来,这样看着就会有连续滚动的感觉。
下⾯仅说明实现效果的核⼼⽅法,源码⾃取:
0. 核⼼类:TextPaint和android.os.handler
1. 获取绘制⽂本的宽度
private fun getTextWidth(text: String?): Float {
if (text.isNullOrEmpty()) {
return 0f
}
asureText(text)
}
2. 填充循环模式下的⽂本拼接
if (repeat == REPEAT_FILL_LOOP) {
mFinalDrawText = ""
//计算⽂本的宽度
mSingleContentWidth = getTextWidth(targetContent)
if (mSingleContentWidth > 0) {
// 最⼤可见内容项数
val maxVisibleCount = ceil(width / Double()).toInt() + 1
repeat(maxVisibleCount) {
mFinalDrawText += targetContent
}
}
html滚动效果代码contentWidth = getTextWidth(mFinalDrawText)
}
3. 绘制⽂本内容
override fun onDraw(canvas: Canvas) {
// 忽略部分代码 ...
// 绘制⽂本
if (mFinalDrawText.isNotBlank()) {
canvas.drawText(mFinalDrawText, xLocation, height / 2 + textHeight / 2, textPaint)
}
}
4. 定时绘制内容——滚起来
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
if (msg.what == WHAT_RUN) {
<()?.apply {
if (speed > 0) {
xLocation -= speed
invalidate()
/
/ 50 毫秒绘制⼀次
sendEmptyMessageDelayed(WHAT_RUN, 50)
}
}
}
}
总结
整个实现下来总的来说还是⽐较简单的,能够满⾜平时⽂本滚动(跑马灯)效果的需求了。代码量很少的,也⽐较清晰,⼤家看下源码应该就清楚了。有不清楚的欢迎交流。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论