Android-自定義SplashView

先看一下要實現(xiàn)的效果

要實現(xiàn)的效果

從上面的動畫分析品擎,可以分為以下幾步

  1. 六個圓圍繞圓心旋轉(zhuǎn)。
  2. 旋轉(zhuǎn)完成后备徐,先進(jìn)行擴(kuò)散萄传,后聚合。
  3. 聚合完成后蜜猾,從圓心慢慢擴(kuò)散秀菱,展示后面的視圖。

第一步畫六個圓

package rc.loveq.splashview

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import kotlin.math.hypot
import kotlin.properties.Delegates
import kotlin.math.cos
import kotlin.math.sin


/**
 * Author:Rc
 * 0n 2019/8/26 22:42
 */
class SplashView(context: Context, attrs: AttributeSet) : View(context, attrs) {


    // 背景色
    private val bgColor = Color.WHITE

    // 6個圓的顏色
    private val circleColor: IntArray = context.resources.getIntArray(R.array.splash_circle_colors)

    // 6個圓畫筆
    private var paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)


    //View中心點的x坐標(biāo)
    var centerX by Delegates.notNull<Float>()

    //View中心點的y坐標(biāo)
    var centerY by Delegates.notNull<Float>()

    //當(dāng)前View對角線的一半
    var distance by Delegates.notNull<Float>()


    private val rotateRadius = 90f

    // 默認(rèn)六個圓圍繞的外圍圓半徑
    private val currentRotateRadius = rotateRadius

    // 6個圓半徑
    private val circleRadius = 18f

    // 當(dāng)前splash的狀態(tài)
    private var splashState: SplashState? = null


    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        //獲取中心點
        centerX = (w / 2).toFloat()
        centerY = (h / 2).toFloat()

        //當(dāng)前View對角線的一半
        distance = (hypot(x.toDouble(), h.toDouble()) / 2).toFloat()

    }


    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        //初始化默認(rèn)狀態(tài)
        splashState ?: splashState.apply {
            splashState = RotateStatus()
        }
        splashState!!.drawState(canvas)

    }


    /**
     * 閃屏頁的狀態(tài)的抽象類
     */
    abstract inner class SplashState {
        abstract fun drawState(canvas: Canvas)
    }

    /**
     * 1.旋轉(zhuǎn)
     */
    inner class RotateStatus : SplashState() {

        override fun drawState(canvas: Canvas) {
            drawBackground(canvas)
            drawCircle(canvas)
        }

        private fun drawCircle(canvas: Canvas) {
            //每個圓的弧度
            val rotateAngle = (Math.PI * 2 / circleColor.size)
            // 根據(jù)6種顏色蹭睡,獲取6個球
            for (i in circleColor.indices) {
                // 獲取第i個圓的角度 衍菱;如果旋轉(zhuǎn)的話需要加上角度
                val angle = i * rotateAngle
                // x = r * cos(a) + centerX
                // y = r * sin(a) + centerY
                val cx = (currentRotateRadius * cos(angle) + centerX).toFloat()
                val cy = (currentRotateRadius * sin(angle) + centerY).toFloat()
                paint.color = circleColor[i]
                canvas.drawCircle(cx, cy, circleRadius, paint)
            }
        }

        private fun drawBackground(canvas: Canvas) {
            //畫背景色
            canvas.drawColor(bgColor)

        }

    }


}
六個靜態(tài)的圓

第二步讓六個圓動起來

package rc.loveq.splashview

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import android.view.animation.LinearInterpolator
import kotlin.math.hypot
import kotlin.properties.Delegates
import kotlin.math.cos
import kotlin.math.sin


/**
 * Author:Rc
 * 0n 2019/8/26 22:42
 */
class SplashView(context: Context, attrs: AttributeSet) : View(context, attrs) {


    // 背景色
    private val bgColor = Color.WHITE

    // 6個圓的顏色
    private val circleColor: IntArray = context.resources.getIntArray(R.array.splash_circle_colors)

    // 6個圓畫筆
    private var paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)


    //View中心點的x坐標(biāo)
    var centerX by Delegates.notNull<Float>()

    //View中心點的y坐標(biāo)
    var centerY by Delegates.notNull<Float>()

    //當(dāng)前View對角線的一半
    var distance by Delegates.notNull<Float>()


    private val rotateRadius = 90f

    // 默認(rèn)六個圓圍繞的外圍圓半徑
    private val currentRotateRadius = rotateRadius

    // 6個圓半徑
    private val circleRadius = 18f

    // 當(dāng)前splash的狀態(tài)
    private var splashState: SplashState? = null


    // 旋轉(zhuǎn)動畫時長
    private val rotateDuration = 1200


    // 當(dāng)前大圓的旋轉(zhuǎn)角度
    private var currentRotateAngle = 0f


    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        //獲取中心點
        centerX = (w / 2).toFloat()
        centerY = (h / 2).toFloat()

        //當(dāng)前View對角線的一半
        distance = (hypot(x.toDouble(), h.toDouble()) / 2).toFloat()

    }


    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        //初始化默認(rèn)狀態(tài)
        splashState ?: splashState.apply {
            splashState = RotateStatus()
        }
        splashState!!.drawState(canvas)

    }


    /**
     * 閃屏頁的狀態(tài)的抽象類
     */
    abstract inner class SplashState {
        abstract fun drawState(canvas: Canvas)
    }

    /**
     * 1.旋轉(zhuǎn)
     */
    inner class RotateStatus : SplashState() {

        init {
            val valueAnimator = ValueAnimator.ofFloat(0f, (Math.PI * 2).toFloat())
                .apply {
                    repeatCount = 2
                    duration = rotateDuration.toLong()
                    interpolator = LinearInterpolator()
                }

            valueAnimator.addUpdateListener {
                currentRotateAngle = it.animatedValue as Float

                invalidate()
            }

            valueAnimator.start()
        }

        override fun drawState(canvas: Canvas) {
            drawBackground(canvas)
            drawCircle(canvas)
        }

        private fun drawCircle(canvas: Canvas) {
            //每個圓的弧度
            val rotateAngle = (Math.PI * 2 / circleColor.size)
            // 根據(jù)6種顏色,獲取6個球
            for (i in circleColor.indices) {
                // 獲取第i個圓的角度 肩豁;如果旋轉(zhuǎn)的話需要加上角度
                val angle = i * rotateAngle + currentRotateAngle
                // x = r * cos(a) + centerX
                // y = r * sin(a) + centerY
                val cx = (currentRotateRadius * cos(angle) + centerX).toFloat()
                val cy = (currentRotateRadius * sin(angle) + centerY).toFloat()
                paint.color = circleColor[i]
                canvas.drawCircle(cx, cy, circleRadius, paint)
            }
        }

        private fun drawBackground(canvas: Canvas) {
            //畫背景色
            canvas.drawColor(bgColor)

        }

    }


}

上面的代碼中脊串,在RotateStatus構(gòu)造函數(shù)中辫呻,使用ValueAnimator來動態(tài)更新每個圓的角度,從而使六個圓動起來琼锋。

旋轉(zhuǎn)6個圓

第三步實現(xiàn)聚合效果

package rc.loveq.splashview

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.animation.LinearInterpolator
import android.view.animation.OvershootInterpolator
import androidx.core.animation.addListener
import kotlin.math.hypot
import kotlin.properties.Delegates
import kotlin.math.cos
import kotlin.math.sin


/**
 * Author:Rc
 * 0n 2019/8/26 22:42
 */
class SplashView(context: Context, attrs: AttributeSet) : View(context, attrs) {


    // 背景色
    private val bgColor = Color.WHITE

    // 6個圓的顏色
    private val circleColor: IntArray = context.resources.getIntArray(R.array.splash_circle_colors)

    // 6個圓畫筆
    private var paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)


    //View中心點的x坐標(biāo)
    var centerX by Delegates.notNull<Float>()

    //View中心點的y坐標(biāo)
    var centerY by Delegates.notNull<Float>()

    //當(dāng)前View對角線的一半
    var distance by Delegates.notNull<Float>()


    private val rotateRadius = 90f

    // 默認(rèn)六個圓圍繞的外圍圓半徑
    private var currentRotateRadius = rotateRadius

    // 6個圓半徑
    private val circleRadius = 18f

    // 當(dāng)前splash的狀態(tài)
    private var splashState: SplashState? = null


    // 旋轉(zhuǎn)動畫時長
    private val rotateDuration = 1200


    // 當(dāng)前大圓的旋轉(zhuǎn)角度
    private var currentRotateAngle = 0f


    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        //獲取中心點
        centerX = (w / 2).toFloat()
        centerY = (h / 2).toFloat()

        //當(dāng)前View對角線的一半
        distance = (hypot(x.toDouble(), h.toDouble()) / 2).toFloat()

    }


    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        //初始化默認(rèn)狀態(tài)
        splashState ?: splashState.apply {
            splashState = RotateStatus()
        }
        splashState!!.drawState(canvas)

    }


    /**
     * 閃屏頁的狀態(tài)的抽象類
     */
    abstract inner class SplashState {
        abstract fun drawState(canvas: Canvas)
    }

    /**
     * 1.旋轉(zhuǎn)
     */
    inner class RotateStatus : SplashState() {

        init {
            val valueAnimator = ValueAnimator.ofFloat(0f, (Math.PI * 2).toFloat())
                .apply {
                    repeatCount = 2
                    duration = rotateDuration.toLong()
                    interpolator = LinearInterpolator()
                }

            valueAnimator.addUpdateListener {
                currentRotateAngle = it.animatedValue as Float

                invalidate()
            }


            valueAnimator.addListener(object : AnimatorListenerAdapter() {

                override fun onAnimationEnd(animation: Animator?) {
                    splashState = MerginStatus()
                }


            })

            valueAnimator.start()
        }

        override fun drawState(canvas: Canvas) {
            drawBackground(canvas)
            drawCircle(canvas)
        }


    }


    /**
     * 2.聚合擴(kuò)散
     */
    inner class MerginStatus : SplashState() {

        init {
            val valueAnimator = ValueAnimator.ofFloat(circleRadius, rotateRadius)
                .apply {
                    duration = rotateDuration.toLong()
                    interpolator = OvershootInterpolator()
                }
            valueAnimator.addUpdateListener {
                currentRotateRadius = it.animatedValue as Float
                invalidate()
            }

            //這里沒有使用start,而是使用reverse
            //reverse 會從ValueAnimator end的地方開始放闺,應(yīng)用OvershootInterpolator進(jìn)行值的更新
            valueAnimator.reverse()


        }

        override fun drawState(canvas: Canvas) {
            drawBackground(canvas)
            drawCircle(canvas)
        }


    }


    private fun drawCircle(canvas: Canvas) {
        //每個圓的弧度
        val rotateAngle = (Math.PI * 2 / circleColor.size)
        // 根據(jù)6種顏色,獲取6個球
        for (i in circleColor.indices) {
            // 獲取第i個圓的角度 缕坎;如果旋轉(zhuǎn)的話需要加上角度
            val angle = i * rotateAngle + currentRotateAngle
            // x = r * cos(a) + centerX
            // y = r * sin(a) + centerY
            val cx = (currentRotateRadius * cos(angle) + centerX).toFloat()
            val cy = (currentRotateRadius * sin(angle) + centerY).toFloat()
            paint.color = circleColor[i]
            canvas.drawCircle(cx, cy, circleRadius, paint)
        }
    }

    private fun drawBackground(canvas: Canvas) {
        //畫背景色
        canvas.drawColor(bgColor)

    }

}

旋轉(zhuǎn)完成后怖侦,進(jìn)行聚合動畫,動畫使用的差值器是OvershootInterpolator谜叹,這個差值器是有彈性回彈的效果匾寝。

聚合效果

第四步擴(kuò)展

package rc.loveq.splashview

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.animation.LinearInterpolator
import android.view.animation.OvershootInterpolator
import androidx.core.animation.addListener
import kotlin.math.hypot
import kotlin.properties.Delegates
import kotlin.math.cos
import kotlin.math.sin
import android.icu.lang.UCharacter.GraphemeClusterBreak.T


/**
 * Author:Rc
 * 0n 2019/8/26 22:42
 */
class SplashView(context: Context, attrs: AttributeSet) : View(context, attrs) {


    // 背景色
    private val bgColor = Color.WHITE

    // 6個圓的顏色
    private val circleColor: IntArray = context.resources.getIntArray(R.array.splash_circle_colors)

    // 6個圓畫筆
    private var paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)


    //View中心點的x坐標(biāo)
    var centerX by Delegates.notNull<Float>()

    //View中心點的y坐標(biāo)
    var centerY by Delegates.notNull<Float>()

    //當(dāng)前View對角線的一半
    var distance by Delegates.notNull<Float>()


    private val rotateRadius = 90f

    // 默認(rèn)六個圓圍繞的外圍圓半徑
    private var currentRotateRadius = rotateRadius

    // 6個圓半徑
    private val circleRadius = 18f

    // 當(dāng)前splash的狀態(tài)
    private var splashState: SplashState? = null


    // 旋轉(zhuǎn)動畫時長
    private val rotateDuration = 1200


    // 當(dāng)前大圓的旋轉(zhuǎn)角度
    private var currentRotateAngle = 0f


    // 擴(kuò)散圓的半徑
    private var currentHoleRadius = 0f

    private var holePaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
        .apply {
            style = Paint.Style.STROKE
            color = bgColor
        }


    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        //獲取中心點
        centerX = (w / 2).toFloat()
        centerY = (h / 2).toFloat()

        //當(dāng)前View對角線的一半
        distance = (hypot(w.toDouble(), h.toDouble()) / 2f).toFloat()

    }


    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        //初始化默認(rèn)狀態(tài)
        splashState ?: splashState.apply {
            splashState = RotateStatus()
        }
        splashState!!.drawState(canvas)

    }


    /**
     * 閃屏頁的狀態(tài)的抽象類
     */
    abstract inner class SplashState {
        abstract fun drawState(canvas: Canvas)
    }

    /**
     * 1.旋轉(zhuǎn)
     */
    inner class RotateStatus : SplashState() {

        init {
            val valueAnimator = ValueAnimator.ofFloat(0f, (Math.PI * 2).toFloat())
                .apply {
                    repeatCount = 1
                    duration = rotateDuration.toLong()
                    interpolator = LinearInterpolator()
                }

            valueAnimator.addUpdateListener {
                currentRotateAngle = it.animatedValue as Float

                invalidate()
            }


            valueAnimator.addListener(object : AnimatorListenerAdapter() {

                override fun onAnimationEnd(animation: Animator?) {
                    splashState = MerginStatus()
                }


            })

            valueAnimator.start()
        }

        override fun drawState(canvas: Canvas) {
            drawBackground(canvas)
            drawCircle(canvas)
        }


    }


    /**
     * 2.聚合擴(kuò)散
     */
    inner class MerginStatus : SplashState() {

        init {
            val valueAnimator = ValueAnimator.ofFloat(circleRadius, rotateRadius)
                .apply {
                    duration = rotateDuration.toLong()
                    interpolator = OvershootInterpolator()
                }
            valueAnimator.addUpdateListener {
                currentRotateRadius = it.animatedValue as Float
                invalidate()
            }


            valueAnimator.addListener(object : AnimatorListenerAdapter() {

                override fun onAnimationEnd(animation: Animator?) {
                    splashState = ExpandState()
                }


            })

            //這里沒有使用start,而是使用reverse
            //reverse 會從ValueAnimator end的地方開始,應(yīng)用OvershootInterpolator進(jìn)行值的更新
            valueAnimator.reverse()


        }

        override fun drawState(canvas: Canvas) {
            drawBackground(canvas)
            drawCircle(canvas)
        }


    }

    /**
     * 3.擴(kuò)展
     */
    inner class ExpandState : SplashState() {

        init {
            val valueAnimator = ValueAnimator.ofFloat(circleRadius, distance)
                .apply {
                    duration = rotateDuration.toLong()
                    interpolator = LinearInterpolator()
                }
            valueAnimator.addUpdateListener {
                currentHoleRadius = it.animatedValue as Float
                invalidate()
            }
            valueAnimator.start()

        }


        override fun drawState(canvas: Canvas) {
            drawBackground(canvas)
        }


    }

    private fun drawCircle(canvas: Canvas) {
        //每個圓的弧度
        val rotateAngle = (Math.PI * 2 / circleColor.size)
        // 根據(jù)6種顏色荷腊,獲取6個球
        for (i in circleColor.indices) {
            // 獲取第i個圓的角度 旗吁;如果旋轉(zhuǎn)的話需要加上角度
            val angle = i * rotateAngle + currentRotateAngle
            // x = r * cos(a) + centerX
            // y = r * sin(a) + centerY
            val cx = (currentRotateRadius * cos(angle) + centerX).toFloat()
            val cy = (currentRotateRadius * sin(angle) + centerY).toFloat()
            paint.color = circleColor[i]
            canvas.drawCircle(cx, cy, circleRadius, paint)
        }
    }

    private fun drawBackground(canvas: Canvas) {
        if (currentHoleRadius > 0) {
            //繪制空心圓
            val strokeWidth = distance - currentHoleRadius
            val radius = strokeWidth / 2 + currentHoleRadius
            holePaint.strokeWidth = strokeWidth
            canvas.drawCircle(centerX, centerY, radius, holePaint)

        } else {
            //畫背景色
            canvas.drawColor(bgColor)
        }

    }

}

水波的效果,就是通過畫空心圓實現(xiàn)停局,不斷增加空心圓的半徑,減少畫筆的寬度香府。


最終效果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末董栽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子企孩,更是在濱河造成了極大的恐慌锭碳,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件勿璃,死亡現(xiàn)場離奇詭異擒抛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)补疑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門歧沪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人莲组,你說我怎么就攤上這事诊胞。” “怎么了锹杈?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵撵孤,是天一觀的道長。 經(jīng)常有香客問我竭望,道長邪码,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任咬清,我火速辦了婚禮闭专,結(jié)果婚禮上奴潘,老公的妹妹穿的比我還像新娘。我一直安慰自己喻圃,他們只是感情好萤彩,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著斧拍,像睡著了一般雀扶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上肆汹,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天愚墓,我揣著相機(jī)與錄音,去河邊找鬼昂勉。 笑死浪册,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的岗照。 我是一名探鬼主播村象,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼攒至!你這毒婦竟也來了厚者?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤迫吐,失蹤者是張志新(化名)和其女友劉穎库菲,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體志膀,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡熙宇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了溉浙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烫止。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖戳稽,靈堂內(nèi)的尸體忽然破棺而出烈拒,到底是詐尸還是另有隱情,我是刑警寧澤广鳍,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布荆几,位于F島的核電站,受9級特大地震影響赊时,放射性物質(zhì)發(fā)生泄漏吨铸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一祖秒、第九天 我趴在偏房一處隱蔽的房頂上張望诞吱。 院中可真熱鬧舟奠,春花似錦、人聲如沸房维。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咙俩。三九已至耿戚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間阿趁,已是汗流浹背膜蛔。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留脖阵,地道東北人皂股。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像命黔,于是被迫代替她去往敵國和親呜呐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 【Android 動畫】 動畫分類補(bǔ)間動畫(Tween動畫)幀動畫(Frame 動畫)屬性動畫(Property ...
    Rtia閱讀 6,115評論 1 38
  • 1 背景 不能只分析源碼呀悍募,分析的同時也要整理歸納基礎(chǔ)知識卵史,剛好有人微博私信讓全面說說Android的動畫,所以今...
    未聞椛洺閱讀 2,697評論 0 10
  • 動畫基礎(chǔ)概念 動畫分類 Android 中動畫分為兩種搜立,一種是 Tween 動畫、還有一種是 Frame 動畫槐秧。 ...
    Rtia閱讀 1,221評論 0 6
  • 1 背景 不能只分析源碼呀啄踊,分析的同時也要整理歸納基礎(chǔ)知識,剛好有人微博私信讓全面說說Android的動畫刁标,所以今...
    lisx_閱讀 961評論 0 0
  • 轉(zhuǎn)載一篇高質(zhì)量博文颠通,原地址請戳這里轉(zhuǎn)載下來方便今后查看。1 背景不能只分析源碼呀膀懈,分析的同時也要整理歸納基礎(chǔ)知識顿锰,...
    Elder閱讀 1,938評論 0 24