Android 转场动画

我平时项目开发必备框架java

  1. Android上最强网络请求 Net
  2. Android上最强列表(包含StateLayout) BRV
  3. Android最强缺省页 StateLayout
  4. JSON和长文本日志打印工具 LogCat
  5. 支持异步和全局自定义的吐司工具 Tooltip
  6. 开发调试窗口工具 DebugKit
  7. 一行代码建立透明状态栏 StatusBar

我平时项目开发必备框架android

  1. Android上最强网络请求 Net
  2. Android上最强列表(包含StateLayout) BRV
  3. Android最强缺省页 StateLayout
  4. JSON和长文本日志打印工具 LogCat
  5. 支持异步和全局自定义的吐司工具 Tooltip
  6. 开发调试窗口工具 DebugKit
  7. 一行代码建立透明状态栏 StatusBar

转场动画

转场动画: 是Android L 引入的动画效果, 能够说是api19引入的场景(Scene)动画的扩展. 使开发者更加方便的实现布局(界面)变化时候的过渡动画.git

Android L 是Google于2014年升级的系统版本号, 在2015年国内厂商新机就开始推送Android L, 如今是2017年我以为此时不用更待什么时候.github

转场动画(Transition)

在android.transition包下提供关于transitionAnimation的过渡框架, Transiton框架是在api19引入, 可是转场动画倒是在api21引入.api

Tip: 某些动画效果可能须要api23之上bash

类关系:markdown

  • Transition
    • ChangeBounds 改变目标视图的布局边界
    • ChangeClipBounds 裁剪目标视图边界
    • ChangeTransform 改变目标视图的缩放比例和旋转角度
    • ChangeImageTransform 改变目标图片的大小和缩放比例
    • ChangeScroll
    • TransitionSet
      • AutoTransition 默认过渡动画
    • Visibility 其子类都属于界面切换动画
      • Explode 爆炸
      • Fade 淡出
      • Slide 上下滑动

Transition是一个不须要考虑关键帧(keyFrame)只须要告诉系统你想要的动画效果就能实现其过渡网络

带有change前缀的Transition的子类只是针对特有属性才有效果app

而Visibility的子类是针对共享元素的坐标建立动画效果框架

简单的效果实现演示:

界面A

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.button) Button mButton;

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }

    @OnClick(R.id.button) public void onClick() {
        startActivity(new Intent(this, SecondActivity.class), ActivityOptionsCompat.makeSceneTransitionAnimation(this).toBundle());
    }
}
复制代码

界面B

public class SecondActivity extends AppCompatActivity {

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); // 必须
        setContentView(R.layout.activity_second);

        getWindow().setExitTransition(new Slide());
        getWindow().setEnterTransition(new Slide());
    }
}
复制代码

Tip: 官方文档说明转场动画要求当前Activity必须在setContentView以前写入以下代码, 不过api21以上并不须要如下设置.

getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
复制代码

若是要退出界面仍然有transition动画不能执行finish, 须要执行finishAfterTransition()

动画目标

默认转场动画会对全部的子View进行遍历加载动画, 可是若是添加目标则不会进行遍历全部子View, 或者你也能够排除特定View.

对于目标有三个操做

  • 添加

    默认会进行遍历全部的视图加载动画, 可是若是使用了添加就不会遍历全部, 只会让指定的视图进行动画

  • 排除

    若是使用排除方法, 依旧会进行遍历视图对象, 不过会排除你指定的视图

  • 删除

    删除目标是在动画已经遍历视图完成之后还想对目标集合进行变动, 就能够删除指定的视图

添加/排除和删除目标支持如下参数类型

  1. 视图对象(View)
  2. 过渡名(TransitionNames)
  3. 字节码(Class)
  4. ID
Transition addTarget (View target) Transition addTarget (String targetName) Transition addTarget (Class targetType) Transition addTarget (int targetId) 复制代码

删除是removeTarget(), 排除是excludeTarget()

转场动画都支持设置监听器

Transition addListener (Transition.TransitionListener listener) 复制代码

TransitionListener和AnimatorListener同样的重写方法.

窗口(Window)

从示例能够看出转场动画在代码中是经过获取Window对象进行设置的. 看下Window有哪些关于转场动画的方法.

转场动画有四种场景:

// 当前界面进入动画
void setEnterTransition (Transition transition) // 当前界面退出动画 void setExitTransition (Transition transition) // 如下介绍的是返回时的动画, 若是不设置就会默认和进入和退出动画相同 // 下个界面返回当前界面时, 当前界面进入动画 void setReenterTransition (Transition transition) // 返回上个界面时当前界面退出动画 void setReturnTransition (Transition transition) 复制代码

默认状况下界面A的退出动画尚未结束时, 界面B的进入动画就会开始执行. 如下两个方法默认为true. 想要进入动画等待退出动画结束后再播放就须要如下两个方法设置为false.

建议处于默认开启的状态, 不然可能出现背景空白期. 若是想清晰的看出几个不一样状态的动画顺序能够开启

void setAllowEnterTransitionOverlap (boolean allow) void setAllowReturnTransitionOverlap (boolean allow) 复制代码

直接设置一个

void setTransitionManager (TransitionManager tm)
复制代码

在分享元素过渡的时候是否容许重叠

void setSharedElementsUseOverlay (boolean sharedElementsUseOverlay) 复制代码

Tip: 转场动画还支持主题文件里面直接设置

界面选项(ActivityOptions)

若是想兼容api16以前的系统版本可使用ActivityOptionsCompat

该类用跳转界面的使用做为可选参数传递;

若是想让转场动画生效就必须使用下面两种方法开启界面

// 单一共享元素, 若是没有共享元素传入NULL
ActivityOptions makeSceneTransitionAnimation (Activity activity, View sharedElement, String sharedElementName) // 支持多个共享元素 ActivityOptions makeSceneTransitionAnimation (Activity activity, Pair...<View, String> sharedElements) 复制代码

自定义进入和退出动画, 和overridePendingTransition方法同样

ActivityOptions makeCustomAnimation (Context context, int enterResId, int exitResId) 复制代码

下面介绍三种系统提供的默认动画效果, 我实际使用感受效果不是很明显, 感受用处不大.

裁剪动画, 这是api23(Android m) 新增api.

ActivityOptions makeClipRevealAnimation (View source, int startX, int startY, int width, int height) 复制代码

缩放动画

ActivityOptions makeScaleUpAnimation (View source, int startX, int startY, int width, int height) 复制代码

缩略图

ActivityOptions makeThumbnailScaleUpAnimation (View source, Bitmap thumbnail, int startX, int startY) 复制代码

场景(Scene)

场景能够理解为在一个界面(Activity)当中切换或者改变布局内容, 场景是在api19引入

建立方式有两种, 一种是经过如下的静态方法直接建立

Scene getSceneForLayout (ViewGroup sceneRoot, int layoutId, Context context) 复制代码

或者经过构造方法

Scene (ViewGroup sceneRoot,  // 当前场景
                View layout) // 须要进入的新场景
复制代码

sceneRoot能够称为根视图. 在官方示例中是当前界面布局的视图对象, 能够理解为其场景(Scene)依附的Activity容器

若是你须要动态的设置场景的视图内容, 能够只指定根视图

Scene (ViewGroup sceneRoot)
复制代码

进入场景和退出场景, 不带任何动画. 通常状况下场景的进入由TransitionManager负责

void enter ()

void exit ()
复制代码

exit并不会对场景有任何变化

在场景进入和退出时能够设置两个回调方法

void setEnterAction (Runnable action)

void setExitAction (Runnable action)
复制代码

Tip: 若是两个场景存在相同的ID会自动进行共享元素动画(前提是用的不是默认的AutoTransiton, 由于该类没有使用Change)

过渡管理器(TransitionManager)

Scene默认是没有针对场景的变化, TransitionManager提供两种方式

  1. 这种默认的过渡动画是 AutoTransition

    static void go (Scene scene) 复制代码

  2. 自定义过渡动画

    static void go (Scene scene, Transition transition) 复制代码

开始延迟过渡, 即保存当前视图的属性状态, 而后在以后其发生改变的时候自动进行过渡动画

void beginDelayedTransition (ViewGroup sceneRoot) void beginDelayedTransition (ViewGroup sceneRoot, Transition transition) 复制代码

后面还能够结束自动保存属性状态

void endTransitions (ViewGroup sceneRoot)
复制代码

场景切换

// 建立一个自定义Transition动画的TransitionManager
mTransitionManagerForScene3 = TransitionInflater.from(getActivity())
.inflateTransitionManager(R.transition.scene3_transition_manager, mSceneRoot);

// 而后切换任意布局
mTransitionManagerForScene3.transitionTo(mScene3);
复制代码

该方法等同于提到的go()

void transitionTo (Scene scene) 复制代码

XML定义

不一样于普通的动画, 转场动画拥有专属的资源目录transition

在res/transition目录下建立XML文件

标签一览

引用XML

Transition explode = TransitionInflater.from(this).inflateTransition(R.transition.explode);
复制代码

或者能够直接在主题中设置

<item name="android:windowExitTransition">@transition/explode</item>
<item name="android:windowEnterAnimation">@transition/explode</item>
<item name="android:windowReenterTransition">@transition/explode</item>
复制代码

TransitionInflat除上面提到的方法外还能够填充trantionManager对象

TransitionManager inflateTransitionManager (int resource, ViewGroup sceneRoot) 复制代码

共享元素(ShareElement)

共享元素

通常是在关联的界面以前存在相同的(或者说相似的, 并不强制必定要相同)控件元素就会使用, 例以下图的按钮:

A界面跳转要指定共享元素

startActivity(new Intent(this, SecondActivity.class),
                ActivityOptionsCompat.makeSceneTransitionAnimation(this, mButton, "button")
                        .toBundle());
复制代码

B界面的布局文件中指定共享元素android:transitionName="button"

<Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="第二个界面" android:transitionName="button" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="99dp" />
复制代码

能够看到所谓的共享元素即在两个界面的两个控件(或多个控件)之间的过渡变化效果

能够看到转场动画的操做都是针对Window对象, 拥有以下方法(同时都拥有对应的getter方法)

共享元素

void setSharedElementEnterTransition (Transition transition) void setSharedElementExitTransition (Transition transition) void setSharedElementReenterTransition (Transition transition) void setSharedElementReturnTransition (Transition transition) 复制代码

自定义Transiton

主要重写三个方法

  1. 开始值
  2. 结束值
  3. 建立动画

官方示例

Tip: 针对不一样的View采用不一样的动画效果能够重写Transition

扩散(Propagation)

Propagation能够指定Transition中的视图过渡延迟, 控制进入当前场景的视图进入的前后顺序. 例如要求Explode动画中特定的View速度快于其余的视图.

扩散中心

首先须要Transition确认扩散中心

void setEpicenterCallback (Transition.EpicenterCallback epicenterCallback) 复制代码

在Transiton.EpicenterCallback回调中须要重写如下方法

Rect onGetEpicenter (Transition transition) 复制代码

在回调方法内返回一个矩形, 其矩形的中心即扩散中心.

关系:

  • TransitionPropagation
    • VisibilityPropagation
      • SidePropagation
      • CircularPropagation

经过transition的方法指定

void setPropagation (TransitionPropagation transitionPropagation) // 设置扩散 void setPropagationSpeed (float propagationSpeed) // 设置速度 复制代码

查看源码能够看到Explode默认使用的CircularPropagation

Slide使用的天然是SlidePropagation

TransitionPropagation 属于抽象类提供三个重写方法

void captureValues (TransitionValues transitionValues) String[] getPropagationProperties () long getStartDelay (ViewGroup sceneRoot, Transition transition, TransitionValues startValues, TransitionValues endValues) 复制代码

分别控制:

  1. 捕捉

示例

slide.setPropagation(new VisibilityPropagation() {
  @Override public long getStartDelay(ViewGroup sceneRoot, Transition transition, TransitionValues startValues, TransitionValues endValues) {
    return 0;
  }
});
复制代码

路径动做

PathMotion是在api21引入的过渡动画的一种新的实现方式. 能够经过指定路径来限制动画运动轨迹

经过Transition设置路径动画

void setPathMotion (PathMotion pathMotion) 复制代码

PathMotion

  • ArcMotion (弧形动做)
  • PatternPathMotion

弧形轨迹

共享元素都是在不一样的界面间的位置变化是以直线运动的, 经过指定如下路径动做能够变成弧形轨迹

参考 GooglePlay 的实现效果

<changeBounds>
   <arcMotion android:minimumHorizontalAngle="15" android:minimumVerticalAngle="0" android:maximumAngle="90"/>
 </changeBounds>
复制代码

参数:

  • android:maximumAngle

    ​ 开始和结束的最大弧形角度

  • android:minimumHorizontalAngle

    ​ 二者接近水平的时候最小角度

  • android:minimumVerticalAngle

    ​ 垂直同上

路径动做

能够彻底自定义路径来控制共享元素的运动轨迹

<changeBounds>
     <patternPathMotion android:patternPathData="M0 0 L0 100 L100 100"/>
 </changeBounds>
复制代码

Tip: patternPathData 的参数值相似矢量动画

自定义路径动做

<changeBounds>
     <pathMotion class="my.app.transition.MyPathMotion"/>
 </changeBounds>
复制代码
相关文章
相关标签/搜索