亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android實現(xiàn)循環(huán)輪播跑馬燈的效果

 更新時間:2023年05月04日 10:42:59   作者:Calculus_小王  
這篇文章主要介紹了為大家詳細(xì)介紹了如何通過Android實現(xiàn)循環(huán)輪播跑馬燈的效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

先看效果

支持暫停,恢復(fù),view自定義和池化回收復(fù)用。使用上,只需要引入xml,并綁定factory即可,內(nèi)部會在attach時自動開始

 <MarqueeAnimalView
        android:id="@+id/marqueeView"
        android:layout_width="200dp"
        android:layout_height="30dp"
        android:background="@color/color_yellow" />
val list = mutableListOf("我是跑馬燈1", "我不是跑馬燈", "你猜我是不是跑馬燈")
var position = 0
view.marqueeView.setFactory(object : PoolViewFactory {
    override fun makeView(layoutInflater: LayoutInflater, parent: ViewGroup): View {
        val view = TextView(this@ViewActivity)
        view.setPadding(0, 0, 20.dp(), 0)
        view.textSize = 12f
        view.setTextColor(ResourceUtil.getColor(R.color.white))
        return view
    }
    override fun setAnimator(objectAnimator: ObjectAnimator, width: Int, parentWidth: Int) {
        objectAnimator.duration = (parentWidth + width) * 5L
    }
    override fun setView(view: View): Boolean {
        (view as? TextView)?.text = list[position++ % list.size]
        return true
    }
})

池化思路

參考Message的思路,對view進行回收復(fù)用,避免內(nèi)存持續(xù)增長,增大GC壓力

private fun obtain(): View? {
    synchronized(sPoolSync) {
        if (!isAttachedToWindow) {
            return null
        }
        if (queue.isNotEmpty()) {
            return queue.poll()
        }
    }
    return factory?.makeView(layoutInflater, this@MarqueeAnimalView)?.apply {
        addView(this, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
    }
}
private fun recycle(view: View) {
    synchronized(sPoolSync) {
        if (queue.size < MAX_POOL_SIZE) {
            queue.offer(view)
        }
    }
}

創(chuàng)造工廠

這里的思路源于ViewSwitchFactory

interface PoolViewFactory {
    fun makeView(layoutInflater: LayoutInflater, parent: ViewGroup): View
    fun setAnimator(objectAnimator: ObjectAnimator, width: Int, parentWidth: Int)
    /**
     * 返回值,代表view是否需要重新測量
     */
    fun setView(view: View): Boolean
}

輪詢切換

這里根據(jù)對動畫進行初始化,并設(shè)置合適的監(jiān)聽。此時需要獲取當(dāng)view和parent的width,以用于標(biāo)定始末位置,需要注意x軸的正負(fù)方向。animators用于存儲開始的動畫,這也是設(shè)計時存在的遺留問題,因為主動取消所有動畫,但view->animator是單向綁定關(guān)系,所以需要保存發(fā)生的動畫

private val animators = hashMapOf<String, ObjectAnimator>()
private fun next(view: View?) {
    view ?: return
    if (factory?.setView(view) == true) {
        view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED))
    }
    val width = view.measuredWidth
    val parentWidth = measuredWidth
    val targetValue = parentWidth - width
    val animator = ObjectAnimator.ofFloat(view, PROPERTY_NAME, parentWidth.toFloat(), -width.toFloat()).apply {
        // null即為默認(rèn)線性插值器
        interpolator = null
        addUpdateListener(
            RecyclerAnimatorUpdateListener(targetValue) {
                next(obtain())
                removeUpdateListener(it)
            }
        )
        addListener(this@MarqueeAnimalView)
        factory?.setAnimator(this, width, parentWidth)
    }
    animators["${view.hashCode()}-${animator.hashCode()}"] = animator
    animator.start()
}

動畫監(jiān)聽

當(dāng)動畫結(jié)束時,需要對view進行回收,并對動畫移除。取消動畫時,需要將view強制歸位

同時,為了方便使用,OnAttachStateChangeListener使得整體動畫更加平滑,也避免了view不可見時,動畫仍然在持續(xù)執(zhí)行浪費資源。當(dāng)然如fragment不可見時的監(jiān)聽需要完善

override fun onAnimationEnd(animation: Animator?) {
    (animation as? ObjectAnimator)?.let { animator ->
        (animator.target as? View)?.let { view ->
            animators.remove("${view.hashCode()}-${animator.hashCode()}")
            recycle(view)
        }
        // target釋放
        animator.target = null
    }
}
override fun onAnimationCancel(animation: Animator?) {
    (animation as? ObjectAnimator)?.let { animator ->
        (animator.target as? View)?.let { view ->
            view.translationX = measuredWidth.toFloat()
        }
    }
}
override fun onViewAttachedToWindow(v: View?) {
    if (animators.isNotEmpty()) {
        resume()
    } else {
        start()
    }
}
override fun onViewDetachedFromWindow(v: View?) {
    pause()
}

對外能力

fun start() {
    if (measuredWidth == 0) {
        this.post {
            // 如果測量還未完成,那就等待post后發(fā)起
            next(obtain())
        }
        return
    }
    next(obtain())
}
fun stop() {
    val it = animators.values.iterator()
    while (it.hasNext()) {
        val i = it.next()
        it.remove()
        i.cancel()
    }
}
fun pause() {
    for (i in animators.values) {
        i.pause()
    }
}
fun resume() {
    for (i in animators.values) {
        i.resume()
    }
}

完整代碼

歡迎支持,搜索MarqueeAnimalView即可 github.com/wjf-962464/Self_Demo.git

到此這篇關(guān)于Android實現(xiàn)循環(huán)輪播跑馬燈的效果的文章就介紹到這了,更多相關(guān)Android跑馬燈內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android布局之表格布局TableLayout詳解

    Android布局之表格布局TableLayout詳解

    這篇文章主要為大家詳細(xì)介紹了Android布局之表格布局TableLayout,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Android仿微信布局的實現(xiàn)示例

    Android仿微信布局的實現(xiàn)示例

    本文主要介紹了Android仿微信布局的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 淺析Android手機衛(wèi)士關(guān)閉自動更新

    淺析Android手機衛(wèi)士關(guān)閉自動更新

    保存數(shù)據(jù)的四種方式,網(wǎng)絡(luò),廣播提供者,SharedPreferences,數(shù)據(jù)庫。接下來通過本文給大家介紹android手機衛(wèi)士關(guān)閉自動更新的相關(guān)知識,感興趣的朋友一起學(xué)習(xí)吧
    2016-04-04
  • Android開發(fā)之ImageSwitcher相冊功能實例分析

    Android開發(fā)之ImageSwitcher相冊功能實例分析

    這篇文章主要介紹了Android開發(fā)之ImageSwitcher相冊功能,結(jié)合實例形式分析了Android ImageSwitcher相冊的原理、使用方法及相關(guān)操作注意事項,需要的朋友可以參考下
    2019-03-03
  • 一文帶你搞清楚Android游戲發(fā)行切包資源ID那點事

    一文帶你搞清楚Android游戲發(fā)行切包資源ID那點事

    這篇文章主要介紹了Android 解決游戲發(fā)行切包資源ID的一些問題,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下
    2023-05-05
  • 安卓逆向騰訊動漫app返回數(shù)據(jù)加密分析案例分享

    安卓逆向騰訊動漫app返回數(shù)據(jù)加密分析案例分享

    這篇文章主要為大家介紹了安卓逆向騰訊動漫app返回數(shù)據(jù)加密分析的案例分享,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-02-02
  • Android編程ProgressBar自定義樣式之動畫模式實現(xiàn)方法

    Android編程ProgressBar自定義樣式之動畫模式實現(xiàn)方法

    這篇文章主要介紹了Android編程ProgressBar自定義樣式之動畫模式實現(xiàn)方法,涉及Android動畫模式的布局技巧,非常具有實用價值,需要的朋友可以參考下
    2015-10-10
  • Android RenderScript高斯模糊

    Android RenderScript高斯模糊

    這篇文章主要介紹了Android RenderScript高斯模糊的相關(guān)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • 給大家分享一些安卓自學(xué)心得

    給大家分享一些安卓自學(xué)心得

    本文是筆者在學(xué)習(xí)安卓開發(fā)的過程中的一些經(jīng)驗之談的分享,希望對大家學(xué)習(xí)安卓開發(fā)能夠有所幫助。
    2015-12-12
  • Android 側(cè)滑抽屜菜單的實現(xiàn)代碼

    Android 側(cè)滑抽屜菜單的實現(xiàn)代碼

    這篇文章主要介紹了Android 側(cè)滑抽屜菜單的實現(xiàn)代碼,本文通過實例圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03

最新評論