android 转场动画 4.4,Android 转场动画之揭露动画的使用

//将 Activity 的揭露效果写在 Base 类中,需要揭露动画效果时继承abstract class BaseAnimRevealActivity : BaseActivityWrapper() {

companion object {

//手动往 intent 里传入上个界面的点击位置坐标 val CLICK_X = "CLICK_X"

val CLICK_Y = "CLICK_Y"

var time = 300L

}

private var onGlobalLayout: ViewTreeObserver.OnGlobalLayoutListener? = null

//揭露(进入)动画 var mAnimReveal: Animator? = null

//反揭露(退出)动画 var mAnimRevealR: Animator? = null

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

circularReveal(intent)

}

//Activity 揭露(进入)动画,进入时使用 private fun circularReveal(intent: Intent?) {

//系统提供的揭露动画需 5.0 及以上的 sdk 版本,当我们获取不到上个界面的点击区域时就不展示揭露动画,因为此时没有合适的锚点 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP ||

(intent?.sourceBounds == null && intent?.hasExtra(CLICK_X)?.not() ?: true)

) return

val rect = intent?.sourceBounds

val v = window.decorView

v.visibility = View.INVISIBLE

@SuppressWarnings

onGlobalLayout = object : ViewTreeObserver.OnGlobalLayoutListener {

override fun onGlobalLayout() {//此时既是开始揭露动画的最佳时机 println("centerX ${rect?.centerX() ?: intent?.getIntExtra(CLICK_X, 0)}")

println("centerY ${rect?.centerY() ?: intent?.getIntExtra(CLICK_Y, 0)}")

// mAnimReveal?.removeAllListeners()// mAnimReveal?.cancel() if (mAnimReveal == null) {

mAnimReveal = ViewAnimationUtils.createCircularReveal(

v,

rect?.centerX() ?: intent?.getIntExtra(CLICK_X, 0) ?: 0,

rect?.centerY() ?: intent?.getIntExtra(CLICK_Y, 0) ?: 0,

0f,

v.height.toFloat()

)

mAnimReveal?.duration = time

mAnimReveal?.interpolator = LinearInterpolator()

mAnimReveal?.addListener(object : Animator.AnimatorListener {

override fun onAnimationRepeat(animation: Animator?) {

}

override fun onAnimationEnd(animation: Animator?) {

onGlobalLayout?.let {

//我们需要在揭露动画进行完后及时移除回调 v?.viewTreeObserver?.removeOnGlobalLayoutListener(it)

}

}

override fun onAnimationCancel(animation: Animator?) {

}

override fun onAnimationStart(animation: Animator?) {

}

})

}

mAnimReveal?.isStarted?.let {

if (!it) {

mAnimReveal?.start()

}

}

}

}

//视图可见性发生变化时的回调,回调里正是开始揭露动画的最佳时机 v.viewTreeObserver.addOnGlobalLayoutListener(onGlobalLayout)

}

//Activtiy 反揭露(退出)动画,即退出时的过渡动画, // 这么起名可能不恰当,其实还是同样的动画, // 只不过揭露的起始和终结半径跟上面相比反过来了 private fun circularRevealReverse(intent: Intent?) {

//系统提供的揭露动画需 5.0 及以上的 sdk 版本,当我们获取不到上个界面的点击区域时就不展示揭露动画,因为此时没有合适的锚点 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP ||

(intent?.sourceBounds == null && intent?.hasExtra(CLICK_X)?.not() ?: true)

) {

super.onBackPressed()

return

}

val rect = intent?.sourceBounds

val v = window.decorView

mAnimRevealR?.removeAllListeners()

mAnimRevealR?.cancel()

mAnimRevealR = ViewAnimationUtils.createCircularReveal(

v,

rect?.centerX() ?: intent?.getIntExtra(CLICK_X, 0) ?: 0,

rect?.centerY() ?: intent?.getIntExtra(CLICK_Y, 0) ?: 0,

v.height.toFloat(),

0f

)

mAnimRevealR?.duration = time

mAnimRevealR?.interpolator = LinearInterpolator()

mAnimRevealR?.addListener(object : Animator.AnimatorListener {

override fun onAnimationRepeat(animation: Animator?) {

}

override fun onAnimationEnd(animation: Animator?) {

println("onAnimationEnd")

v.visibility = View.GONE

this@BaseAnimRevealActivity.finish()

}

override fun onAnimationCancel(animation: Animator?) {

}

override fun onAnimationStart(animation: Animator?) {

println("onAnimationStart")

}

})

mAnimRevealR?.start()

}

//回退时应用反揭露动画 override fun onBackPressed() {

circularRevealReverse(intent)

}

override fun onDestroy() {

//及时释放资源以保证代码健壮性 mAnimReveal?.removeAllListeners()

mAnimReveal?.cancel()

mAnimRevealR?.removeAllListeners()

mAnimRevealR?.cancel()

//及时释放资源以保证代码健壮性 onGlobalLayout?.let {

window.decorView.viewTreeObserver?.removeOnGlobalLayoutListener(it)

}

super.onDestroy()

}

//这个方法很重要,如果我们应用的启动图标在桌面上的位置有变化,可在此收到新的位置信息,然而经作者本人实践作用十分有限 override fun onNewIntent(intent: Intent?) {

super.onNewIntent(intent)

println("---------onNewIntent")

circularReveal(intent)

//更新intent this.intent = intent

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值