使用FLAG_ACTIVITY_CLEAR_TOP时是否无法进行过渡动画?

时间:2015-01-27 17:16:33

标签: android android-intent android-animation

我有MainActivity(有launchMode = singleTop),我可以从中进行其他活动,例如BC。现在,我想在MainActivityB点击一些按钮后返回C。而且我也想要过渡动画。

这是代码

CODE 1

Intent intent=new Intent(this,MainActivity.class);
        Bundle animation= ActivityOptions.makeCustomAnimation(getApplicationContext(), R.animator.translate_left_to_right, R.animator.translate_source_left_to_right).toBundle();
        startActivity(intent,animation);
        finish();

上面的代码工作正常,除了在旧版本之上创建MainActivity的新实例这一事实!我不希望这种情况发生。所以,经过一番研究后我尝试了下面的代码


代码2

Intent intent=new Intent(this,ListingActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        Bundle animation= ActivityOptions.makeCustomAnimation(getApplicationContext(), R.animator.translate_left_to_right, R.animator.translate_source_left_to_right).toBundle();
        startActivity(intent,animation);
        finish();

此代码似乎消除了创建活动的新实例的问题,因为标记FLAG_ACTIVITY_CLEAR_TOP负责处理它。但是,现在转换动画似乎不起作用了! 标志FLAG_ACTIVITY_CLEAR_TOP不允许任何动画吗?我的问题有什么解决方案?我既需要动画转换,也需要创建MainActivity的新实例。


修改
这似乎是 David Wasser 所建议的伎俩。

 Intent intent=new Intent(this,ListingActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        finish();
        overridePendingTransition(R.animator.translate_left_to_right,R.animator.translate_source_left_to_right);

但动画不流畅。动画中有一个小故障。我认为那是因为在动画完成之前活动(B或C)被破坏了。我不确定

发布动画文件

translate_left_to_right.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="-100%p"
    android:toXDelta="0%p"
    android:duration="400"/>


translate_right_to_left.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="100%p"
    android:toXDelta="0"
    android:duration="400"/>


 的 translate_source_left_to_right.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0%p"
    android:toXDelta="50%p"
    android:duration="400"/>


 的 translate_source_right_to_left.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:toXDelta="-50%p"
    android:duration="400"/>

4 个答案:

答案 0 :(得分:4)

我玩这个很多。我终于能够重现你的问题了。我错过了launchMode="singleTop"的{​​{1}},这就是为什么我之前没有看到这种行为的原因。对不起。

如果我在清单中将MainActivity添加到launchMode="singleTop",那么我可以使用代码2重现该行为。

使用我建议的代码,我能够解决问题:

MainActivity

但是,我还需要将动画资源文件 Intent intent=new Intent(this,ListingActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); overridePendingTransition(R.animator.translate_left_to_right, R.animator.translate_source_left_to_right); 更改为:

translate_source_left_to_right.xml

这是导致&#34;故障的原因。在动画中。您将传入的活动从-100%设置为0%,并将传出活动在同一时间段内从0%设置为50%。因此,传出活动移动屏幕宽度的一半然后停止。我更改了传出动画,使其动画从0%到100%,现在你看到两个视图都在整个宽度上动画(我认为这就是你想要的)。

感谢您的挑战: - )

答案 1 :(得分:1)

如果不使用Intent.FLAG_ACTIVITY_*或其他FLAG,有更好的解决方案。您可以尝试在android:noHistory="boolean"中添加AndroidManifest.xml属性。使用此属性,请理解我的概念图:

enter image description here

说明中,

由于ActivityCActivityD(也称为上次活动)具有真实值,因此他们无法返回MainActivity,但他们可以返回ActivityA并且ActivityB首先。此外,ActivityAActivityB可以返回MainActivity。因此,不会创建新实例。

在清单中声明值后,您只需调用以下代码即可打开下一个Activity(不需要FLAG):

如果您想从AC(在这种情况下是您的活动,而不是概念图上的活动)转到D,请致电:

startActivity(new Intent(C.this, A.class));

再次查看概念图,ActivityAActivityC相关联,ActivityBActivityD相关联。由于这些活动看起来像链,因此您无法调用finish()或按后退键直接转到MainActivity。所以,调用上面的代码。

如果您想从ActivityA(在这种情况下是您的活动,而不是概念图上的活动)转到ActivityB,您可以致电finish()。默认情况下,按下返回键时,Android会在不调用finish()的情况下返回上一个活动。

通常,在使用android:launchMode属性时,我不需要android:noHistory="boolean"属性。

<强>记住:

  • 在清单中设置Activity的最后android:noHistory="true"
  • 必须使用false值设置另一个Activity
  • 为您的所有活动应用此属性。

另外,以下是如何在清单中使用它:

<activity android:name=".MyActivity" android:noHistory="true" />

添加动画

覆盖onResume()中的ActivityA方法(在这种情况下是您的活动,而不是概念图上的活动)并在此处制作动画:

@Override
public void onResume(){
    super.onResume();
    overridePendingTransition(R.anim.enterAnim, R.anim.exitAnim);
}

如果不使用onResume()方法,请尝试使用onStart()方法覆盖动画:

@Override
public void onStart(){
    super.onStart();
    overridePendingTransition(R.anim.enterAnim, R.anim.exitAnim);
}

答案 2 :(得分:0)

我和你有完全相同的问题 但是,使用@David Wasser的解决方案会在转换过程中牺牲视差效果。 可能是一些开发人员也不希望这样的行为。

然后我通过检查您的MainActivity是否存在于Backstack中来找到另一种解决方案。请在下面查看我的答案:

how to check if activity is still in the stack?

请注意,我的解决方案将使用系统的默认动画(与finish()相同)禁用动画。但由于你真的关闭了当前的活动,我认为这更自然。

答案 3 :(得分:0)

之所以会发生这种情况,是因为过渡没有对象来开始过渡和结束过渡。当我们使用透明堆栈时,所有活动都会被清除,过渡将一无所有,因此请通过在我的样式代码中实现以下行来完成此操作

但是请谨慎使用

<item name="android:windowDisablePreview">true</item>