设置visibility把View隐藏后再次显示出现旋转中心错误
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
int pivotYType, float pivotYValue) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mPivotXValue = pivotXValue;
mPivotXType = pivotXType;
mPivotYValue = pivotYValue;
mPivotYType = pivotYType;
initializePivotPoint();
}
正常情况设置旋转中心为中心点时写法
RotateAnimation anim = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f)
在当前View显示时,设置动画正常播放,如果默认View的状态为GONE
,设置动画后在显示后进行播放,会出现旋转中心变成左上角的情况
而预期结果是这样的
深入源码
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
}
源码中,根据设置的参数和属性计算出旋转中心的具体值,我们需要看下该方法什么时候调用
/**
* Utility function, called by draw(canvas, parent, drawingTime) to handle the less common
* case of an active Animation being run on the view.
*/
private boolean applyLegacyAnimation(ViewGroup parent, long drawingTime,
Animation a, boolean scalingRequired) {
Transformation invalidationTransform;
final int flags = parent.mGroupFlags;
final boolean initialized = a.isInitialized();
if (!initialized) {
a.initialize(mRight - mLeft, mBottom - mTop, parent.getWidth(), parent.getHeight());
a.initializeInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop);
if (mAttachInfo != null) a.setListenerHandler(mAttachInfo.mHandler);
onAnimationStart();
}
...
}
该方法在View的draw方法进行调用,此时宽高测量完毕,可以准确算出旋转中心的位置
并且有个是否初始化过的前置判断,确保只会触发一次。
public void initialize(int width, int height, int parentWidth, int parentHeight) {
reset();
mInitialized = true;
}
一旦初始化,直接更改字段
在未显示时,宽高为0,自然导致旋转中心变成左上角
问题解决
- 在设置显示时再讲动画设置进去
- 自定义View,在onLayout时手动调用initialize,并将相关参数传入
动画的View在隐藏或者停止后仍残留在屏幕
在View消失后,补间动画仍然显示
问题解决
- 不要设置setFillAfter属性,否则会残留
- 隐藏后手动设置clearAnimation对动画进行清除操作
本文由 bt 创作,采用 知识共享署名4.0 国际许可协议进行许可。
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。