自定义视图删除所有 postInvalidate()
Custom View remove all postInvalidate()
正如Writing Custom View for Android所说:
Remove any posted Runnable in onDetachedFromWindow
我有一个自定义视图,CircleCheckBox
。单击时将执行动画。
动画由View#postInvalidate()
实现。
那么有没有办法删除 onDetachedFromWindow()
中任何已发布的可运行对象?
编辑
让我告诉你 CircleCheckBox
是如何工作的。
第 1 步
在CircleCheckBox
构造函数中我设置了View#OnClickListener
:
this.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
toggle();
if (mListener != null) {
mListener.onCheckedChanged(isChecked());
}
}
});
第 2 步
在方法 toggle()
中它将调用:
@Override
public void setChecked(boolean checked) {
....
if (checked) {
startCheckedAnimation();
} else {
startUnCheckedAnimation();
}
}
第 3 步
假设 startCheckedAnimation()
。
private void startCheckedAnimation() {
// circle animation
ValueAnimator circleAnimator = ValueAnimator.ofFloat(0f, 1f);
circleAnimator.setInterpolator(new DecelerateInterpolator());
circleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
mArcPath.reset();
mArcPath.addArc(mRectF, -159, 360 * (1 - value));
postInvalidate();
}
});
circleAnimator.setDuration(mDuration / 4);
circleAnimator.start();
}
我使用 postInvalidate()
方法让视图调用 onDraw()
。
我想你可以使用 removeCallbacks(Runnable r) 方法。
删除消息队列中 Runnable r 的所有待处理帖子。
View#clearAnimation()
将取消已应用于 View
的所有动画。
在你的例子中,你使用的是 ValueAnimator
,这意味着你必须保留对它的引用,当你需要取消动画时,你应该执行 ValueAnimator#cancel()
:
private ValueAnimator circleAnimator;
...
circleAnimator = ValueAnimator.ofFloat(0f, 1f);
// setup and start `ValueAnimator`
然后,当需要取消动画时:
circleAnimator.cancel();
正如Writing Custom View for Android所说:
Remove any posted Runnable in onDetachedFromWindow
我有一个自定义视图,CircleCheckBox
。单击时将执行动画。
动画由View#postInvalidate()
实现。
那么有没有办法删除 onDetachedFromWindow()
中任何已发布的可运行对象?
编辑
让我告诉你 CircleCheckBox
是如何工作的。
第 1 步
在CircleCheckBox
构造函数中我设置了View#OnClickListener
:
this.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
toggle();
if (mListener != null) {
mListener.onCheckedChanged(isChecked());
}
}
});
第 2 步
在方法 toggle()
中它将调用:
@Override
public void setChecked(boolean checked) {
....
if (checked) {
startCheckedAnimation();
} else {
startUnCheckedAnimation();
}
}
第 3 步
假设 startCheckedAnimation()
。
private void startCheckedAnimation() {
// circle animation
ValueAnimator circleAnimator = ValueAnimator.ofFloat(0f, 1f);
circleAnimator.setInterpolator(new DecelerateInterpolator());
circleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
mArcPath.reset();
mArcPath.addArc(mRectF, -159, 360 * (1 - value));
postInvalidate();
}
});
circleAnimator.setDuration(mDuration / 4);
circleAnimator.start();
}
我使用 postInvalidate()
方法让视图调用 onDraw()
。
我想你可以使用 removeCallbacks(Runnable r) 方法。
删除消息队列中 Runnable r 的所有待处理帖子。
View#clearAnimation()
将取消已应用于 View
的所有动画。
在你的例子中,你使用的是 ValueAnimator
,这意味着你必须保留对它的引用,当你需要取消动画时,你应该执行 ValueAnimator#cancel()
:
private ValueAnimator circleAnimator;
...
circleAnimator = ValueAnimator.ofFloat(0f, 1f);
// setup and start `ValueAnimator`
然后,当需要取消动画时:
circleAnimator.cancel();