Kotlin--›Android 極致體驗,圖片轉場動畫(類似微信/QQ圖片查看效果, 帶拖拽返回, 高擴展, 支持任意類型界面過渡)

效果圖(大於2MB):
在這裏插入圖片描述
本文核心:

Transition
TransitionManager

1. Transition 入門

轉場動畫, 是由若干個Transition對象組成的, 而Transition的本質, 依舊是Animator, 畢竟這纔是Android的動畫.

所以, Transition的作用, 就是用來創建 Animator 的.

Transition 的核心方法如下:

  public abstract void captureStartValues(@NonNull TransitionValues var1);

  public abstract void captureEndValues(@NonNull TransitionValues var1);
  
  @Nullable
   public Animator createAnimator(@NonNull ViewGroup sceneRoot, @Nullable TransitionValues startValues, @Nullable TransitionValues endValues) {
        return null;
   }

captureStartValues

此方法的作用, 就是保存動畫開始時, 需要的值

captureEndValues

此方法的作用, 就是保存動畫結束時, 需要的值

createAnimator

通過動畫開始的值動畫結束的值 創建動畫.

舉個例子:

例子1: ColorTransition(顏色過渡動畫)

class ColorTransition : Transition() {
    companion object {
        private const val KEY = "android:ColorTransition:color"
    }

    override fun captureStartValues(values: TransitionValues) {
        captureValues(values)
    }

    override fun captureEndValues(values: TransitionValues) {
        captureValues(values)
    }

    private fun captureValues(values: TransitionValues) {
        val view = values.view
        if (targets.contains(view)) {
            (view.background as? ColorDrawable)?.let {
                values.values[KEY] = it.color
            }
        }
    }

    override fun createAnimator(
        sceneRoot: ViewGroup,
        startValues: TransitionValues?,
        endValues: TransitionValues?
    ): Animator? {
        if (startValues != null && endValues != null) {
            val startColor = startValues.values[KEY]
            val endColor = endValues.values[KEY]

            if (startColor != endColor) {
                val colorAnimator = ValueAnimator.ofObject(ArgbEvaluator(), startColor, endColor)
                colorAnimator.addUpdateListener { animation ->
                    val color = animation.animatedValue as Int//之後就可以得到動畫的顏色了.
                    startValues.view.setBackgroundColor(color)//設置一下, 就可以看到效果..
                }
                colorAnimator.duration = duration
                colorAnimator.interpolator = interpolator
                return colorAnimator
            }
        }
        return null
    }
}

例子2: AlphaTransition(透明度過渡動畫)

class AlphaTransition : Transition() {
    companion object {
        private const val KEY = "android:AlphaTransition:alpha"
    }

    override fun captureStartValues(values: TransitionValues) {
        captureValues(values)
    }

    override fun captureEndValues(values: TransitionValues) {
        captureValues(values)
    }

    private fun captureValues(values: TransitionValues) {
        val view = values.view
        if (targets.contains(view)) {
            values.values[KEY] = view.alpha
        }
    }

    override fun createAnimator(
        sceneRoot: ViewGroup,
        startValues: TransitionValues?,
        endValues: TransitionValues?
    ): Animator? {
        if (startValues != null && endValues != null) {
            val startAlpha: Float = startValues.values[KEY] as Float
            val endAlpha: Float = endValues.values[KEY] as Float

            if (startAlpha != endAlpha) {
                val animator = ValueAnimator.ofFloat(startAlpha, endAlpha)
                animator.addUpdateListener { animation ->
                    val value = animation.animatedValue as Float
                    startValues.view.alpha = value
                }
                animator.duration = duration
                animator.interpolator = interpolator
                return animator
            }
        }
        return null
    }
}

到這裏, 是不是 覺得Transition很簡單?

其實就是這麼簡單.

那怎麼使用Transition對象呢?
莫急.
接下來就是…

2.TransitionManager 使用

注意,注意,注意:

使用Transition三步驟:

  1. 設置動畫view動畫開始時的屬性
  2. 創建Transition對象, 調用 TransitionManager#beginDelayedTransition 方法.
  3. 設置動畫view動畫結束時的屬性

之後, 動畫就會自動執行.

寫成代碼就是如下步驟:

 open fun doTransition() {
     onTransitionBeforeValues()  //對應步驟1
     post { //請注意, post是核心操作, 必須使用post, 否則 `動畫view`的屬性還沒有被 `captureStartValues` 捕捉, 就被 `onTransitionAfterValues` 覆蓋了.
         onCreateTransition()    //對應步驟2
         onTransitionAfterValues()  //對應步驟3
     }
 }
 open fun createTransitionSet(): TransitionSet {
       val transitionSet = TransitionSet()
       transitionSet.addTransition(ChangeTransform())
       transitionSet.addTransition(ChangeScroll())
       transitionSet.addTransition(ChangeClipBounds())
       transitionSet.addTransition(ChangeImageTransform())
       transitionSet.addTransition(ChangeBounds())
       transitionSet.addTransition(ColorTransition())

       transitionSet.duration = ANIM_DURATION
       transitionSet.interpolator = FastOutSlowInInterpolator()
       transitionSet.addTarget(rootLayout)
       return transitionSet
   }

明白了核心關鍵, 剩下的就是針對項目的邏輯封裝了.

各位, 請直接前往 磚廠地址 查看.

友情提示

如果使用Glide加載圖片, 請使用原始大小的圖片 requestOptions.override(Target.SIZE_ORIGINAL) , 否則圖片在過渡的時候, 不能做到無縫切換.


羣內有各(pian)種(ni)各(jin)樣(qun)的大佬,等你來撩.

聯繫作者

點此快速加羣

請使用QQ掃碼加羣, 小夥伴們都在等着你哦!

關注我的公衆號, 每天都能一起玩耍哦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章