【问题标题】:Android view rotation not happening after a few setAnimation calls几次 setAnimation 调用后没有发生 Android 视图旋转
【发布时间】: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())

标签: android multithreading animation views


【解决方案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() 是一个更短的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 2012-07-15
    相关资源
    最近更新 更多