Skip to content

Instantly share code, notes, and snippets.

@johnbear724
Last active August 29, 2015 14:08
Show Gist options
  • Save johnbear724/83ca04a416c67d67b554 to your computer and use it in GitHub Desktop.
Save johnbear724/83ca04a416c67d67b554 to your computer and use it in GitHub Desktop.
定义自定义动画

该文档翻译自 Android 5.0 文档中对 Material Design 的介绍,原文地址:http://developer.android.com/training/material/animations.html

Material Design 中的动画用于在用户执行操作时给予他们反馈,并使用户在与你的应用交互时提供良好的视觉连续性。Material 主题为按钮和 Activity 过渡提供了一些默认的动画,同时在Android 5.0(API level 21)及以上版本你可以自定义这些动画并创建新的:

  • 触摸反馈 (Touch feedback)
  • 圆形波纹 (Circular Reveal)
  • Activity 过渡 (Activity transitions)
  • 曲线运动 (Curved motion)
  • 视图状态变化 (View state changes)

##自定义触摸反馈

Material Design 中的触摸反馈在用户与UI元素交互时在其接触点上给予了一个转瞬即逝的视觉确认信息。默认的触摸反馈使用新的 RippleDrawable 类为按钮施加动画,该类可以使按钮在不同状态间切换时实现水波纹效果。

在大多数情况下,你若要将这些功能应用到你的视图 XML 文件中,需要像这样指定视图的背景:

  • 有边界波纹需要设置背景为: ?android:attr/selectableItemBackground
  • 超出视图界限的波纹设置背景为: ?android:attr/selectableItemBackgroundBorderless

注意:selectableItemBackgroundBorderless 是在 API level 21 加入的新属性。

或者,你可以使用 ripple 元素定义一个 XML 资源 RippleDrawable。

你可以为 RippleDrawable 分配一种颜色。要改变默认的触摸反馈颜色,使用主题的 android:colorControlHighlight 属性。

更多信息,请参考 API 文档 RippleDrawable 类。

##使用显露效果(Revele Effect)

显露(Revele)动画在你显示或隐藏一组 UI 元素时给用户提供了更好的视觉连续性。 ViewAnimationUtils.createCircularReveal() 方法能够让你对一个剪切圆实施动画来显现和隐藏一个视图。

要显示之前隐藏的视图使用以下效果:

// 之前不可见的视图
View myView = findViewById(R.id.my_view);

// 获取裁剪圆的中心
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;

// 获得裁剪圆的最终半径
int finalRadius = myView.getWidth();

// 为该视图创建并启动动画绘制器
// (开始半径为 0 )
Animator anim =
    ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
anim.start();

要隐藏一个之前可见的视图使用以下效果:

// 之前可见的视图
final View myView = findViewById(R.id.my_view);

// 获取裁剪圆的中心
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;

// 获得裁剪圆的最终半径
int initialRadius = myView.getWidth();

// 创建动画(最终半径为0)
Animator anim =
    ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);

// 当动画完成时使视图不可见
anim.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
        myView.setVisibility(View.INVISIBLE);
    }
});

// 启动动画
anim.start();

##自定义 Activity 过渡(transition)

Material Design 中的 Activity 过渡动画通过两个 Activity 中的共有元素的移动和变换为其在不同状态提供了可视化的连接。你可以为进入过渡,退出过渡和 Activity 之间共享元素的过渡进行定制来指定你自己创建的动画。

  • 进入过渡决定了 Activity 中的视图如何进入场景。例如,在 explode 的进入过渡中,视图从屏幕外面进入屏幕并飞到屏幕中间。
  • 退出过渡决定了Activity 中的视图如何退出场景。例如,在 explode 的退出过渡中,视图从中间向外退出场景。
  • 共享元素过渡决定了在两个 Activitis 之间共享的视图在这些 Activities 转变时的变化。例如,如果两个 Activities 有一个相同的图片在不同的位置有着不同的大小,changeImageTransform 这个共享元素过渡将在两个 Activities 之间平滑的变换缩放该图片。

Android 5.0(API level 21)支持这些进入和退出过渡:

  • explode - 将视图从场景中心移入或移出。
  • slid - 从场景的某一边移入或移出
  • fade - 通过改变视图的透明度来添加或移除一个视图。

任何继承了 Visibility 类的过渡都可以作为进入过渡或退出过渡。更多信息,请查看 Transition 类。

Android 5.0(API level 21)还支持共享元素过渡:

  • changeBounds - 动态改变目标视图的布局边界
  • changeClipBounds - 动态改变目标视图的裁剪边界
  • changeTransform - 动态改变目标视图的缩放比例和旋转角度
  • changeImageTransform - 动态改变目标图片的尺寸和缩放比例

当你在你的应用中启用了 Activity 过渡,默认的交叉渐隐过渡会在进入和退出 Activities 时触发。

图例: 有一个共享元素的场景过渡

###指定自定义过渡

首先,当你定义了一个继承了 Material 主题的样式时,可以使用 android:windowContentTransitions 属性启用窗口内容过渡。你还可以在你的样式定义中指定进入,退出和共享元素过渡。

<style name="BaseAppTheme" parent="android:Theme.Material">
  <!-- 启用窗口内容过渡 -->
  <item name="android:windowContentTransitions">true</item>

  <!-- 指定进入和退出过渡 -->
  <item name="android:windowEnterTransition">@transition/explode</item>
  <item name="android:windowExitTransition">@transition/explode</item>

  <!-- 指定共享元素过渡 -->
  <item name="android:windowSharedElementEnterTransition">
    @transition/change_image_transform</item>
  <item name="android:windowSharedElementExitTransition">
    @transition/change_image_transform</item>
</style>

该实例中的 change_image_transform 过渡定义如下:

<!-- res/transition/change_image_transform.xml -->
<!-- (更多信息请查看下面的共享元素过渡) -->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
  <changeImageTransform/>
</transitionSet>

changeImageTransform 元素对应了 ChangeImageTransform 类。更多信息,查看 Transition API 文档。

要在你的代码中启用窗口内容过渡,调用 Window.requestFeature() 方法:

// 在你的 Activity 代码中(如果你没有在你的主题中启用过渡)
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

// 设置一个退出过渡
getWindow().setExitTransition(new Explode());

要在代码中指定过渡,传入一个 Transition 对象来调用这些方法:

  • Window.setEnterTransition()
  • Window.setExitTransition()
  • Window.setSharedElementEnterTransition()
  • Window.setSharedElementExitTransition()

setExitTransition() 和 setSharedElementExitTransition() 方法为调用的 Activity 定义了退出过渡。

setEnterTransition() 和 setSharedElementEnterTransition() 方法为调用的 Activity 定义了进入过渡。

要获得过渡的全部效果,你必须要在调用和被调用的 Activities 都启用窗口内容过渡。否则,你调用的 Activity 会启动退出过渡,但是之后你将看到窗口过渡(像是缩放或淡出)。

要尽可能快的开始进入过渡,在被调用的 Activity 上使用 Window.setAllowEnterTransitionOverlap() 方法。这会让你有更引人注目的进入过渡动画。

###用过渡启动一个 Activity

如果你启用了过渡并为一个 Activity 设置了一个退出过渡,当你像下面这样启动另一个 Activity 时该过渡会被激活:

startActivity(intent,
              ActivityOptions.makeSceneTransition
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment