emmm发烧了两天,今天我们开看看图片动画的相关知识。
关于动画我一直是接触很少,也没有细心去学过。
我们上节课讨论过,图片的显示其实就是维护一个RectF对象,再使用重绘方法即可完成显示效果。
而由于简单的动画并没有涉及view相关属性的变化,所以我们需要为Animator注册监听,监听动画的update,以此对相关属性就行修改,以维护好状态
关于估值器相关知识大家可以移步这里
https://blog.csdn.net/xiangzhihong8/article/details/52260566
class ClipImageEvaluator : TypeEvaluator<ClipImageState> {
private val TAG = "ClipImageEvaluator"
private var clipImageState: ClipImageState? = null
override fun evaluate(fraction: Float, startValue: ClipImageState?, endValue: ClipImageState?): ClipImageState {
if (startValue != null && endValue != null) {
var left = startValue.frame.left + fraction * (endValue.frame.left - startValue.frame.left)
var top = startValue.frame.top + fraction * (endValue.frame.top - startValue.frame.top)
var right = startValue.frame.right + fraction * (endValue.frame.right - startValue.frame.right)
var bottom = startValue.frame.bottom + fraction * (endValue.frame.bottom - startValue.frame.bottom)
if (clipImageState != null) {
clipImageState?.frame = RectF(left, top, right, bottom)
} else {
clipImageState = ClipImageState(RectF(left, top, right, bottom))
}
}
return clipImageState ?: ClipImageState(RectF(0f, 0f, 0f, 0f))
}
}
简单来说我们的clipImageState维护一个RectF,通过fraction计算每个动画更新导致RectF变化后的新值。
之后我们会得到这个clipImageState对相关的状态进行更新,以保证我们的参数随着动画保持着正确的变化。
class ClipImageAnimator() : ValueAnimator() {
private var mEvaluator: ClipImageEvaluator? = null
init {
interpolator = AccelerateDecelerateInterpolator()
}
override fun setObjectValues(vararg values: Any?) {
super.setObjectValues(*values)
if (mEvaluator == null) {
mEvaluator = ClipImageEvaluator()
}
setEvaluator(mEvaluator)
}
fun setChangeState(sState: ClipImageState, eState: ClipImageState) {
setObjectValues(sState, eState)
}
}
Animator就比较简单了,使用我们刚刚定义好的估值器
在ontouchEvent中 我们监听ACTION_UP
startAnimation(ClipImageState(zoomImageView.getFrame()),
ClipImageState(zoomImageView.getResetTransEnd()))
override fun onAnimationUpdate(animation: ValueAnimator?) {
val state = animation?.animatedValue as ClipImageState
zoomImageView.setFrame(state.frame)
invalidate()
}
将计算的到的新的frame赋值给我们的图片类即可。
最后关于getResetTransEnd方法实现就很简单了,我们只需要将frame的上下左右与0以及图片的长宽进行比较,然后调用之前写的onscroll方法进行修正位置即可,换成裁剪框就是与裁剪框边缘进行比较,这个之后我们再进行。
项目github地址:https://github.com/lqy20160609/ImageClip