Skip to content

5. 使用场景- 转场动画

YoKey edited this page Dec 31, 2017 · 8 revisions

Fragmentation库对Fragment的转场动画设定有更简洁的实现,库中内置提供了2种动画:横向和竖向动画,默认竖向的转场动画。

1. 通过SupportActivity设置全局Fragment的转场动画

当然如果不满足你的需求,可以自定义。你只需要通过复写SupportActivity的onCreateFragmentAnimator(),就可以轻松为该Activity下所有的Fragment设置转场动画,或者使用setFragmentAnimator()来动态改变动画。

@Override
protected FragmentAnimator onCreateFragmentAnimator() {
        // 设置横向(和安卓4.x动画相同)
        // return new DefaultHorizontalAnimator();
        // 设置无动画
        // return new DefaultNoAnimator();
        // 设置自定义动画
        // return new FragmentAnimator(enter,exit,popEnter,popExit);

        // 默认竖向(和安卓5.0以上的动画相同)
        return super.onCreateFragmentAnimator();
}

2. 为Fragment单独设置转场动画

如果某个Fragment不想使用Activity全局设置的动画,则可以通过复写Fragment内的onCreateFragmentAnimator()仅为该Fragment设置动画,,或者使用setFragmentAnimator()来动态改变动画。

// 通过
setFragmentAnimator(FragmentAnimator);

// 或者复写
@Override
protected FragmentAnimator onCreateFragmentAnimator() {
    // 获取在SupportActivity里设置的全局动画对象,进行修改
    FragmentAnimator fragmentAnimator = super.onCreateFragmentAnimation();
    fragmentAnimator.setEnter(0);
    fragmentAnimator.setExit(0);
    return fragmentAnimator;

    // 也可以直接通过
    // return new FragmentAnimator(enter,exit,popEnter,popExit)设置一个全新的动画
}

3. 为启动方Fragment和目标方Fragment 单独设置转场动画

下面的方法可以让启动的Fragment和目标Fragment拥有临时动画,优先级大于上面的FragmentAnimator设置;

场景:当你想以某个特殊动画启动一个Fragment的小弹窗时,可以使用下面方法,它不影响Fragment本身的FragmentAnimator

Demo

extraTransaction()
   .setCustomAnimations(targetFragmentEnter, currentFragmentPopExit, currentFragmentPopEnter, targetFragmentExit)
   .start(targetFragment);

4. MD过渡动画:SharedElement

Fragmentation支持SharedElement(5.0+),示例代码如下:

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
     setExitTransition(new Fade());
     fragment.setEnterTransition(new Fade());
     fragment.setSharedElementReturnTransition(new DetailTransition());
     fragment.setSharedElementEnterTransition(new DetailTransition());
     // 25.1.0以下的support包,Material过渡动画只有在进栈时有,返回时没有;
     // 25.1.0+的support包,SharedElement正常
     fragment.extraTransaction()
             .addSharedElement(((FirstHomeAdapter.VH) vh).img, getString(R.string.image_transition))
             .addSharedElement(((FirstHomeAdapter.VH) vh).tvTitle, "tv")
             .start();
} else{
    start(fragment);
}

4. 动画的优化

在复杂Fragment页面,第一次start时,会导致该Fragment因复杂初始化和动画的同时进行,导致动画卡顿问题,库中提供一个解决方案:onEnterAnimationEnd()的回调方法,具体使用移步使用场景- Fragment的优化使用