活动导航:如何使用popEnter和popExit自定义动画,就像片段一样。

6
使用以下代码可以通过动画更改活动:
```java overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left); ```
这将导致新活动从右侧滑入并覆盖旧活动。
Bundle animation = ActivityOptions.makeCustomAnimation(App.getContext(), R.anim.enter_from_right, R.anim.exit_to_left).toBundle();
startActivity(intent, animation);

对于片段,您可以在FragmentTransaction上执行类似的操作:

// ...
transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left);
// ...

这可以实现!但是我想在按下后退按钮时(从后堆栈中弹出)加入动画。对于片段,只需添加2个动画资源(popEnter和popExit):
transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);

如何为活动创建相同的“后退动画”?

1
我使用了这段代码:overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); 您可以在GmailAnimationLopeAnimations中看到这些示例。此外,您还可以在这个博客中了解更多信息。 - Cabezas
我用同样的例子回答了自己的问题,但稍微扩展了一下;-) - P Kuijpers
1个回答

32

我发现了一种不同但简单的方法,似乎效果很好。活动的动画也可以使用overridePendingTransition来执行,因此当活动完成时,您将只需要使用该方法。

最有效的方法是在BaseActivity中实现这些覆盖,该类被所有项目中的活动扩展。现在,您的所有活动都会自动包含退出动画和启动新活动时的动画:

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);
    }
}

总的来说,我将包括4个动画资源:
进入从右边 enter_from_right
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromXDelta="100%p"
    android:toXDelta="0%p"/>

离开向左
<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"/>

退出至右侧。
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromXDelta="0%p"
    android:toXDelta="100%p"/>

提示:在您的起始/主要活动中,您可能希望排除退出动画;-)

public class MainMenuActivity extends BaseActivity {
    ....
    @Override
    protected void onLeaveThisActivity() {
        // Don't use an exit animation when leaving the main activity!
    }
}

2019年10月24日更新:

在从一个活动导航到另一个活动并完成当前活动的过程中,请注意在导航实现之前调用finish()。如果按照错误顺序进行操作,onLeaveThisActivity将在onStartNewActivity之后被调用,导致错误的动画效果。


1
不错的方法。我会更新答案,同时覆盖startActivityForResult方法。 - ikarhun
很好的建议ikarhun,我会尝试并尽快更新我的代码! - P Kuijpers
不错的解决方案。唯一的问题是,在我的三星S6设备上,这种过渡效果需要的时间大约是没有此功能的设备的两倍。我创建了一个帖子:https://stackoverflow.com/questions/45735395/activity-navigation-translation-animation-not-working-correctly-on-samsung-s6 - Rik van Velzen
@ikarhun 当我调试活动转换时,我发现当调用startActivityForResult时,很快就会调用startActivity,因此可能不需要覆盖重写。但是,我不确定这是否总是如此,并且多次覆盖重写也不会有害。 - P Kuijpers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接