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

前端之家收集整理的这篇文章主要介绍了如何在Android上实现平滑的片段交易动画前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我主要使用iOS,已经习惯了非常流畅和流畅的屏幕更改动画.我现在正在开发一个 Android应用程序,并且不能在我的生活中获得一个片段事务来顺利添加/替换片段.

我的设置如下:MainActivity的xml有一个FrameLayout,我立即将FragmentA加载到MainActivity的OnCreate上.我的应用程序然后继续使用FragmentB,FragmentC等替换MainActivity的FrameLayout.所以我的整个应用程序有1个活动.

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

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

slide_in.xml看起来像(slide_out.xml显然是相反的):

<?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>

滑入和滑出我动画xFraction,我已经将LinearLayout子类化为这样做:

public class SlidingLinearLayout extends LinearLayout {

    private float yFraction = 0;
    private float xFraction = 0;

    public SlidingLinearLayout(Context context) {
        super(context);
    }

    public SlidingLinearLayout(Context context,AttributeSet attrs) {
        super(context,attrs);
    }

    public SlidingLinearLayout(Context context,AttributeSet attrs,int defStyle) {
        super(context,attrs,defStyle);
    }

    private ViewTreeObserver.OnPreDrawListener preDrawListener = null;

    public void setYFraction(float fraction) {

        this.yFraction = fraction;

        if (getHeight() == 0) {
            if (preDrawListener == null) {
                preDrawListener = new ViewTreeObserver.OnPreDrawListener() {
                    @Override
                    public boolean onPreDraw() {
                        getViewTreeObserver().removeOnPreDrawListener(preDrawListener);
                        setYFraction(yFraction);
                        return true;
                    }
                };
                getViewTreeObserver().addOnPreDrawListener(preDrawListener);
            }
            return;
        }

        float translationY = getHeight() * fraction;
        setTranslationY(translationY);
    }

    public float getYFraction() {
        return this.yFraction;
    }

    public void setXFraction(float fraction) {

        this.xFraction = fraction;

        if (getWidth() == 0) {
            if (preDrawListener == null) {
                preDrawListener = new ViewTreeObserver.OnPreDrawListener() {
                    @Override
                    public boolean onPreDraw() {
                        getViewTreeObserver().removeOnPreDrawListener(preDrawListener);
                        setXFraction(xFraction);
                        return true;
                    }
                };
                getViewTreeObserver().addOnPreDrawListener(preDrawListener);
            }
            return;
        }

        float translationX = getWidth() * fraction;
        setTranslationX(translationX);
    }

    public float getxFraction() {
        return xFraction;
    }
}

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

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

解决方法

根据我的经验,如果片段在加载时做了太多工作,那么系统将基本上跳过输入动画并只显示片段.在我的例子中,解决方案是在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;
}

猜你在找的Android相关文章