Android自定義可控制速度的跑馬燈
背景
原生的TextView是支持跑馬燈效果的,但是在項(xiàng)目中實(shí)際用了之后,達(dá)不到需求,原因是內(nèi)容滾動(dòng)太慢,速度無(wú)法調(diào)節(jié)。因此,需要自定義一個(gè)可以調(diào)節(jié)速度的跑馬燈。
思路
目前實(shí)現(xiàn)的思路是對(duì)文本內(nèi)容不斷地重繪,同時(shí)改變每次重繪的坐標(biāo),來(lái)在視覺(jué)上達(dá)到內(nèi)容在滾動(dòng)的效果。缺點(diǎn)是如果每次改變的坐標(biāo)差值太大,會(huì)有明顯的卡頓效果。經(jīng)過(guò)調(diào)試,下面源碼中的速度感覺(jué)還可以接受,如果有特殊需求,自行在調(diào)試一下。
源碼(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() ? ? } ? ? /** ? ? ?* 測(cè)量文字寬度 ? ? ?* @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 ? ? } ? ? /** ? ? ?* 測(cè)量文字高度 ? ? ?* @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>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android4.4+ 實(shí)現(xiàn)半透明狀態(tài)欄(Translucent Bars)
這篇文章主要為大家詳細(xì)介紹了Android4.4+ 實(shí)現(xiàn)半透明狀態(tài)欄,對(duì)狀態(tài)欄(Status Bar)和下方導(dǎo)航欄(Navigation Bar)進(jìn)行半透明處理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09解決android有的手機(jī)拍照后上傳圖片被旋轉(zhuǎn)的問(wèn)題
這篇文章主要介紹了解決android有的手機(jī)拍照后上傳圖片被旋轉(zhuǎn)的問(wèn)題的相關(guān)資料,需要的朋友可以參考下2016-09-09Android簡(jiǎn)單實(shí)用的可拖拽GridView組件分享
在我們?nèi)粘i_(kāi)發(fā)中,使用?GridView?這種網(wǎng)格視圖的場(chǎng)合還是不少的,本篇我們來(lái)介紹一個(gè)支持拖拽的?GridView?組件,可以輕松搞定網(wǎng)格視圖的拖拽排序,需要的可以參考一下2023-06-06Android實(shí)現(xiàn)點(diǎn)擊兩次BACK鍵退出應(yīng)用
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)點(diǎn)擊兩次BACK鍵退出應(yīng)用的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09Android android:exported = true 用法詳解
在本篇文章里小編給大家整理了關(guān)于Android android:exported = true 用法,需要的朋友們參考下。2019-09-09Android 中SwipeRefreshLayout與ViewPager滑動(dòng)事件沖突解決方法
這篇文章主要介紹了Android 中SwipeRefreshLayout與ViewPager滑動(dòng)事件沖突解決方法的相關(guān)資料,需要的朋友可以參考下2017-04-04