我有MainActivity
(有launchMode = singleTop),我可以从中进行其他活动,例如B
和C
。现在,我想在MainActivity
和B
点击一些按钮后返回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"/>
答案 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
属性。使用此属性,请理解我的概念图:
由于ActivityC
和ActivityD
(也称为上次活动)具有真实值,因此他们无法返回MainActivity
,但他们可以返回ActivityA
并且ActivityB
首先。此外,ActivityA
和ActivityB
可以返回MainActivity
。因此,不会创建新实例。
在清单中声明值后,您只需调用以下代码即可打开下一个Activity
(不需要FLAG
):
如果您想从A
或C
(在这种情况下是您的活动,而不是概念图上的活动)转到D
,请致电:
startActivity(new Intent(C.this, A.class));
再次查看概念图,ActivityA
与ActivityC
相关联,ActivityB
与ActivityD
相关联。由于这些活动看起来像链,因此您无法调用finish()
或按后退键直接转到MainActivity
。所以,调用上面的代码。
如果您想从ActivityA
(在这种情况下是您的活动,而不是概念图上的活动)转到ActivityB
,您可以致电finish()
。默认情况下,按下返回键时,Android会在不调用finish()
的情况下返回上一个活动。
通常,在使用android:launchMode
属性时,我不需要android:noHistory="boolean"
属性。
<强>记住:强>
Activity
的最后android:noHistory="true"
。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
>