android-一步一步实现三种动画_android动画实现
目录
帧动画
补间动画
透明度:
旋转
缩放
平移
属性动画
通过ValueAnimator实现属性动画
通过ObjectAnimator来实现
通过AnimatorSet实现多动画组合
动画监听器
动画插值器
三种动画的使用场景和总结
帧动画
什么是帧动画?
在 Android 中,帧动画(Frame Animation) 是通过快速切换一系列静态图片帧,来制造动画效果的方式,类似于翻页书或 GIF 动图。
实现方式如下:
可以看到我在项目的drawable目录下有这几张图片:
因为想把几张图片连到一起,这里引入一个集合: animation-list
因为帧动画可以看做一张图片,所以还是在drawable目录下新建一个frame
的xml文件,在文件中利用android:drawable
来写对应的图片,利用android:duration
来设定对应每一帧的播放时间,这里的单位是毫秒,代码如下:
这里说明:帧动画的每一帧是图片,图片属于位图资源,那么帧动画自然属于drawable(可绘制资源了)
但是视频,是属于媒体资源,存放在res/raw目录下
然后在activity_main.xml文件中加入图片的控件:
最后我们在主活动中,设置帧动画的点击事件,点击开始播放帧动画,关闭即停止;
这里我们先根据ID获取布局中控件的对象,然后利用getDrawable()
方法来获取图片资源,把图片资源强转成帧动画,最后设置控件的监听事件,利用变量pd通过帧动画的对象调用start
和stop
方法来达到我们的目标效果;
ImageView viewById = (ImageView)findViewById(R.id.iv); AnimationDrawable drawable = (AnimationDrawable)viewById.getDrawable(); viewById.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(pd){ drawable.start(); pd = false; } else{ pd = true; drawable.stop(); } } });
优点:可做出非常丰富的视觉效果;
缺点:图片资源多,体积大,消耗内存和存储空间,灵活性差;
补间动画
补间动画是通过指定 起始状态和结束状态,系统自动计算中间帧并播放出来,实现动画效果的一种方式。
原理:补间动画通过计算动画开始和结束状态之间的中间帧,并把计算的结果应用于视图的显示层,实际上它只改变视图的绘制效果(如位置、大小、透明度等),不改变控件的真实属性;
通俗来说,就是设置动画的初始和结束状态以及动画时间,让计算机自动补全过程的动画;
补间动画有四种方式:
-
alpha --透明度
-
rotate --旋转
-
scale --缩放
-
translate --平移
透明度:
首先我们在activity_main.xml文件中设置我们想要看到的图片
然后在创建一个res目录下的文件夹:anim
然后创建alpha的xml文件,在这个文件中设定我们想要的动画属性,一般来说,补间动画有三种需要设置:初始的状态,结束状态,以及持续的过程。这里我们还看到set根节点,然后在alpha标签中设置属性:duration设置事件,fromAlpha,toAlpha设置开始结束的透明度,透明度从0-1依次降低
最后在主活动中:
获得控件的对象,通过AnimationUtils类中的静态方法loadAnimation创建动画对象animation,参数有两个,第一个是启动活动的上下文,第二个是动画的设置,我们传入R.anim.alpha,最后通过控件的startAnimation传入动画对象开启动画;
ImageView view = (ImageView)findViewById(R.id.iv); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.translate); view.startAnimation(animation); } });
后续大部分代码与透明度相同,这里不做演示,只说明不同部分
旋转
不同的部分是在anim目录下的xml文件中,这里fromto Degrees指的旋转的度数;pivotx,pivoty指的是旋转的位置,这里指的是中心
缩放
缩放的大小从1-0,1代表原始大小,0代表没有,fromXScale,toXScale分别代表开始和结束状态横坐标,y同理
平移
toXDelta,fromXDelta设置平移的开始结束的横坐标的位置,y同理,0代表初始位置,400代表400px
优点:兼容性好,性能开销低,适合简单动画;
缺点:复杂动画难以实现,灵活性差,没有改变控件的真实属性;
属性动画
这个动画很强大,灵活,我们来看看
通过ValueAnimator实现属性动画
什么是ValueAnimator
ValueAnimator
是 Android 中的一个动画类,用于在一段时间内产生数值的连续变化,你可以利用这些变化的数值去控制任何属性(透明度、位置、颜色等);而且还是属性动画的底层类;
我的理解是:ValueAnimator是根据过程中的数值的变化,比如我要求前1秒是一个动画,后一秒是另外一个动画,这里使用ValueAnimator就会更灵活,来控制我想要的属性;
实现:
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 1f); valueAnimator.setDuration(2000); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(@NonNull ValueAnimator valueAnimator) { float f = valueAnimator.getAnimatedFraction(); Log.e(\"leo\",\"onAnimationUpdate:\"+f); } }); valueAnimator.start();
-
通过ValueAnimtor的方法ofFloat,创建对象,参数是0到1,指的是这个过程中,数值会从0变到1;
-
通过这个对象,我们可以设置动画的时间,以及启动,分别是setDuration,start;
-
然后我们可以创建动画的监听器ddUpdateListener,这里指的是每一帧都会回调此方法;
-
通过getAnimatedFraction()方法可以获得动画的进度,返回一个float值
-
我们建议表示将值打印出来
最后打印出来是这个效果
通过ObjectAnimator来实现
TextView a = (TextView)findViewById(R.id.tv); ObjectAnimator alpha = ObjectAnimator.ofFloat(a, \"alpha\", 0f, 1f); alpha.setDuration(2000); alpha.start();
这里ObjectAnimator是对控件a,进行透明度在2秒内,因为是float,所以对透明度数值要+f;
然后设置其时间以及调用start方法实现控件a,透明度的变化;
ObjectAnimator是ValueAnimator的子类,直接操作对象的属性;
通过AnimatorSet实现多动画组合
TextView a = (TextView)findViewById(R.id.tv); ObjectAnimator alpha = ObjectAnimator.ofFloat(a, \"alpha\", 0f, 1f); ObjectAnimator t = ObjectAnimator.ofFloat(a, \"translationX\", 2f, 4f); AnimatorSet p = new AnimatorSet(); p.playTogether(alpha,t); p.start(); alpha.setDuration(2000); alpha.start();
动画监听器
动画监听器是用于监听动画生命周期的工具:通常使用 Animator.AnimatorListener
接口实现:
alpha.addListener(new Animator.AnimatorListener() { @Override public void onAnimationCancel(@NonNull Animator animator) { } @Override public void onAnimationEnd(@NonNull Animator animator) { } @Override public void onAnimationRepeat(@NonNull Animator animator) { } @Override public void onAnimationStart(@NonNull Animator animator) { } });
分别是动画被取消,动画结束,动画重复,动画开始时调用;
动画插值器
什么是插值器:
通俗来说,改变动画播放速度的;
LinearInterpolator
AccelerateInterpolator
DecelerateInterpolator
BounceInterpolator
AnticipateOvershootInterpolator
使用:
ObjectAnimator animator = ObjectAnimator.ofFloat(view, \"translationX\", 0f, 500f);animator.setDuration(1000);animator.setInterpolator(new BounceInterpolator()); // 设置弹跳效果animator.start();
优点:灵活性强,支持多个属性同时动画;
缺点:只支持 API 11 及以上版本;
三种动画的使用场景和总结
如何根据不同的需求去使用以上三种动画?
- 帧动画:类似播放一组连续帧图片的动画,适合表现复杂的动画序列。
- 补间动画:只是视觉上的变化,不改变控件真实属性(比如位置和大小仅表现上变了,点击区域没变);
- 属性动画:直接改变控件的属性(位置、透明度、旋转、颜色等),支持复杂动画组合;
另外补间动画对老版本比较包容,而属性动画灵活性强,仅支持API11以上;
参考视频:安卓三种动画