之前一个自定义控件的特效,发现在Android 5.0机型上无法起效。原本代码如下:
private class AnimatorBean implements ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {
private View mBubbleView;
private double mAmplitude;
private double mOffset;
private double mFreq;
private Integer mChoiceIconResID = null;
/**@param choiceIconResIS 不随机使用icon,而是指定使用某个icon**/
public void setChoiceIconResID(int choiceIconResIS) {
this.mChoiceIconResID = choiceIconResIS;
}
@Override
public void onAnimationStart(Animator animation, boolean isReverse) {
//一半空间宽度的振幅 × 随机缩放系数
mAmplitude = Math.random() * mWidth / 2;
//随机相位
mOffset = Math.random() * 90;
//随机频率
mFreq = 180f + Math.random() * 180f;
//创建小泡泡
mBubbleView = new Button(getContext());
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(PixelUtil.dp2px(30), PixelUtil.dp2px(30));
mBubbleView.setLayoutParams(params);
mBubbleView.setX(mWidth / 2);
mBubbleView.setY(mHeight);
if (mChoiceIconResID == null) {
mBubbleView.setBackgroundResource(mBubbleIcons.get(new Random().nextInt(mBubbleIcons.size())));
} else {
mBubbleView.setBackgroundResource(mChoiceIconResID);
}
addView(mBubbleView);
}
@Override
public void onAnimationEnd(Animator animation, boolean isReverse) {
//消失了,可以销毁了
removeView(mBubbleView);
}
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
if (mBubbleView != null) {
float curVal = (float) animation.getAnimatedValue();
float scale = (50f - Math.abs(50f - curVal)) / 50f;
float y = ((1 - curVal / 100f) * mHeight);
double x = (Math.sin(Math.toRadians(mFreq * (1 - curVal / 100f) + mOffset))) * mAmplitude; //通过sin函数结合随机参数和进度值,产生随y值增大而产生不同的波浪x值
mBubbleView.setX((float) x + mWidth / 2);
mBubbleView.setY(y);
mBubbleView.setScaleX(scale * 1.6f);
mBubbleView.setScaleY(scale * 1.6f);
mBubbleView.setAlpha(scale);
}
}
}
在Android 5.0中打断点发现
onAnimationStart(Animator animation, boolean isReverse)
onAnimationEnd(Animator animation, boolean isReverse)
这两个方法并没有被执行,反而:
onAnimationStart(Animator animation)
onAnimationEnd(Animator animation)
被执行了,因此导致了动画效果没有被初始化,也没有调用override之后的view销毁操作。推测是Android 5.0使用ValueAnimator时,并且既添加了addUpdateListener和addListener之后,会优先调用AnimatorListener接口的回调方法。因此把代码修改一下,从而实现一个间接调用即可解决问题:
private class AnimatorBean implements ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {
private View mBubbleView;
private double mAmplitude;
private double mOffset;
private double mFreq;
private Integer mChoiceIconResID = null;
/**@param choiceIconResIS 不随机使用icon,而是指定使用某个icon**/
public void setChoiceIconResID(int choiceIconResIS) {
this.mChoiceIconResID = choiceIconResIS;
}
@Override
public void onAnimationStart(Animator animation, boolean isReverse) {
//一半空间宽度的振幅 × 随机缩放系数
mAmplitude = Math.random() * mWidth / 2;
//随机相位
mOffset = Math.random() * 90;
//随机频率
mFreq = 180f + Math.random() * 180f;
//创建小泡泡
mBubbleView = new Button(getContext());
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(PixelUtil.dp2px(30), PixelUtil.dp2px(30));
mBubbleView.setLayoutParams(params);
mBubbleView.setX(mWidth / 2);
mBubbleView.setY(mHeight);
if (mChoiceIconResID == null) {
mBubbleView.setBackgroundResource(mBubbleIcons.get(new Random().nextInt(mBubbleIcons.size())));
} else {
mBubbleView.setBackgroundResource(mChoiceIconResID);
}
addView(mBubbleView);
}
@Override
public void onAnimationEnd(Animator animation, boolean isReverse) {
//消失了,可以销毁了
removeView(mBubbleView);
}
@Override
public void onAnimationStart(Animator animation) {
if (Build.VERSION.SDK_INT <= 22) {
onAnimationStart(animation, false);
}
}
@Override
public void onAnimationEnd(Animator animation) {
if (Build.VERSION.SDK_INT <= 22) {
onAnimationEnd(animation, false);
}
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
if (mBubbleView != null) {
float curVal = (float) animation.getAnimatedValue();
float scale = (50f - Math.abs(50f - curVal)) / 50f;
float y = ((1 - curVal / 100f) * mHeight);
double x = (Math.sin(Math.toRadians(mFreq * (1 - curVal / 100f) + mOffset))) * mAmplitude; //通过sin函数结合随机参数和进度值,产生随y值增大而产生不同的波浪x值
mBubbleView.setX((float) x + mWidth / 2);
mBubbleView.setY(y);
mBubbleView.setScaleX(scale * 1.6f);
mBubbleView.setScaleY(scale * 1.6f);
mBubbleView.setAlpha(scale);
}
}
}
|