HarmonyOS 开发之 —— 合理使用动画与转场

217 阅读5分钟

HarmonyOS 开发之 —— 合理使用动画与转场

在移动应用开发中,动画与转场效果是提升用户体验的重要手段。HarmonyOS 提供了丰富的动画 API,支持属性动画和转场动画,能够实现流畅的界面交互和页面切换效果。本文将详细介绍如何在 HarmonyOS 中合理使用这两类动画,并提供具体的代码示例。

一、属性动画(Property Animation)

1.1 动画概述

动画是通过连续改变视图的属性(如位置、大小、透明度等),在视觉上产生动态变化的效果。合理的动画可以增强用户反馈,引导用户注意力,提升界面的交互性和美观度。HarmonyOS 的动画系统基于属性驱动,支持对任意可动画化的属性进行操作。

1.2 属性动画概述

属性动画通过修改目标对象的属性值,在指定时间内完成从起始值到结束值的过渡。与传统的补间动画(Tween Animation)相比,属性动画直接操作对象的属性,支持更灵活的动画控制,并且可以作用于任何对象,而不仅仅是视图组件。

核心组件:

Animator:动画的基类,提供动画的基本控制功能(启动、暂停、停止等)。

ValueAnimator:数值动画器,用于生成连续的数值序列,需要结合目标对象的属性设置来实现动画效果。

ObjectAnimator:对象动画器,直接针对目标对象的属性进行动画操作,简化了动画配置流程。

插值器(Interpolator):控制动画的速度变化(如线性、加速、减速等)。

估值器(Evaluator):定义数值过渡的规则,支持整数、浮点数、颜色等类型的插值计算。

1.3 实现属性动画

场景 1:视图位置移动动画
// 获取目标组件

Component targetComponent = findComponentById(ResourceTable.Id\_target\_component);

// 创建ObjectAnimator,修改x坐标属性

ObjectAnimator moveAnimator = ObjectAnimator.ofFloat(targetComponent, "x", 0f, 400f);

moveAnimator.setDuration(1000); // 动画时长1秒

moveAnimator.setInterpolator(new AccelerateInterpolator()); // 设置加速插值器

// 动画监听器(可选)

moveAnimator.addAnimatorListener(new Animator.AnimatorListener() {

    @Override

    public void onStart(Animator animator) {

        // 动画开始时回调

    }

    @Override

    public void onEnd(Animator animator) {

        // 动画结束时回调

    }

    @Override

    public void onCancel(Animator animator) {

        // 动画取消时回调

    }

    @Override

    public void onPause(Animator animator) {

        // 动画暂停时回调

    }

});

// 启动动画

moveAnimator.start();
场景 2:组合动画(缩放 + 透明度变化)
// 创建缩放动画(x和y轴同时缩放)

ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(targetComponent, "scaleX", 1f, 1.5f, 1f);

ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(targetComponent, "scaleY", 1f, 1.5f, 1f);

// 创建透明度动画

ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(targetComponent, "alpha", 1f, 0.5f, 1f);

// 组合动画(同时播放)

AnimatorSet animatorSet = new AnimatorSet();

animatorSet.play(scaleXAnimator).with(scaleYAnimator).with(alphaAnimator);

animatorSet.setDuration(1500);

animatorSet.start();
场景 3:自定义属性动画(非视图对象属性)
// 定义目标对象及属性

class MyData {

    private float progress;

    public float getProgress() {

        return progress;

    }

    public void setProgress(float progress) {

        this.progress = progress;

        // 更新UI或执行其他逻辑

    }

}

MyData data = new MyData();

// 使用ValueAnimator生成数值序列

ValueAnimator progressAnimator = ValueAnimator.ofFloat(0f, 100f);

progressAnimator.setDuration(2000);

progressAnimator.addUpdateListener(animation -> {

    float value = (float) animation.getAnimatedValue();

    data.setProgress(value);

});

progressAnimator.start();

二、转场动画(Transition Animation)

2.1 转场动画概述

转场动画用于页面(Ability)或组件之间的切换过渡,通过定义进入和退出的动画效果,使界面切换更具连贯性和视觉反馈。HarmonyOS 支持两种转场类型:简单转场带共享元素的转场

核心类:

Transition:转场动画的基类,提供进入 / 退出动画的配置。

TransitionElement:共享元素转场的核心类,用于定义两个页面间共享的视觉元素(如图片、按钮等)。

TransitionManager:管理转场动画的启动和配置。

2.2 使用简单转场动画

场景:页面滑动切换效果

在源页面(Source Ability)中启动转场

// 创建转场对象(滑动从右进入,从左退出)

Transition enterTransition = new SlideTransition(SlideTransition.SLIDE\_RIGHT);

Transition exitTransition = new SlideTransition(SlideTransition.SLIDE\_LEFT);

// 设置转场持续时间

enterTransition.setDuration(500);

exitTransition.setDuration(500);

// 创建转场参数

TransitionParameters transitionParameters = new TransitionParameters();

transitionParameters.setEnterTransition(enterTransition);

transitionParameters.setExitTransition(exitTransition);

// 启动转场并跳转页面

Intent intent = new Intent();

Operation operation = new Intent.OperationBuilder()

        .withBundleName("com.example.target")

        .withAbilityName("com.example.target.TargetAbility")

        .build();

intent.setOperation(operation);

startAbilityForResult(intent, 0, transitionParameters);

在目标页面(Target Ability)中接收转场

@Override

protected void onStart(Intent intent) {

    super.onStart(intent);

    // 配置目标页面的进入转场(可选,与源页面的退出转场配合)

    Transition enterTransition = new SlideTransition(SlideTransition.SLIDE\_LEFT);

    setEnterTransition(enterTransition);

}

2.3 使用共享元素转场

场景:图片点击放大进入新页面

源页面布局(包含共享图片组件)

\<Image

&#x20;   ohos:id="\$+id/shared\_image"

&#x20;   ohos:width="100vp"

&#x20;   ohos:height="100vp"

&#x20;   ohos:image\_src="\$media:shared\_image"

&#x20;   ohos:scale\_mode="zoom\_center"

&#x20;   ohos:clickable="true"/>

源页面代码

Image sharedImage = findComponentById(ResourceTable.Id\_shared\_image);

sharedImage.setClickedListener(component -> {

&#x20;   // 创建共享元素转场参数

&#x20;   TransitionElement sharedElement = new TransitionElement(sharedImage);

&#x20;   TransitionParameters parameters = new TransitionParameters();

&#x20;   parameters.addTransitionElement(sharedElement);

&#x20;  &#x20;

&#x20;   // 跳转目标页面并传递共享元素信息

&#x20;   Intent intent = new Intent();

&#x20;   Operation operation = new Intent.OperationBuilder()

&#x20;       .withBundleName("com.example.target")

&#x20;       .withAbilityName("com.example.target.BigImageAbility")

&#x20;       .build();

&#x20;   intent.setOperation(operation);

&#x20;   startAbilityForResult(intent, 0, parameters);

});

目标页面布局(包含放大后的共享图片组件)

\<Image

&#x20;   ohos:id="\$+id/big\_image"

&#x20;   ohos:width="match\_parent"

&#x20;   ohos:height="match\_parent"

&#x20;   ohos:image\_src="\$media:shared\_image"

&#x20;   ohos:scale\_mode="zoom\_center"/>

目标页面代码

Image bigImage = findComponentById(ResourceTable.Id\_big\_image);

// 配置共享元素映射(名称需与源页面一致)

TransitionElement sharedElement = new TransitionElement(bigImage);

sharedElement.setTransitionName("shared\_image");

addTransitionElement(sharedElement);

// 设置进入转场动画(共享元素缩放效果)

ScaleTransition scaleTransition = new ScaleTransition();

scaleTransition.setDuration(800);

setEnterTransition(scaleTransition);

三、最佳实践与注意事项

性能优化:避免对大量组件同时应用复杂动画,优先使用硬件加速(通过Component.setHardwareAccelerated(true))。

交互一致性:保持动画时长和效果在整个应用中的一致性,避免过度动画干扰用户。

兼容性:检查不同 API 版本的动画支持情况,使用hasFeature()方法判断设备是否支持特定动画功能。

可访问性:为动画添加适当的无障碍描述,确保视障用户能感知动画变化。

通过合理运用属性动画和转场动画,开发者可以为 HarmonyOS 应用打造更具吸引力和易用性的用户界面。建议在实际项目中结合具体场景,灵活组合不同的动画类型,并通过调试工具(如 DevEco Studio 的动画预览功能)优化动画效果。