安卓开发之动画效果

  • 动画可以为应用程序增添生动性和交互性,增强用户体验。在安卓中有几种比较常见的动画形式:帧动画、补间动画、属性动画、过渡动画。他们有着各自的特性,从而适应不同的开发场景。

帧动画(Frame Animation)

帧动画就像播放一系列的图片帧来形成动画效果。它通过在 XML 文件中定义一系列的draw1able资源作为帧,然后按照一定的顺序和时间间隔来播放这些帧。优点是实现简单,工作量都在设计师。缺点是需要添加很多图片资源,占用安装包大小。如果图片太大,也会造成卡顿。

  • 在drawable目录下创建一个frame_animation.xml文件:

<animation - list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/frame1" android:duration="100"/> <item android:drawable="@drawable/frame2" android:duration="100"/> <item android:drawable="@drawable/frame3" android:duration="100"/> </animation - list>

  • 在Java代码中引用,并显示到控件当中:

ImageView imageView = findViewById(R.id.image_view); imageView.setImageResource(R.drawable.frame_animation); AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getDrawable(); animationDrawable.start();//启动 animationDrawable.stop();//停止

补间动画(Tween Animation)

补间动画也可以叫视图动画(View Animation),只有View类型可以使用。通过对视图的初始状态和结束状态进行定义,然后系统自动计算补足中间的过渡动画效果。补间动画可以实现平移(Translate)、旋转(Rotate)、缩放(Scale)和透明度变化(Alpha)这四种基本变换,也可以将这些变换组合使用。通常用于简单的动画效果,但不适合更复杂的场景。

注意:补间动画是基于视觉呈现的改变,并不会改变view的实际属性

用xml文件描述补间动画

在res下创建anim文件夹,并创建xml文件,根元素使用set,可以创建一个补间动画的集合。set之下可以声明透明度、缩放、位移、旋转等效果:

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <alpha android:duration="1000" android:fromAlpha="0.0" android:toAlpha="1.0" /> <scale android:duration="1000" android:fromXScale="1.0" android:fromYScale="1.0" android:pivotX="50%" android:pivotY="50%" android:startOffset="1000" android:toXScale="2.0" android:toYScale="2.0" /> <translate android:duration="2000" android:fromXDelta="30" android:fromYDelta="30" android:startOffset="2000" android:toXDelta="-80" android:toYDelta="300" /> <rotate android:duration="3000"++ android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:startOffset="4000" android:toDegrees="+350" /> </set>

在java代码中关联View

Animation animation = AnimationUtils.loadAnimation(this, R.anim.animation_set); imageView.startAnimation(animation);

属性描述

  1. 定义视图的透明度变化动画:
    1. android:duration="1000":动画的持续时间为 1000 毫秒(1 秒)。
    2. android:fromAlpha="0.0":设置视图的初始透明度为 0.0,也就是完全透明的状态。
    3. android:startOffset="0":0表示这个透明度变化动画没有延迟,会立即开始执行。
    4. android:toAlpha="1.0":定义视图的最终透明度为 1.0,意思就是1秒钟内从完全透明到不透明。
  2. 定义缩放动画效果:
    • android:duration="1000":持续时间为 1000 毫秒。
    • android:fromXScale="1.0"和android:fromYScale="1.0":分别设置视图在 X 轴和 Y 轴方向上的初始缩放比例为 1.0,也就是原始大小。
    • android:pivotX="50%"和android:pivotY="50%":缩放中心点位于视图的中心位置(50% 表示相对视图自身的中心位置)。
    • android:startOffset="1000":让缩放效果有 1000 毫秒的延迟。
    • android:toXScale="2.0"和android:toYScale="2.0":定义视图在 X 轴和 Y 轴方向上的最终缩放比例为 2.0,放大到两倍。
  • 定义视图的平移动画:
    • android:duration="2000":持续时间为 2000 毫秒。
    • android:fromXDelta="30"和android:fromYDelta="30":视图在 X 轴和 Y 轴方向上的初始位移量,这里是从相对于原始位置在 X 轴正方向移动 30 像素、在 Y 轴正方向移动 30 像素的位置开始。
    • android:startOffset="2000":2000 毫秒(2 秒)的延迟。
    • android:toXDelta="-80"和android:toYDelta="300":分别定义视图在 X 轴和 Y 轴方向上的最终位移量,即最终会在 X 轴负方向移动 80 像素、在 Y 轴正方向移动 300 像素。
  • 定义视图的旋转动画:
    • android:duration="3000":指定旋转动画的持续时间为 3000 毫秒。
    • android:fromDegrees="0":设置视图的初始旋转角度为 0 度。
    • android:pivotX="50%"和android:pivotY="50%":旋转中心点位于视图的中心位置(50% 表示相对视图自身的中心位置)。
    • android:startOffset="4000":表示这个旋转动画会有 4000 毫秒(4 秒)的延迟,在其他动画开始 4 秒后才开始执行。
    • android:toDegrees="+350":绕中心点顺时针旋转 350 度。

用Java描述补间动画

// 透明度动画 AlphaAnimation alphaAnimator = new AlphaAnimation(0f, 1f); alphaAnimator.setDuration(1000); // 缩放动画 ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, // 起始X轴缩放比例 2.0f, // 结束X轴缩放比例 1.0f, // 起始Y轴缩放比例 2.0f, // 结束Y轴缩放比例 Animation.RELATIVE_TO_SELF, 0.5f, // 缩放中心点X轴,相对于视图自身的50%位置 Animation.RELATIVE_TO_SELF, 0.5f // 缩放中心点Y轴,相对于视图自身的50%位置 ); scaleAnimation.setDuration(1000); scaleAnimation.setStartOffset(1000); //位移 TranslateAnimation translateAnimation = new TranslateAnimation(30f, -80f, 30f, 300f); translateAnimation.setDuration(2000); translateAnimation.setStartOffset(2000); //旋转 RotateAnimation rotateAnimation = new RotateAnimation(0f, 350f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); rotateAnimation.setDuration(3000); rotateAnimation.setStartOffset(4000); //使用一个动画集合装载 AnimationSet animationSet = new AnimationSet(true); animationSet.addAnimation(alphaAnimator); animationSet.addAnimation(scaleAnimation); animationSet.addAnimation(translateAnimation); animationSet.addAnimation(rotateAnimation); //关联view view.startAnimation(animationSet);

单独为某个动画效果设置重复效果,注意,虽然AnimationSet也有设置重复的方法,但AnimationSet的重复不生效:

rotateAnimation.setRepeatCount(3);//重复次数为3次,-1为无限循环 //重复的效果和之前一样,如果是REVERSE那指的就是反向效果 rotateAnimation.setRepeatMode(Animation.RESTART);

添加动画监听:

//为整个集合添加监听,同时也可以单独为某个动画添加 animationSet.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { // 整个动画集开始时执行的代码 } @Override public void onAnimationEnd(Animation animation) { // 整个动画集结束时执行的代码 } //注意:animationSet直接设置重复,是不会生效的。只有单独的Animation效果才会让重复生效 @Override public void onAnimationRepeat(Animation animation) { // 整个动画集重复时执行的代码(如果设置了重复) } });

属性动画(Property Animation)

属性动画,是安卓在 API 11 (Android 3.0) 引入的一个动画框架。和视图动画不一样。可以改变对象的真实属性值,不仅仅是视图效果。它适合构建复杂的动画场景。是目前 Android 动画系统中最常用的方式。

属性动画主要有以下三个核心类:ValueAnimator、ObjectAnimator、AnimatorSet

ValueAnimator

提供一组动态变化的值,借助值的变化,动态改变一些View或者非 View 的属性动画,特别是在需要动态计算或平滑过渡数值的地方。

常见用法

  1. 透明度

//创建 ValueAnimator valueAnimator = ValueAnimator.ofInt(0,500); valueAnimator.setDuration(1000); //添加动画值更新回调 valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(@NonNull ValueAnimator animation) { float animatedValue = (float) animation.getAnimatedValue(); imageView.setAlpha(animatedValue); Log.i(TAG, "onAnimationUpdate: animatedValue = " + animatedValue); } }); //在必要的时候启动 valueAnimator.start();

  1. 颜色渐变

//指定颜色变化的初始和结束值,让颜色从红色渐变到蓝色 ValueAnimator colorAnimator = ValueAnimator.ofArgb(Color.RED, Color.BLUE); // 从红色渐变到蓝色 colorAnimator.setDuration(2000); colorAnimator.addUpdateListener(animation -> { int color = (int) animation.getAnimatedValue(); imageView.setBackgroundColor(color); // 设置背景颜色 }); colorAnimator.start();

  1. 平滑过渡数据变化

ValueAnimator animator = ValueAnimator.ofInt(0, 1000); // 动态从 0 增长到 1000 animator.setDuration(10000); animator.addUpdateListener(animation -> { int value = (int) animation.getAnimatedValue(); textView.setText(String.valueOf(value)); // 实时更新数值显示 });

  1. 改变Y轴坐标

ValueAnimator animator = ValueAnimator.ofFloat(0, 1000); // 从高度 0 下落到 1000 animator.setInterpolator(new BounceInterpolator()); // 添加弹跳效果 animator.setDuration(3000); animator.addUpdateListener(animation -> { float position = (float) animation.getAnimatedValue(); view.setTranslationY(position); // 改变物体的 Y 坐标 }); animator.start();

ObjectAnimator

基于ValueAnimator,使用的时候传入一个View对象,可以直接对View的一些属性进行设置,帮助开发者快速实现一些平滑的效果。

常见用法

  1. 动画改变 View 的透明度

ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f); // 从完全可见到完全透明 animator.setDuration(1000); // 动画时长 1 秒 animator.start();

  1. 动画改变 View 的平移位置

ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationX", 0f, 300f); // 从原始位置移动到右侧 300px animator.setDuration(1000); animator.start();

  1. 动画改变 View 的旋转角度

ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f); // 顺时针旋转一圈 animator.setDuration(1000); animator.start();

  1. 动画改变 View 的缩放

ObjectAnimator animator = ObjectAnimator.ofFloat(view, "scaleX", 1f, 1.5f); // 水平方向放大 1.5 倍 animator.setDuration(1000); animator.start(); //或者同时设置X、Y的缩放 ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1f, 1.5f); ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1f, 1.5f); AnimatorSet set = new AnimatorSet(); set.playTogether(scaleX, scaleY); // 同时播放缩放动画 set.setDuration(1000); set.start();

  1. 动画改变 View 的背景颜色

ObjectAnimator animator = ObjectAnimator.ofArgb(view, "backgroundColor", Color.RED, Color.BLUE); // 从红色到蓝色 animator.setDuration(1000); animator.start();

  1. 组合多个动画,实现复杂动画,比如同时缩放、移动和旋转。

ObjectAnimator move = ObjectAnimator.ofFloat(view, "translationX", 0f, 300f); ObjectAnimator rotate = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f); ObjectAnimator scale = ObjectAnimator.ofFloat(view, "scaleX", 1f, 1.5f); AnimatorSet set = new AnimatorSet(); set.playTogether(move, rotate, scale); // 同时播放所有动画 set.setDuration(1000); set.start();

  1. 改变 TextView 的文字颜色

ObjectAnimator animator = ObjectAnimator.ofArgb(textView, "textColor", Color.BLACK, Color.RED); // 从黑色到红色 animator.setDuration(1000); animator.start();

  1. 改变 View 的路径运动

Path path = new Path(); path.moveTo(0f, 0f); // 起点 path.lineTo(300f, 300f); // 移动到点 (300, 300) path.lineTo(600f, 0f); // 移动到点 (600, 0) ObjectAnimator animator = ObjectAnimator.ofFloat(view, "x", "y", path); animator.setDuration(2000); animator.start();

  1. 动画改变自定义对象属性

注意:自定义类里面需要实现对应的setter方法,这样ObjectAnimator才能通过反射机制寻找到对应的参数

public class Point { private float x; public void setX(float x) { this.x = x; Log.d("Point", "X: " + x); } } //使用 ObjectAnimator,改变Point自定义类中的x: Point point = new Point(); ObjectAnimator animator = ObjectAnimator.ofFloat(point, "x", 0f, 100f); // 改变 Point 的 X 值 animator.setDuration(1000); animator.start();

  1. 循环动画

ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f); // 旋转一圈 animator.setDuration(1000); animator.setRepeatCount(ValueAnimator.INFINITE); // 无限循环 animator.setRepeatMode(ValueAnimator.RESTART); // 每次从头开始 animator.start();

  1. 配置插值器(Interpolator), 设置动画节奏,例如减速、弹跳等。

ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationY", 0f, 300f); // 垂直移动 animator.setDuration(1000); animator.setInterpolator(new BounceInterpolator()); // 添加弹跳效果 animator.start();

  1. 使用 PropertyValuesHolder 同时改变同一个view的多个属性。

PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1f, 1.5f); PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1f, 1.5f); ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view, scaleX, scaleY); // 同时缩放 animator.setDuration(1000); animator.start();

过渡动画

过渡动画(Transition Animation)是 Android 提供的一种机制,用于在两个界面状态之间切换时为 UI 元素添加动态效果,使界面过渡更加平滑和美观。过渡动画主要应用于 Activity/Fragment 的切换、视图元素的显示/隐藏 或 状态改变 等场景。

常见用法

1. Activity 过渡动画

  • 通过代码设置:使用 overridePendingTransition() 方法,为 Activity 的进入和退出指定动画。
  • 使用的时候需要分别指定进入、退出的Activity效果。一般在startActivity或者finish的时候使用。

Intent intent = new Intent(this, SecondActivity.class); startActivity(intent); overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);

res/anim/slide_in_right.xml

<translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="100%" android:toXDelta="0%" android:duration="300" />

res/anim/slide_out_left.xml

<translate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="300" android:fromXDelta="0%" android:toXDelta="-100%" />

2. Fragment 过渡动画

  • 设置 Fragment 切换动画:

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.setCustomAnimations( R.anim.enter_from_right, // Fragment 进入动画 R.anim.exit_to_left, // Fragment 退出动画 R.anim.enter_from_left, // Fragment 返回时的进入动画 R.anim.exit_to_right // Fragment 返回时的退出动画 ); transaction.replace(R.id.container, new SecondFragment()); transaction.addToBackStack(null); transaction.commit();

3. 共享元素过渡动画(Shared Element Transition)

  • 适用于:两个 Activity 或 Fragment 之间的共享 UI 元素的动画。
  • 实现步骤:
    1. 在源和目标布局中,为共享的视图设置相同的 transitionName。

<ImageView android:id="@+id/imageView" android:layout_width="100dp" android:layout_height="100dp" android:transitionName="sharedImage" /> <!-- 目标布局 --> <ImageView android:id="@+id/imageView" android:layout_width="200dp" android:layout_height="200dp" android:transitionName="sharedImage" />

    1. 启动目标 Activity 时,使用 ActivityOptionsCompat:

Intent intent = new Intent(this, SecondActivity.class); ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation( this, imageView, // 共享的视图 "sharedImage" // 对应的 transitionName ); startActivity(intent, options.toBundle());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值