在无效之间保持动画状态

Posted

技术标签:

【中文标题】在无效之间保持动画状态【英文标题】:Hold animation state between invalidate 【发布时间】:2015-12-04 08:57:51 【问题描述】:

我试图在无效后保存视图状态,但我非常不成功。

问题是我有一个图像,用户可以缩放(在右侧或左侧)。在他缩放它之后,应用程序将在某些位置上绘制点,并且在用户单击其中一些之后,我希望它改变(它是带有可选城市的地图)。

问题是,在单击该点后,我需要调用 invalidate() 以再次调用 onDraw() - 以更改该点,但在使地图失效后,它会恢复到其原始状态,因此它再次“未缩放”。能否请您告诉我,如何通过 invalidate 方法保留应用于视图的动画状态?

@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);
    

【问题讨论】:

【参考方案1】:

您应该尝试使用 Animator 而不是 Animation。动画仅更改渲染,而 Animator 更改将在无效后保留的对象的属性。

看看 ValueAnimator 或 ObjectAnimator。

【讨论】:

以上是关于在无效之间保持动画状态的主要内容,如果未能解决你的问题,请参考以下文章

在 CSS3 动画结束时保持最终状态

React-native:将动画值保持在状态或作为类属性?

Android 动画 - 按钮保持可点击状态

如果输入是垃圾邮件,Unity动画属性将保持禁用状态

css3动画如何在动作结束时保持该状态不变

使用jQuery动画远离光标时,停止“:悬停”元素保持其状态?