6

在视图上调用onGlobalLayoutFinished之后,我正在动画活动中的视图。我的动画在开始时跳过〜300 ms的帧。如果我将动画延迟超过300毫秒,它不会跳过任何帧。导致这种情况发生的活动发生了什么?我该如何阻止它,或者如何在完成时收听?活动开始时的动画跳过帧

我创建了一个死的简单的应用程序来演示此行为。在AndroidManifest.xml的<application>

内容:

<activity 
    android:name=".main.TestLagActivity" 
    android:label="Test Lag Activity"> 
    <intent-filter> 
    <action android:name="android.intent.action.MAIN" /> 
    <category android:name="android.intent.category.LAUNCHER" /> 
    </intent-filter> 
</activity> 

TestLagActivity.java:

public class TestLagActivity extends ActionBarActivity { 
    private View mRedSquareView; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_test_lag); 

    mRedSquareView = findViewById(R.id.activity_test_lag_redSquareView); 

    if (mRedSquareView.getViewTreeObserver() != null) { 
     mRedSquareView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
     public void onGlobalLayout() { 
      mRedSquareView.getViewTreeObserver().removeOnGlobalLayoutListener(this); 
      animate(); 
     } 
     }); 
    } 
    } 

    private void animate() { 
    ObjectAnimator xAnimator = ObjectAnimator.ofFloat(mRedSquareView, "x", 0, 1000); 
    xAnimator.setDuration(1000); 
    xAnimator.start(); 
    } 
} 

activity_test_lag.xml:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"> 

    <View 
     android:id="@+id/activity_test_lag_redSquareView" 
     android:layout_width="50dp" 
     android:layout_height="50dp" 
     android:background="#FF0000"/> 

</FrameLayout> 

在这个演示中,一个红色方块在1000毫秒内从左到右移动1000个像素。如果未设置延迟,则会跳过大约前300个像素。如果设置了延迟,它会顺利进行动画。请参阅下面的视频。

无延迟(跳帧): https://www.youtube.com/watch?v=dEwvllhvvN0

400ms的延迟(不跳过的FAME): https://www.youtube.com/watch?v=zW0akPhl_9I&feature=youtu.be

任何意见都欢迎。

+1

您确实需要显示onPause和onSaveInstanceState方法以及潜在的视图层次结构。您可能在onSaveInstanceState之前在onPause中拥有自定义逻辑阻塞,或者您可能拥有一个在onSaveInstanceState中阻止的自定义视图。 – dcow 2015-02-10 23:23:09

+0

“在MainActivity中,onPause和onSaveInstanceState通常在彼此的20ms内发生”...你在做什么不同的CreatActivity? – 2015-02-10 23:25:32

+0

@dcow我应该提到的方法是空的,除了日志语句。 – clocksmith 2015-02-11 00:09:51

回答

2

发生这种情况的原因是活动的过渡动画,这是在创建活动时播放的。因此,您的自定义动画在系统忙于绘制转场时启动。

我还没找到干净的解决方案。现在,我只是等待过渡期间开始我的动画之前,但它远不是完美的:

// The duration of the animation was found here: 
// http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.5_r1/frameworks/base/core/res/res/anim/activity_open_enter.xml 
new Handler().postDelayed(runnable, android.R.integer.config_shortAnimTime); 

您还可以禁用活动转变,而不是与:

overridePendingTransition(0, 0); 

我仍在寻找一种方式来倾听转换的确切结束时间。如果我找到解决方案,将会保持公布。