最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android自定義View模仿即刻點(diǎn)贊數(shù)字切換效果實(shí)例

 更新時(shí)間:2022年12月24日 11:23:49   作者:timer  
有一個(gè)項(xiàng)目是仿即刻的點(diǎn)贊,這篇文章主要給大家介紹了關(guān)于Android自定義View模仿即刻點(diǎn)贊數(shù)字切換效果的相關(guān)資料,文中通過示例代碼介紹 的非常詳細(xì),需要的朋友可以參考下

即刻點(diǎn)贊展示

點(diǎn)贊的數(shù)字增加和減少并不是整個(gè)替換,而是差異化替換。再加上動畫效果就看的很舒服。

自己如何實(shí)現(xiàn)這種數(shù)字切換呢?

下面用一張圖來展示我的思路:

現(xiàn)在只需要根據(jù)這張圖,寫出對應(yīng)的動畫即可。 分為2種場景:

  • 數(shù)字+1:
    • 差異化的數(shù)字從3號區(qū)域由漸變動畫(透明度 0- 255) + 偏移動畫 (3號區(qū)域繪制文字的基線,2號區(qū)域繪制文字的基線),將數(shù)字移動到2號位置處
    • 差異化的數(shù)字從2號區(qū)域由漸變動畫(透明度 255- 0) + 偏移動畫(2號區(qū)域繪制文字的基線,1號區(qū)域繪制文字的基線),將數(shù)字移動到1號位置處
  • 數(shù)字-1
    • 差異化的數(shù)字從1號區(qū)域由漸變動畫(透明度 0- 255) + 偏移動畫 (1號區(qū)域繪制文字的基線,2號區(qū)域繪制文字的基線),將數(shù)字移動到2號位置處
    • 差異化的數(shù)字從2號區(qū)域由漸變動畫(透明度 255- 0) + 偏移動畫(2號區(qū)域繪制文字的基線,3號區(qū)域繪制文字的基線),將數(shù)字移動到3號位置處

公共部分就是: 不變的文字不需要做任何處理,繪制在2號區(qū)域就行。繪制差異化文字時(shí),需要加上不變的文字的寬度就行。

效果展示

源碼

class LikeView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val paint = Paint().also {
        it.isAntiAlias = true
        it.textSize = 200f
    }

    private val textRect0 = Rect(300, 100, 800, 300)
    private val textRect1 = Rect(300, 300, 800, 500)
    private val textRect2 = Rect(300, 500, 800, 700)

    private var nextNumberAlpha: Int = 0
        set(value) {
            field = value
            invalidate()
        }

    private var currentNumberAlpha: Int = 255
        set(value) {
            field = value
            invalidate()
        }

    private var offsetPercent = 0f
        set(value) {
            field = value
            invalidate()
        }

    private val fontMetrics: FontMetrics = paint.fontMetrics
    private var currentNumber = 99
    private var nextNumber = 0
    private var motionLess = currentNumber.toString()
    private var currentMotion = ""
    private var nextMotion = ""

    private val animator: ObjectAnimator by lazy {
        val nextNumberAlphaAnimator = PropertyValuesHolder.ofInt("nextNumberAlpha", 0, 255)
        val offsetPercentAnimator = PropertyValuesHolder.ofFloat("offsetPercent", 0f, 1f)
        val currentNumberAlphaAnimator = PropertyValuesHolder.ofInt("currentNumberAlpha", 255, 0)
        val animator = ObjectAnimator.ofPropertyValuesHolder(
            this,
            nextNumberAlphaAnimator,
            offsetPercentAnimator,
            currentNumberAlphaAnimator
        )
        animator.duration = 200
        animator.interpolator = DecelerateInterpolator()
        animator.addListener(
            onEnd = {
                currentNumber = nextNumber
            }
        )
        animator
    }

    override fun onDraw(canvas: Canvas) {
        paint.alpha = 255

        paint.color = Color.LTGRAY
        canvas.drawRect(textRect0, paint)

        paint.color = Color.RED
        canvas.drawRect(textRect1, paint)

        paint.color = Color.GREEN
        canvas.drawRect(textRect2, paint)

        paint.color = Color.BLACK
        if (motionLess.isNotEmpty()) {
            drawText(canvas, motionLess, textRect1, 0f)
        }

        if (nextMotion.isEmpty() || currentMotion.isEmpty()) {
            return
        }

        val textHorizontalOffset =
            if (motionLess.isNotEmpty()) paint.measureText(motionLess) else 0f
        if (nextNumber > currentNumber) {
            paint.alpha = currentNumberAlpha
            drawText(canvas, currentMotion, textRect1, textHorizontalOffset, -offsetPercent)
            paint.alpha = nextNumberAlpha
            drawText(canvas, nextMotion, textRect2, textHorizontalOffset, -offsetPercent)
        } else {
            paint.alpha = nextNumberAlpha
            drawText(canvas, nextMotion, textRect0, textHorizontalOffset, offsetPercent)
            paint.alpha = currentNumberAlpha
            drawText(canvas, currentMotion, textRect1, textHorizontalOffset, offsetPercent)
        }
    }

    private fun drawText(
        canvas: Canvas,
        text: String,
        rect: Rect,
        textHorizontalOffset: Float = 0f,
        offsetPercent: Float = 0f
    ) {
        canvas.drawText(
            text,
            rect.left.toFloat() + textHorizontalOffset,
            rect.top + (rect.bottom - rect.top) / 2f - (fontMetrics.bottom + fontMetrics.top) / 2f + offsetPercent * 200,
            paint
        )
    }


    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        animator.end()
    }

    fun plus() {
        if (currentNumber == Int.MAX_VALUE) {
            return
        }
        nextNumber = currentNumber + 1

        processText(findEqualsStringIndex())

        if (animator.isRunning) {
            return
        }
        animator.start()
    }

    fun minus() {
        if (currentNumber == 0) {
            return
        }
        nextNumber = currentNumber - 1
        processText(findEqualsStringIndex())
        if (animator.isRunning) {
            return
        }
        animator.start()
    }

    private fun findEqualsStringIndex(): Int {
        var equalIndex = -1
        val nextNumberStr = nextNumber.toString()
        val currentNumberStr = currentNumber.toString()

        val endIndex = min(currentNumberStr.length, nextNumberStr.length) - 1

        for (index in 0..endIndex) {
            if (nextNumberStr[index] != currentNumberStr[index]) {
                break
            }
            equalIndex = index
        }
        return equalIndex
    }

    private fun processText(index: Int) {
        val currentNumberStr = currentNumber.toString()
        val nextNumberStr = nextNumber.toString()
        if (index == -1) {
            motionLess = ""
            currentMotion = currentNumberStr
            nextMotion = nextNumberStr
        } else {
            motionLess = currentNumberStr.substring(0, index + 1)
            currentMotion = currentNumberStr.substring(index + 1)
            nextMotion = nextNumberStr.substring(index + 1)
        }
    }
}

總結(jié)

到此這篇關(guān)于Android自定義View模仿即刻點(diǎn)贊數(shù)字切換效果的文章就介紹到這了,更多相關(guān)Android模仿即刻點(diǎn)贊數(shù)字切換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android CoordinatorLayout詳解及實(shí)例代碼

    Android CoordinatorLayout詳解及實(shí)例代碼

    這篇文章主要介紹了Android CoordinatorLayout詳解及實(shí)例代碼的相關(guān)資料,CoordinatorLayout基本實(shí)現(xiàn)兩個(gè)功能: 作為頂層布局 和調(diào)度協(xié)調(diào)子布局,這里詳細(xì)介紹此部分知識,需要的朋友可以參考下
    2016-12-12
  • Android中的序列化淺析

    Android中的序列化淺析

    這篇文章主要介紹了Android中的序列化淺析,本文講解了序列化原因、序列化方法和代碼實(shí)現(xiàn)等內(nèi)容,需要的朋友可以參考下
    2015-03-03
  • Android實(shí)現(xiàn)快遞物流時(shí)間軸效果

    Android實(shí)現(xiàn)快遞物流時(shí)間軸效果

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)快遞物流時(shí)間軸效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • 深入android中The connection to adb is down的問題以及解決方法

    深入android中The connection to adb is 

    本篇文章是對android中The connection to adb is down的問題以及解決方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • Android實(shí)現(xiàn)銀行卡號掃描識別功能

    Android實(shí)現(xiàn)銀行卡號掃描識別功能

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)銀行卡號掃描識別功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • Android開啟閃光燈的方法 Android打開手電筒功能

    Android開啟閃光燈的方法 Android打開手電筒功能

    這篇文章主要為大家詳細(xì)介紹了Android開啟閃光燈的方法,Android打開手電筒功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Android仿支付寶的頭部伸縮動畫效果

    Android仿支付寶的頭部伸縮動畫效果

    Android5.0推出的MaterialDesign庫包含了處理頭部工具欄的多個(gè)控件,不但允許自定義頂部導(dǎo)航欄,而且導(dǎo)航欄高度是可以伸縮的。下文給大家介紹Android仿支付寶的頭部伸縮動畫效果,需要的朋友參考下吧
    2017-05-05
  • Android ViewFlipper簡單用法解析

    Android ViewFlipper簡單用法解析

    這篇文章主要為大家詳細(xì)介紹了Android ViewFlipper簡單用法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Android應(yīng)用啟動流程之從啟動到可交互的過程解析

    Android應(yīng)用啟動流程之從啟動到可交互的過程解析

    這篇文章將給大家總結(jié)學(xué)習(xí)Android 基礎(chǔ)知識,Android應(yīng)用啟動流程,從啟動到可交互的過程解析,在學(xué)習(xí)過程中,大家最好是把源碼下載下來,感興趣的小伙伴跟著小編一起來看看吧
    2023-08-08
  • Android實(shí)現(xiàn)語音數(shù)據(jù)實(shí)時(shí)采集、播放

    Android實(shí)現(xiàn)語音數(shù)據(jù)實(shí)時(shí)采集、播放

    這篇文章主要介紹了android實(shí)現(xiàn)語音數(shù)據(jù)實(shí)時(shí)采集、播放的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12

最新評論

台安县| 阿巴嘎旗| 米脂县| 沐川县| 哈尔滨市| 札达县| 左云县| 赤壁市| 湾仔区| 白城市| 平度市| 大名县| 宿迁市| 博爱县| 阳新县| 都昌县| 内江市| 松溪县| 巴林左旗| 兴化市| 黔南| 油尖旺区| 禹城市| 漳平市| 琼中| 天水市| 衡水市| 沙湾县| 武汉市| 乾安县| 西充县| 阿拉善盟| 拉孜县| 安乡县| 黄石市| 巴林右旗| 桑日县| 吴桥县| 吴川市| 德令哈市| 溧水县|