问题
Changing activities with an animation is possible using the code below:
Bundle animation = ActivityOptions.makeCustomAnimation(App.getContext(), R.anim.enter_from_right, R.anim.exit_to_left).toBundle();
startActivity(intent, animation);
For fragments you can do something similar on FragmentTransaction:
// ...
transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left);
// ...
This works! But I'd like to have an animation when pressing back (pop from backstack). For fragments you simply add 2 anim resources (popEnter & popExit):
transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
How can I create the same 'back-animation' for activities?
回答1:
I've found a different though simple approach that seems to work quite well. Animations for activities can also be performed using overridePendingTransition, so when the activity finishes you'll simply use that method.
It would be most effective to implement these overrides in a BaseActivity, which is extended by all activities in your project. Now all your activities will automatically include an exit animation and an animation when starting new activities:
public abstract class BaseActivity extends AppCompatActivity {
@Override
public void finish() {
super.finish();
onLeaveThisActivity();
}
protected void onLeaveThisActivity() {
overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right);
}
// It's cleaner to animate the start of new activities the same way.
// Override startActivity(), and call *overridePendingTransition*
// right after the super, so every single activity transaction will be animated:
@Override
public void startActivity(Intent intent) {
super.startActivity(intent);
onStartNewActivity();
}
@Override
public void startActivity(Intent intent, Bundle options) {
super.startActivity(intent, options);
onStartNewActivity();
}
@Override
public void startActivityForResult(Intent intent, int requestCode) {
super.startActivityForResult(intent, requestCode);
onStartNewActivity();
}
@Override
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
super.startActivityForResult(intent, requestCode, options);
onStartNewActivity();
}
protected void onStartNewActivity() {
overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
}
}
To round things up, I'll include the 4 anim resources:
enter_from_right
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXDelta="100%p"
android:toXDelta="0%p"/>
exit_to_left
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXDelta="0%p"
android:toXDelta="-100%p"/>
enter_from_left
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXDelta="-100%p"
android:toXDelta="0%p"/>
exit_to_right
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXDelta="0%p"
android:toXDelta="100%p"/>
ps. You'd probably like to exclude the exit-animation in your starting / main activity ;-)
public class MainMenuActivity extends BaseActivity {
....
@Override
protected void onLeaveThisActivity() {
// Don't use an exit animation when leaving the main activity!
}
}
EDIT Oct 24 2019:
When navigating from one activity to the next, AND finishing the current activity in the process, take note that finish()
should be called BEFORE the navigation implementation. If this is done in the wrong order, onLeaveThisActivity
will be called AFTER onStartNewActivity
, resulting in the wrong animation.
来源:https://stackoverflow.com/questions/39711666/activity-navigation-custom-animation-with-popenter-and-popexit-like-fragments