在无效之间保持动画状态
Hold animation state between invalidate
我试图在无效后保存视图状态,但很不成功。
问题是我有一张图像,用户可以缩放(在右侧或左侧)。在他缩放之后,应用程序将在某些位置绘制点,在用户点击其中的一些位置后,我希望它发生变化(它是带有可选城市的地图)。
问题是点击该点后,我需要调用 invalidate() 再次调用 onDraw() - 以更改该点,但在使地图无效后,地图会恢复到其原始状态,因此它 "unzoomed"再次。你能告诉我,如何通过无效方法保留应用于视图的动画状态吗?
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (zoomed) {
Paint p //init Paint
for (Location l : locations) {
if (l.selected) {
canvas.drawCircle(l.calculatedPixels.X, l.calculatedPixels.Y, pxFromDp(getContext(), 10), p);
} else {
canvas.drawCircle(l.calculatedPixels.X, l.calculatedPixels.Y, pxFromDp(getContext(), 5), p);
p.setStyle(Paint.Style.STROKE);
canvas.drawCircle(l.calculatedPixels.X, l.calculatedPixels.Y, pxFromDp(getContext(), 10), p);
}
//NOTHING OF THIS WORKS CORRECTLY
if (scaleByTownTouch && getScaleX() != scaleTo) {
//canvas.restore();
setScaleX(scaleTo);
setScaleY(scaleTo);
setPivotX(pivotX);
setPivotY(pivotY);
/*ScaleAnimation scaleAnimation = new ScaleAnimation(scaleFrom, scaleTo, scaleFrom, scaleTo, pivotX, pivotY);
scaleAnimation.setDuration(0);
scaleAnimation.setFillAfter(true);
this.startAnimation(scaleAnimation);*/
scaleByTownTouch = false;
}
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (zoomed) {
for (Location l : locations) {
if (l.calculatedPixels.isTouchNearPoint(event.getX(), event.getY(), 50, scaleTo)) {
l.selected = !l.selected;
scaleByTownTouch = true;
//THIS UNZOOMS WHOLE VIEW
invalidate();
return true;
}
}
zoom(new Point());
} else {
float xTouch = event.getX();
float yTouch = event.getY();
Point touch = new Point();
touch.X = xTouch / measuredX * 100;
touch.Y = 100 - (yTouch / measuredY * 100);
zoom(touch);
}
}
return false;
}
public void zoom(Point touch) {
if (!scaleByTownTouch) {
if (!zoomed) {
if (!touch.isBelowLine()) {
pivotX = measuredX;
pivotY = measuredY;
scaleTo = 1.7f;
} else {
pivotX = 0;
pivotY = 0;
scaleTo = 1.5f;
}
scaleFrom = 1;
} else {
scaleFrom = scaleTo;
scaleTo = 1;
}
final MapImageView miv = this;
ScaleAnimation scaleAnimation = new ScaleAnimation(scaleFrom, scaleTo, scaleFrom, scaleTo, pivotX, pivotY);
scaleAnimation.setDuration(1000);
scaleAnimation.setFillAfter(true);
scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
zoomed = !zoomed;
miv.invalidate();
}
});
this.startAnimation(scaleAnimation);
}
}
您应该尝试使用 Animator 而不是 Animation。动画仅更改渲染,而 Animator 更改对象的 属性,该对象将在失效后保留。
看看 ValueAnimator 或 ObjectAnimator。
我试图在无效后保存视图状态,但很不成功。
问题是我有一张图像,用户可以缩放(在右侧或左侧)。在他缩放之后,应用程序将在某些位置绘制点,在用户点击其中的一些位置后,我希望它发生变化(它是带有可选城市的地图)。
问题是点击该点后,我需要调用 invalidate() 再次调用 onDraw() - 以更改该点,但在使地图无效后,地图会恢复到其原始状态,因此它 "unzoomed"再次。你能告诉我,如何通过无效方法保留应用于视图的动画状态吗?
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (zoomed) {
Paint p //init Paint
for (Location l : locations) {
if (l.selected) {
canvas.drawCircle(l.calculatedPixels.X, l.calculatedPixels.Y, pxFromDp(getContext(), 10), p);
} else {
canvas.drawCircle(l.calculatedPixels.X, l.calculatedPixels.Y, pxFromDp(getContext(), 5), p);
p.setStyle(Paint.Style.STROKE);
canvas.drawCircle(l.calculatedPixels.X, l.calculatedPixels.Y, pxFromDp(getContext(), 10), p);
}
//NOTHING OF THIS WORKS CORRECTLY
if (scaleByTownTouch && getScaleX() != scaleTo) {
//canvas.restore();
setScaleX(scaleTo);
setScaleY(scaleTo);
setPivotX(pivotX);
setPivotY(pivotY);
/*ScaleAnimation scaleAnimation = new ScaleAnimation(scaleFrom, scaleTo, scaleFrom, scaleTo, pivotX, pivotY);
scaleAnimation.setDuration(0);
scaleAnimation.setFillAfter(true);
this.startAnimation(scaleAnimation);*/
scaleByTownTouch = false;
}
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (zoomed) {
for (Location l : locations) {
if (l.calculatedPixels.isTouchNearPoint(event.getX(), event.getY(), 50, scaleTo)) {
l.selected = !l.selected;
scaleByTownTouch = true;
//THIS UNZOOMS WHOLE VIEW
invalidate();
return true;
}
}
zoom(new Point());
} else {
float xTouch = event.getX();
float yTouch = event.getY();
Point touch = new Point();
touch.X = xTouch / measuredX * 100;
touch.Y = 100 - (yTouch / measuredY * 100);
zoom(touch);
}
}
return false;
}
public void zoom(Point touch) {
if (!scaleByTownTouch) {
if (!zoomed) {
if (!touch.isBelowLine()) {
pivotX = measuredX;
pivotY = measuredY;
scaleTo = 1.7f;
} else {
pivotX = 0;
pivotY = 0;
scaleTo = 1.5f;
}
scaleFrom = 1;
} else {
scaleFrom = scaleTo;
scaleTo = 1;
}
final MapImageView miv = this;
ScaleAnimation scaleAnimation = new ScaleAnimation(scaleFrom, scaleTo, scaleFrom, scaleTo, pivotX, pivotY);
scaleAnimation.setDuration(1000);
scaleAnimation.setFillAfter(true);
scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
zoomed = !zoomed;
miv.invalidate();
}
});
this.startAnimation(scaleAnimation);
}
}
您应该尝试使用 Animator 而不是 Animation。动画仅更改渲染,而 Animator 更改对象的 属性,该对象将在失效后保留。
看看 ValueAnimator 或 ObjectAnimator。