我们的app经常遇到这样一种场景,就是小图到大图的转换,这时候如果有个缩放动画就会很自然。本节将介绍如何使用动画进行缩放图片,在点击头像看大图这种场景可以使用。本文的例子的示意图如下所示:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
android:id="@+id/container"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".animation.EnlargeImageActivity">
<ImageButton
android:id="@+id/imageBtn"
android:layout_width="100dp"
android:layout_height="75dp"
android:scaleType="centerCrop"
android:src="@drawable/pic_11"/>
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/pic_11"
android:visibility="invisible"/>
</android.support.constraint.ConstraintLayout>
//从小到大
private fun zoomImageFromThumb() {
mCurrentAnimator?.cancel()
imageView.setImageResource(R.drawable.pic_11)
//获取尺寸
val startBoundsInt = Rect()
val finalBoundsInt = Rect()
val globalOffset = Point()
imageBtn.getGlobalVisibleRect(startBoundsInt)
imageView.getGlobalVisibleRect(finalBoundsInt, globalOffset)
//调整使top=left=0
startBoundsInt.offset(-globalOffset.x, -globalOffset.y)
finalBoundsInt.offset(-globalOffset.x, -globalOffset.y)
val startBounds = RectF(startBoundsInt)
val finalBounds = RectF(finalBoundsInt)
//计算宽高缩放比
val startScale: Float
if ((finalBounds.width() / finalBounds.height() > startBounds.width() / startBounds.height())) {
startScale = startBounds.height() / finalBounds.height()
val startWidth: Float = startScale * finalBounds.width()
val deltaWidth: Float = (startWidth - startBounds.width()) / 2
startBounds.left -= deltaWidth.toInt()
startBounds.right += deltaWidth.toInt()
} else {
// Extend start bounds vertically
startScale = startBounds.width() / finalBounds.width()
val startHeight: Float = startScale * finalBounds.height()
val deltaHeight: Float = (startHeight - startBounds.height()) / 2f
startBounds.top -= deltaHeight.toInt()
startBounds.bottom += deltaHeight.toInt()
}
imageBtn.visibility = View.INVISIBLE
imageView.visibility = View.VISIBLE
imageView.pivotX = 0f
imageView.pivotY = 0f
mCurrentAnimator = AnimatorSet().apply {
//x、y、scaleX、scaleY四个维度一起动画
play(ObjectAnimator.ofFloat(
imageView,
View.X,
startBounds.left,
finalBounds.left)
).apply {
with(ObjectAnimator.ofFloat(imageView, View.Y, startBounds.top, finalBounds.top))
with(ObjectAnimator.ofFloat(imageView, View.SCALE_X, startScale, 1f))
with(ObjectAnimator.ofFloat(imageView, View.SCALE_Y, startScale, 1f))
}
duration = mShortAnimationDuration.toLong()
interpolator = DecelerateInterpolator()
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
mCurrentAnimator = null
}
override fun onAnimationCancel(animation: Animator) {
mCurrentAnimator = null
}
})
start()
}
}
其中有一点说明,宽高采用了同样的缩放比,但是由于初始尺寸的宽高比不一定完全等于结束时的宽高比,因此会对初始尺寸进行微调,使比例与最终比例一致。针对我们这里的情况,示意图如下: ![]