自定义过渡允许您创建任何内置过渡类都无法提供的动画。例如,您可以定义一个自定义过渡,将文本和输入字段的前景色变为灰色,以指示这些字段在新屏幕中已被禁用。这种类型的变化有助于用户识别您禁用的字段。
与内置的过渡类型一样,自定义过渡会将动画应用于起始场景和结束场景的子视图。但是,与内置过渡类型不同,您必须提供用于捕获属性值并生成动画的代码。您可能还需要为您的动画定义目标视图的子集。
本页面将教您如何捕获属性值并生成动画以创建自定义过渡。
扩展 Transition 类
要创建自定义过渡,请向您的项目中添加一个继承自 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 实例,您可以在其中存储所需的视图值。在您的实现中,检索这些属性值并通过将它们存储在映射中传回给框架。
为了确保属性值的键不会与其他 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() 检索的视图属性是相同的,但在起始场景和结束场景中其值不同。框架分别为视图的起始状态和结束状态维护单独的映射。
创建自定义动画器
要为视图在起始场景状态和结束场景状态之间的变化设置动画,请通过重写 createAnimator() 函数来提供动画器。当框架调用此函数时,它会传入场景根视图以及包含您所捕获的起始值和结束值的 TransitionValues 对象。
框架调用 createAnimator() 函数的次数取决于起始场景和结束场景之间发生的更改。
例如,考虑实现为自定义过渡的淡出或淡入动画。如果起始场景有 5 个目标,其中 2 个在结束场景中被移除,而结束场景包含起始场景中的 3 个目标加上 1 个新目标,则框架会调用 createAnimator() 6 次。其中 3 次调用用于为保留在两个场景对象中的目标设置淡出和淡入动画。另外 2 次调用用于为从结束场景中移除的目标设置淡出动画。1 次调用用于为结束场景中的新目标设置淡入动画。
对于存在于起始场景和结束场景中的目标视图,框架会为 startValues 和 endValues 参数提供 TransitionValues 对象。对于仅存在于起始场景或结束场景中的目标视图,框架会为相应的参数提供 TransitionValues 对象,而为另一个参数提供 null。
在创建自定义过渡时实现 createAnimator(ViewGroup, TransitionValues, TransitionValues) 函数时,请使用您捕获的视图属性值来创建 Animator 对象并将其返回给框架。有关实现示例,请参阅 CustomTransition 示例中的 ChangeColor 类。有关属性动画器的更多信息,请参阅属性动画。
应用自定义过渡
自定义过渡的工作方式与内置过渡相同。您可以使用过渡管理器来应用自定义过渡,如应用过渡中所述。