如何在Android上实现平滑的片段交易动画

时间:2015-05-22 20:26:14

标签: android performance android-fragments fragmenttransaction

我主要使用iOS,已经习惯了非常流畅和流畅的屏幕更改动画。我现在正在开发一个Android应用程序,并且在我的生活中无法获得片段事务以平滑地添加/替换片段。

我的设置如下:MainActivity有一个FrameLayout的xml,我立即将FragmentA加载到MainActivity {{1} }}。我的应用随后将OnCreate MainActivity替换为FrameLayoutFragmentB等。所以我的整个应用程序都有1个活动。

按下按钮,我调用以下内容添加/替换当前片段:

FragmentC

slide_in.xml看起来像(slide_out.xml显然正好相反):

        getFragmentManager()
            .beginTransaction()
            .setCustomAnimations(R.animator.slide_in, android.R.animator.fade_out, android.R.animator.fade_in, R.animator.slide_out)
            .addToBackStack(null)
            .add(R.id.fragment_1, fragment)
            .commit();

滑入和滑出我为xFraction制作动画,我已经将 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:interpolator="@android:interpolator/linear" android:propertyName="xFraction" android:valueType="floatType" android:valueFrom="1.0" android:valueTo="0" android:duration="@android:integer/config_shortAnimTime" /> </set> 做了类似的动作:

LinearLayout

所以我的问题大部分时间是我最初点击一个按钮来添加/替换一个片段,我不会得到一个动画片,它只是弹出一个位置。但是,当我按下后退按钮并且从后台堆栈中弹出片段时,动画会按预期执行。我觉得在尝试动画时初始化是一个问题。当片段在内存中并在屏幕上制作动画时,它比创建新片段然后动画到屏幕上要好得多。我很好奇其他人是否经历过这种情况,如果有的话,他们是如何解决的。

这是一个困扰我的Android开发体验的烦恼,我真的很想休息!任何帮助将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:4)

根据我的经验,如果片段在加载时做了太多工作,那么系统将基本上跳过输入动画并只显示片段。在我的例子中,解决方案是在onCreateAnimation中创建一个动画侦听器,等待输入动画完成,然后再执行导致动画被跳过的过程密集型工作。

@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
    if (nextAnim == 0) {
        return super.onCreateAnimation(transit, enter, nextAnim);
    }

    Animation anim = android.view.animation.AnimationUtils.loadAnimation(getContext(), nextAnim);
    anim.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {}
        @Override
        public void onAnimationEnd(Animation animation) {
            // Do any process intensive work that can wait until after fragment has loaded
        }

        @Override
        public void onAnimationRepeat(Animation animation) {}
    });
    return anim;
}