【问题标题】:onEnterAnimationComplete() is not called after an Activity Transaction活动事务后不调用 onEnterAnimationComplete()
【发布时间】:2015-10-31 00:22:47
【问题描述】:

我有两个带有一个共享对象的活动,一个ImageView。这两个活动都是AppCompatActivity 的子类,它们共享相同的主题:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:windowActionBar">false</item>
    <item name="android:windowContentTransitions">true</item>
    <item name="android:windowTranslucentStatus">false</item>
    <item name="android:windowExitTransition">@transition/transition_slide</item>
    <item name="android:windowEnterTransition">@transition/transition_slide</item>
    <!-- specify shared element transitions -->
    <item name="android:windowSharedElementEnterTransition">
        @transition/obj_transition</item>
    <item name="android:windowSharedElementExitTransition">
        @transition/obj_transition</item>
</style>

Activity A 调用 Activity B 的方式如下:

Intent intent = new Intent(ActivityA.this, ActivityB.class);
ActivityOptionsCompat options = ActivityOptionsCompat
    .makeSceneTransitionAnimation(ActivityA.this, view, "common_tag");
ActivityCompat
    .startActivityForResult(ActivityA.this, intent, ACT_B_TAG, options.toBundle());

在 Activity B 上,我想在同一个共享 ImageView 上开始一个简单的摆动动画。如果我在onCreate 方法上启动动画,结果会非常难看,因为它在活动转换结束之前开始。所以我覆盖了Activity B中的onEnterAnimationComplete()方法:

@Override
public void onEnterAnimationComplete() {
    Log.d(TAG, "ANIMATION COMPLETE");
    Animation anim = AnimationUtils.loadAnimation(this, R.anim.wobble);
    findViewById(R.id.SharedView).startAnimation(anim);
}

问题是,什么都没有发生。活动和共享元素转换播放,但当它们结束时,其他动画不会开始。检查 logcat 输出我发现该方法甚至没有被调用。有什么想法吗?

【问题讨论】:

    标签: android android-activity android-transitions


    【解决方案1】:

    有一个解决方法。您可以推迟 Activity 进入过渡,为您的图像添加一个 preDraw 侦听器(或其他任何内容,由您决定),设置您的动画,然后启动推迟的进入过渡。

    postponeEnterTransition();  //  wait until all animations are set up
    imageView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    imageView.getViewTreeObserver().removeOnPreDrawListener(this);  //  only run once
                    enterAnimation();  //  your animations here
                    startPostponedEnterTransition();  //  all animations are ran
    
                    return true;
                }
            });
    

    我不知道 onEnterAnimationComplete() 没有被调用是否是预期行为,但如果是这样,那么这是框架团队的一个重大疏忽。

    【讨论】:

    【解决方案2】:

    我已经测试了代码,它运行良好。

    向 MainActivity 添加一个按钮以导航到 ActivityB。

    public class MainActivity extends AppCompatActivity {
    
    private Button button;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), ActivityB.class);
                startActivity(intent);
            }
        });
    }
    

    重写 ActivityB 的动画以正确理解

    public class ActivityB extends AppCompatActivity {
    
    private TextView textView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        overridePendingTransition(R.anim.slide_in_up, R.anim.still);
        setContentView(R.layout.activity_b);
    
        textView = (TextView) findViewById(R.id.textView);
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        overridePendingTransition(R.anim.still, R.anim.slide_out_down);
    }
    
    @Override
    public void onBackPressed() {
        super.onBackPressed();
        overridePendingTransition(R.anim.still, R.anim.slide_out_down);
    }
    
    @Override
    public void onEnterAnimationComplete() {
        super.onEnterAnimationComplete();
        Toast.makeText(this, "Animation Completed", Toast.LENGTH_SHORT).show();
        Animation anim = AnimationUtils.loadAnimation(this, R.anim.rotate_clockwise);
        textView.startAnimation(anim);
    }
    

    slide_in_up.xml

    <translate
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:fromYDelta="100%"
        android:toYDelta="0"
        android:interpolator="@android:anim/linear_interpolator"
        android:duration="3000" />
    

    slide_out_down.xml

    <translate
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:fromYDelta="0"
        android:toYDelta="100%"
        android:interpolator="@android:anim/linear_interpolator"
        android:duration="3000" />
    

    still.xml

    <translate
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:fromYDelta="0%"
        android:toYDelta="0%"
        android:duration="3000" />
    

    rotate_顺时针.xml

    <rotate
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:fromDegrees="0"
        android:toDegrees="180"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="3000"/>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多