Android上的动画错误?

时间:2014-06-20 17:25:13

标签: android android-fragments android-animation

这很难解释,但我们走了!

好的,直到我获得放置动画的片段的过渡将是:

MainActivity(扩展活动) - > loginActivity(extendsActivity) - >现在我打电话给:

Intent homeIntent = new Intent(loginActivity.this, HomeActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("risposta",(Serializable)risposta);
homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // read below (StackOverFlow)
homeIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); // read below (StackOverFlow)
homeIntent.putExtras(bundle);
startActivity(homeIntent);

启动 HomeActivity ,扩展 FragmentActivity ,并在onCreateView()结束时添加我的片段 CircleFragment {{1}这是@Override

onResume()

或XML(同时尝试过):

    RotateAnimation rotateAnimation1 = new RotateAnimation(0, 360,
            Animation.RELATIVE_TO_SELF, 0.5f,
            Animation.RELATIVE_TO_SELF, 0.5f);
    rotateAnimation1.setInterpolator(new LinearInterpolator());
    rotateAnimation1.setDuration(4000);
    rotateAnimation1.setRepeatCount(Animation.INFINITE);
    radar.startAnimation(rotateAnimation1);

发生了什么?

SOMETIMES 它运行不好(有时很好!):它开始arround~(50%,25%)(或0.5,0.25),不完全(计算)但如果我让屏幕关闭然后我恢复它,一切都会再次起作用:O

为什么选择它?

  1. 你看到评论的两行清理任务并在顶部开始活动吗? 如果我没有设置,那一切都没问题
  2. 如果我将其作为MainActivity启动 - > HomeActivity和完成(而不是清除任务),它也很好。
  3. 发生了什么?

    提前致谢。

1 个答案:

答案 0 :(得分:2)

当你听到如下声明:“有时它很糟糕”时,不要低估这一点。它基本上意味着可能涉及时间组件。由于多线程操作的执行顺序不一定是已知的,因此可能在不同的CPU / GPU负载之前或之后和/或期间几毫秒内发生思考。与此同时,几毫秒之前可能意味着其他东西仍然没有完成,我们可能需要完成它或者它可能是“密集的”。

使用Android Activity / Fragment生命周期,可以保证“或多或少”以某种顺序发生。

如果您添加有时 + 或多或少,您就会得到 unknownness 的配方......

我没有尝试过你的特定场景,但我建议采取以下步骤:

  1. 除非您的布局已布局,否则请勿动画。你得等一等。
  2. 除非您的视图已创建,否则请勿设置动画。你简单不能:D
  3. 所以,即使“有时候工作正常”,我怀疑你有时是因为当视图没有完成时你太早制作动画。不要将已经混淆的onCreatedView方法名称与“是的,视图创建和布局”混淆。创建了!=已经完成了。

    那么什么时候该视图出来呢?

    当Android最终进行大量测量和绘图时。

    我们怎么知道?

    使用你今天看到的最丑陋的代码......

    示例(在您的片段中):

    private volatile boolean mRootLayoutComplete = false; //just a global flag to let the Fragment know when we've been through this.
    
    @Override
    public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
        final View rootView = inflater.inflate(R.layout.your_fragment_layout, container, false);
        // add a GlobalLayoutListener to hear back from the Layout engine.
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                // This beauty can be thanked to Android for changing the name of the method.
                // In any case, you must unsusbcribe to this immediately.
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    rootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                } else {
                    rootView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }
                // Mark this on a volatile global variable in case you want to use it elsewhere.
                mRootLayoutComplete = true;
    
                // Now you can ask: Is my view Created and not yet animated? 
                if ( mViewHasBeenCreated && !mRadarHasBeenAnimated ) {
                    animate(mRadar); // call a method that will do the animation
                }
            };
        } // some {} may be wrong, I did it in this text editor :D
    

    现在你需要标记mViewHasBeenCreated ......或者你可以检查mRadar != null而不是仅使用信号量。

    继续我的例子......

    // Define this flag too, because things are asynchronous we don't know who's gonna happen first!
    private volatile boolean mViewHasBeenCreated = false;
    

    在你的:

    @Override
    public void onViewCreated(final View view, final Bundle savedInstanceState) {
        mViewHasBeenCreated = true;
        super.onViewCreated(view, savedInstanceState);
    }
    

    在你的onResume:

    boolean mRadarHasBeenAnimated = false; //flag to avoid multiple animations.
    
    @Override
    public void onResume() {
        super.onResume();
        if ( mRootLayoutComplete && mViewHasBeenCreated && !mRadarHasBeenAnimated ) {
            animate(mRadar); // could also check for null here
        }   
    }
    

    动画:

    void animate(final View view) {
        if ( view == null ) {
           return;
        }
        // your animation code
        view.animate(youranimation);
        mRadarHasBeenAnimated = true;
    }
    

    最后,如果您想在每次执行onResume时为“雷达”制作动画,那么您必须重置此...

    @Override
    public void onPause() {
        super.onPause();
        mRadarHasBeenAnimated = false;
    }
    

    这应该可以解决问题。

    基本上,只有在满足某些条件后(尤其是mRootLayoutComplete),您才会设置动画视图,并且所有标志都是为了避免多次运行,尤其是在CREATION期间。由于你不知道哪个会先发生,你需要“等待”,只有在你确定可以的时候才能这样做。

    祝你好运!

    p.d。:我没有测试过上面的代码,但我在很多应用程序中都使用了这个技巧,而且它一直都有效。