Kotlin--›极致体验,图片转场动画(类似微信/QQ图片查看效果, 带拖拽返回, 高扩展, 支持任意类型界面过渡)

效果图(大于2MB):
Kotlin--›极致体验,图片转场动画(类似微信/QQ图片查看效果, 带拖拽返回, 高扩展, 支持任意类型界面过渡)
本文核心:

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扫码加群, 小伙伴们都在等着你哦!

Kotlin--›极致体验,图片转场动画(类似微信/QQ图片查看效果, 带拖拽返回, 高扩展, 支持任意类型界面过渡)

关注我的公众号, 每天都能一起玩耍哦!

Kotlin--›极致体验,图片转场动画(类似微信/QQ图片查看效果, 带拖拽返回, 高扩展, 支持任意类型界面过渡)