创建自定义过渡动画
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
试试 Compose 方式
Jetpack Compose 是推荐用于 Android 的界面工具包。了解如何在 Compose 中添加动画。
通过自定义过渡,您可以创建无法通过任何内置过渡类获得的动画。例如,您可以定义一个自定义过渡,该过渡使文本和输入字段的前景颜色变为灰色来表明这些字段已在新屏幕中停用。此类更改有助于用户看到您已停用的字段。
自定义过渡与某种内置过渡类型一样,可将动画应用于起始和结束场景的子视图。不过,与内置过渡类型不同,您必须提供捕获属性值和生成动画的代码。您可能还需要为动画定义目标视图的子集。
本页介绍了如何捕获属性值并生成动画以创建自定义过渡。
扩展过渡类
如需创建自定义过渡,请向您的项目添加一个类以扩展 Transition
类,并替换以下代码段中显示的函数:
Kotlin
class CustomTransition : Transition() {
override fun captureStartValues(transitionValues: TransitionValues) {}
override fun captureEndValues(transitionValues: TransitionValues) {}
override fun createAnimator(
sceneRoot: ViewGroup,
startValues: TransitionValues?,
endValues: TransitionValues?
): Animator? {}
}
Java
public class CustomTransition extends Transition {
@Override
public void captureStartValues(TransitionValues values) {}
@Override
public void captureEndValues(TransitionValues values) {}
@Override
public Animator createAnimator(ViewGroup sceneRoot,
TransitionValues startValues,
TransitionValues endValues) {}
}
下面的部分介绍了如何替换这些函数。
捕获视图属性值
过渡动画使用属性动画概览中所述的属性动画系统。属性动画可以将视图属性从起始值更改为结束值,并在指定的时间段内完成此更改,因此框架需要同时具有属性的起始值和结束值才能构建动画。
不过,属性动画通常只需要视图的所有属性值中的一小部分。例如,颜色动画需要颜色属性值,而移动动画需要位置属性值。由于动画所需的属性值因过渡而异,因此过渡框架不会为某个过渡提供所有属性值。相反,框架会调用允许过渡仅捕获其所需的属性值并将它们存储到框架中的回调函数。
捕获起始值
如需将起始视图值传递给框架,请实现 captureStartValues(transitionValues)
函数。该框架会针对起始场景中的每个视图调用此函数。该函数参数是一个 TransitionValues
对象,其中包含对视图的引用和 Map
实例,您可以在该实例中存储所需的视图值。在您的实现中,通过将这些属性值存储到 Map 实例中对其进行检索并将它们回传至框架。
为了确保属性值的键不会与其他 TransitionValues
键冲突,请使用以下命名方案:
package_name:transition_name:property_name
以下代码段展示了 captureStartValues()
函数的一个实现:
Kotlin
class CustomTransition : Transition() {
// Define a key for storing a property value in
// TransitionValues.values with the syntax
// package_name:transition_class:property_name to avoid collisions
private val PROPNAME_BACKGROUND = "com.example.android.customtransition:CustomTransition:background"
override fun captureStartValues(transitionValues: TransitionValues) {
// Call the convenience method captureValues
captureValues(transitionValues)
}
// For the view in transitionValues.view, get the values you
// want and put them in transitionValues.values
private fun captureValues(transitionValues: TransitionValues) {
// Get a reference to the view
val view = transitionValues.view
// Store its background property in the values map
transitionValues.values[PROPNAME_BACKGROUND] = view.background
}
...
}
Java
public class CustomTransition extends Transition {
// Define a key for storing a property value in
// TransitionValues.values with the syntax
// package_name:transition_class:property_name to avoid collisions
private static final String PROPNAME_BACKGROUND =
"com.example.android.customtransition:CustomTransition:background";
@Override
public void captureStartValues(TransitionValues transitionValues) {
// Call the convenience method captureValues
captureValues(transitionValues);
}
// For the view in transitionValues.view, get the values you
// want and put them in transitionValues.values
private void captureValues(TransitionValues transitionValues) {
// Get a reference to the view
View view = transitionValues.view;
// Store its background property in the values map
transitionValues.values.put(PROPNAME_BACKGROUND, view.getBackground());
}
...
}
捕获结束值
该框架会针对结束场景中的每个目标视图调用一次 captureEndValues(TransitionValues)
函数。在所有其他方面,captureEndValues()
的工作原理与 captureStartValues()
相同。
以下代码段展示了 captureEndValues()
函数的一个实现:
Kotlin
override fun captureEndValues(transitionValues: TransitionValues) {
captureValues(transitionValues)
}
Java
@Override
public void captureEndValues(TransitionValues transitionValues) {
captureValues(transitionValues);
}
在本例中,captureStartValues()
和 captureEndValues()
函数都会调用 captureValues()
以检索和存储值。captureValues()
检索的视图属性是相同的,但在起始场景和结束场景中具有不同的值。该框架会为视图的起始状态和结束状态维护单独的 Map 实例。
创建自定义动画程序
如需为视图在起始场景中的状态和结束场景中的状态之间的变化添加动画效果,请通过替换 createAnimator()
函数来提供动画程序。当框架调用此函数时,它会传入场景根视图和包含您捕获的起始值和结束值的 TransitionValues
对象。
框架调用 createAnimator()
函数的次数取决于起始场景和结束场景之间发生的变化。
例如,假设将淡出或淡入动画作为自定义过渡实现。如果起始场景有 5 个目标,其中 2 个从结束场景中移除,并且结束场景包含起始场景中的 3 个目标以及一个新目标,则该框架会调用 createAnimator()
6 次。其中三个调用会为同时位于两个场景对象中的目标进行淡出和淡入动画。另外两个调用会为从结尾场景中移除的目标添加淡出动画。其中一个调用会在结束场景中为新目标添加淡入动画。
对于同时存在于起始场景和结束场景中的目标视图,该框架会为 startValues
和 endValues
参数提供 TransitionValues
对象。对于仅存在于起始场景或结束场景中的目标视图,该框架会为相应的参数提供 TransitionValues
对象,并为其他参数提供 null
。
如需在创建自定义过渡时实现 createAnimator(ViewGroup, TransitionValues, TransitionValues)
函数,请使用您捕获的视图属性值创建 Animator
对象并将其返回到框架。如需查看示例实现,请参阅
CustomTransition 示例中的 ChangeColor
类。如需详细了解属性动画程序,请参阅属性动画。
应用自定义过渡
自定义过渡与内置过渡的工作原理相同。您可以使用过渡管理程序来应用自定义过渡,如应用过渡中所述。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-08-24。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-08-24。"],[],[],null,["# Create a custom transition animation\n\nTry the Compose way \nJetpack Compose is the recommended UI toolkit for Android. Learn how to add animations in Compose. \n[Add multiple properties with a transition in Compose →](/develop/ui/compose/animation/value-based#updateTransition) \n\nA custom transition lets you create an animation that is not available from any of\nthe built-in transition classes. For example, you can define a custom transition that turns\nthe foreground color of text and input fields to gray to indicate that the fields are disabled\nin the new screen. This type of change helps users see the fields you disabled.\n\nA custom transition, like one of the built-in transition types, applies animations to\nchild views of both the starting and ending scenes. However, unlike built-in transition types,\nyou have to provide the code that captures property values and generates animations.\nYou might also want to define a subset of target views for your animation.\n\nThis page teaches you how to capture property values and generate animations to create\ncustom transitions.\n\nExtend the Transition class\n---------------------------\n\nTo create a custom transition, add a class to your project that extends the [Transition](/reference/android/transition/Transition) class and override the functions shown in the following snippet: \n\n### Kotlin\n\n```kotlin\nclass CustomTransition : Transition() {\n\n override fun captureStartValues(transitionValues: TransitionValues) {}\n\n override fun captureEndValues(transitionValues: TransitionValues) {}\n\n override fun createAnimator(\n sceneRoot: ViewGroup,\n startValues: TransitionValues?,\n endValues: TransitionValues?\n ): Animator? {}\n\n}\n```\n\n### Java\n\n```java\npublic class CustomTransition extends Transition {\n\n @Override\n public void captureStartValues(TransitionValues values) {}\n\n @Override\n public void captureEndValues(TransitionValues values) {}\n\n @Override\n public Animator createAnimator(ViewGroup sceneRoot,\n TransitionValues startValues,\n TransitionValues endValues) {}\n}\n```\n\nThe following sections explain how to override these functions.\n\nCapture view property values\n----------------------------\n\nTransition animations use the property animation system described in\n[Property animation overview](/guide/topics/graphics/prop-animation). Property\nanimations change a view property from a starting value to an ending value over a specified\nperiod of time, so the framework needs to have both the starting and ending values of\nthe property to construct the animation.\n\nHowever, a property animation usually needs only a small subset of all the view's property\nvalues. For example, a color animation needs color property values, while a movement\nanimation needs position property values. Since the property values needed for an animation\nare specific to a transition, the transitions framework does not provide every property value\nto a transition. Instead, the framework invokes callback functions that allow a transition to\ncapture only the property values it needs and store them in the framework.\n\n### Capture starting values\n\nTo pass the starting view values to the framework, implement the\n[captureStartValues(transitionValues)](/reference/android/transition/Transition#captureStartValues(android.transition.TransitionValues))\nfunction. The framework calls this function for every view in the starting scene. The function\nargument is a [TransitionValues](/reference/android/transition/TransitionValues) object that contains a reference\nto the view and a [Map](/reference/java/util/Map) instance in which you can store the view values you\nwant. In your implementation, retrieve these property values and pass them back to the\nframework by storing them in the map.\n\nTo ensure that the key for a property value does not conflict with other\n`TransitionValues` keys, use the following naming scheme: \n\n```xml\npackage_name:transition_name:property_name\n```\n\nThe following snippet shows an implementation of the `captureStartValues()` function: \n\n### Kotlin\n\n```kotlin\nclass CustomTransition : Transition() {\n\n // Define a key for storing a property value in\n // TransitionValues.values with the syntax\n // package_name:transition_class:property_name to avoid collisions\n private val PROPNAME_BACKGROUND = \"com.example.android.customtransition:CustomTransition:background\"\n\n override fun captureStartValues(transitionValues: TransitionValues) {\n // Call the convenience method captureValues\n captureValues(transitionValues)\n }\n\n // For the view in transitionValues.view, get the values you\n // want and put them in transitionValues.values\n private fun captureValues(transitionValues: TransitionValues) {\n // Get a reference to the view\n val view = transitionValues.view\n // Store its background property in the values map\n transitionValues.values[PROPNAME_BACKGROUND] = view.background\n }\n\n ...\n\n}\n```\n\n### Java\n\n```java\npublic class CustomTransition extends Transition {\n\n // Define a key for storing a property value in\n // TransitionValues.values with the syntax\n // package_name:transition_class:property_name to avoid collisions\n private static final String PROPNAME_BACKGROUND =\n \"com.example.android.customtransition:CustomTransition:background\";\n\n @Override\n public void captureStartValues(TransitionValues transitionValues) {\n // Call the convenience method captureValues\n captureValues(transitionValues);\n }\n\n\n // For the view in transitionValues.view, get the values you\n // want and put them in transitionValues.values\n private void captureValues(TransitionValues transitionValues) {\n // Get a reference to the view\n View view = transitionValues.view;\n // Store its background property in the values map\n transitionValues.values.put(PROPNAME_BACKGROUND, view.getBackground());\n }\n ...\n}\n```\n\n### Capture ending values\n\nThe framework calls the [captureEndValues(TransitionValues)](/reference/android/transition/Transition#captureEndValues(android.transition.TransitionValues)) function\nonce for every target view in the ending scene. In all other respects, `captureEndValues()` works the same as `captureStartValues()`.\n\nThe following code snippet shows an implementation of the `captureEndValues()` function: \n\n### Kotlin\n\n```kotlin\noverride fun captureEndValues(transitionValues: TransitionValues) {\n captureValues(transitionValues)\n}\n```\n\n### Java\n\n```java\n@Override\npublic void captureEndValues(TransitionValues transitionValues) {\n captureValues(transitionValues);\n}\n```\n\nIn this example, both the `captureStartValues()` and `captureEndValues()`\nfunctions invoke `captureValues()` to retrieve and store values. The view property\nthat `captureValues()` retrieves is the same, but it has different values in the\nstarting and ending scenes. The framework maintains separate maps for the starting and ending\nstates of a view.\n\nCreate a custom animator\n------------------------\n\nTo animate the changes to a view between its state in the starting scene and its state in\nthe ending scene, provide an animator by overriding the\n[createAnimator()](/reference/android/transition/Transition#createAnimator(android.view.ViewGroup, android.transition.TransitionValues, android.transition.TransitionValues))\nfunction. When the framework calls this function, it passes in the scene root view and the\n`TransitionValues` objects that contain the starting and ending values\nyou captured.\n\nThe number of times the framework calls the `createAnimator()` function depends on the\nchanges that occur between the starting and ending scenes.\n\nFor example, consider a fade-out or\nfade-in animation implemented as a custom transition. If the starting scene has five targets, of\nwhich two are removed from the ending scene, and the ending scene has the three targets from the\nstarting scene plus a new target, then the framework calls `createAnimator()` six times.\nThree of the calls animate the fade-out and fade-in of the targets that stay in both scene\nobjects. Two more calls animate the fade-out of the targets removed from the ending scene. One\ncall animates the fade-in of the new target in the ending scene.\n\nFor target views that exist in both the starting and ending scenes, the framework provides\na `TransitionValues` object for both the `startValues` and\n`endValues` arguments. For target views that only exist in the starting or the\nending scene, the framework provides a `TransitionValues` object\nfor the corresponding argument and `null` for the other.\n\nTo implement the [createAnimator(ViewGroup, TransitionValues, TransitionValues)](/reference/android/transition/Transition#createAnimator(android.view.ViewGroup, android.transition.TransitionValues, android.transition.TransitionValues)) function when you create\na custom transition, use the view property values you captured to create an [Animator](/reference/android/animation/Animator) object and return it to the framework. For an example implementation,\nsee the [ChangeColor](https://github.com/android/animation-samples/blob/master/CustomTransition/Application/src/main/java/com/example/android/customtransition/ChangeColor.java) class in the [CustomTransition](https://github.com/android/animation-samples/tree/main/CustomTransition) sample. For more information about property animators, see\n[Property animation](/guide/topics/graphics/prop-animation).\n\nApply a custom transition\n-------------------------\n\nCustom transitions work the same as built-in transitions. You can apply a custom transition\nusing a transition manager, as described in [Apply a transition](/training/transitions/transitions#Apply)."]]