几次 setAnimation 调用后没有发生 Android 视图旋转

Posted

技术标签:

【中文标题】几次 setAnimation 调用后没有发生 Android 视图旋转【英文标题】:Android view rotation not happening after a few setAnimation calls 【发布时间】:2013-10-31 16:04:35 【问题描述】:

我一直在尝试编写将图像旋转到特定角度的活动方法。 旋转有效,但问题是该方法每秒左右调用一次,但仅在前几次旋转。 在某个时刻,动画图像只是静止不动,即使动画正在设置并以不同的值开始!它假设移动图像,就像前几次一样。

private void animateNeedle(final float sfAngle)

    final View viewNeedle = findViewById(R.id.needle);
    final RotateAnimation needleAnimation;

    RotateAnimation anim;

    anim = new RotateAnimation( 0,
        sfAngle,
        m_nNeedleWidth / 2,
        m_nNeedleHeight);
    anim.setDuration(200);
    anim.setFillAfter(true);
    viewNeedle.setAnimation(anim);
    anim.setAnimationListener(new AnimationListener()
    

        @Override
        public void onAnimationEnd(final Animation animation)
        
            viewNeedle.clearAnimation();
        

        @Override
        public void onAnimationRepeat(final Animation animation)
        
            // TODO Auto-generated method stub
        

        @Override
        public void onAnimationStart(final Animation animation)
        
            // TODO Auto-generated method stub
        
    );

    anim.start();
    findViewById(android.R.id.content).postInvalidate();

我做错了什么? 我确保该函数在动画期间不会被调用两次,但它没有帮助。

【问题讨论】:

你从哪里调用函数? 从一个事件中,确切地说是接收到的音频样本,但这种情况每秒只发生一次,以检查它是否是与线程相关的问题。 您确定传递的sfAngle 始终非零吗? 你是从 UI 线程开始动画的吗? 您是否尝试在方法签名中添加同步关键字以确保它不是多线程问题? (view needle 设置新的动画对象,而另一个线程调用 .clearAnimation()) 【参考方案1】:

问题是它没有在主线程上运行,我们使用了修复它:

anim = new RotateAnimation( m_lastAngle,
                                sfAngle,
                                viewNeedle.getWidth() / 2,
                                viewNeedle.getHeight());
    anim.setDuration(1000);
    anim.setFillAfter(true);
    viewNeedle.setAnimation(anim);
    anim.setAnimationListener(new AnimationListener()
    
        @Override
        public void onAnimationEnd(final Animation animation)
        
            // viewNeedle.clearAnimation();
        

        @Override
        public void onAnimationRepeat(final Animation animation)
        
            // TODO Auto-generated method stub

        

        @Override
        public void onAnimationStart(final Animation animation)
        
            m_lastAngle = sfAngle;
        
    );

    runOnUiThread(new Runnable()
    

        @Override
        public void run()
        
            viewNeedle.startAnimation(anim);
            findViewById(android.R.id.content).invalidate();
        
    );

我们也用过:

    final View viewNeedle = findViewById(R.id.needle);
    viewNeedle.getViewTreeObserver().addOnGlobalLayoutListener(
            new OnGlobalLayoutListener()
            
                @Override
                public void onGlobalLayout()
                
                    scaleView(viewNeedle);
                

                /**
                 * Scale a view.
                 * 
                 * @param viewToScale - View to scale.
                 */
                private void scaleView(final View viewToScale)
                
                    int height = (int) (viewToScale.getHeight() / GraphicsPoint
                            .getScalePoint().y);
                    int width = (int) (viewToScale.getWidth() / GraphicsPoint
                            .getScalePoint().x);
                    final LayoutParams layoutParams = viewToScale
                            .getLayoutParams();
                    layoutParams.height = height;
                    layoutParams.width = width;
                    viewToScale.setLayoutParams(layoutParams);
                    viewToScale.getViewTreeObserver()
                            .removeOnGlobalLayoutListener(this);
                
            );

【讨论】:

【参考方案2】:

我尝试使用您的代码,它可以在以后多次调用动画.. 我添加此代码以在轮换结束时调用:

..
                viewNeedle.startAnimation(anim);
                anim.start();
..

所以要制作一个重复的动画,就像这样:

 @Override
            public void onAnimationEnd(final Animation animation)
            
                viewNeedle.clearAnimation();
                viewNeedle.startAnimation(anim);
                anim.start();
            

所以我可以多次调用该动画..

希望对你有所帮助..

【讨论】:

谢谢,但这不是问题,解决方案是在主线程上运行动画,我现在将发布解决方案。 谢谢伙计,这行得通!这应该是公认的答案。我知道问题在于 UI 线程,但在 Animation 对象上调用 start() 是一个更短的解决方案。

以上是关于几次 setAnimation 调用后没有发生 Android 视图旋转的主要内容,如果未能解决你的问题,请参考以下文章

带有Kerberos的PyHive在几次调用后引发身份验证错误

如果我在使用新程序和结束程序分配数据后没有调用删除运算符会发生啥?

输入网址后发生了什么&没有listen(accept)能建立连接吗&SYN洪水

输入网址后发生了什么&没有listen(accept)能建立连接吗&SYN洪水

android fragment对同一id replace几次后,就偶尔显示空白,随机发生

Swift:SKStoreReviewController - 多久可以调用一次?