android 动画详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wk_beicai/article/details/79407674

 我们在开发时,很多地方会应用到动画,安卓为我们提供很多种动画方式,下面介绍android为我们提供的动画。害羞

1.android 动画分为三种:补间动画,帧动画,属性动画
(属性动画为API 11 新特性)
2.1补间动画的种类
1)TranslateAnimation(平移动画):
2)ScaleAnimation (缩放动画)
3) RoateAnimation (旋转动画)
4)AlphaAnimation(透明动画)、
它们都是Animation的子类;
2.2 固定语法:

2.3 标签的介绍:

<set> : 动画的集合,对应animationSet类,可以包含若干个动画;
android:shareInterpolator:
表示动画是否和集合共享一个差值器,如果集合不指定差值器,子动画就需要单独制定
所需要的差值器或者默认值
<translate>: 表示平移动画,对应TransAnimation类,
属性含义:
fromXDelta ------ 表示X的起始值,比如0
toXDelta -------- 表示X的结束值,比如100
fromYDelta ------ 表示Y的起始值;
toYDelta -------- 表示Y的结束值
<scale> : 表示缩放动画, 对应ScaleAnimation,放大和缩小的效果;
属性含义:
fromXScale ----- 表示水平缩放的起始值 例如0.5;
toXScale -------- 表示水平缩放的结束值, 比如1.2;
fromYScale ------ 竖直方向缩放的起始值
toYScale ------- 竖直方向的结束值
pivotX --------- 缩放的轴点x坐标,他会影响缩放效果
pivotY --------- 缩放的轴点y坐标,他会影响缩放效果
<rotate> 表示旋转动画 对应于RotateAnimation, 使view具有旋转效果
fromDegrees ---- 旋转的开始角度
toDegrees ----- 旋转的结束角度
pivotX --------- 旋转的轴点x坐标
pivotY ------- 旋转轴点的Y轴坐标
<alpha> 表示透明度动画 对应AlphaAnimation, 改变view的透明度
fromAlpha --- 表示透明度的起始值 比如0.1
toAlpha ---- 表示透明度的结束值 比如1

duration ----- 动画的持续时间
fillAfter ------ 动画结束后是否停留结束位置,true表示停留在结束位置,false则不停留

2.4 如何应用上面的动画:
方式一: 在xml布局中定义动画效果

方式二: 在代码中应用动画效果,

3.1 自定义view的动画;
派生一种新动画只需要继承Animation这个抽象类,然后重写initialize和applyTransformation
方法,在initialize方法中做一些初始化的工作,在applyTransformation中进行相应矩阵变化。
很多时候需要采用Camera来简化矩阵变化过程,
自定义view复杂的地方在于,自定义view动画的过程主要是矩阵变化的过程,而矩阵变化是数学上的概念,实现过程比较复杂。
4.1帧动画
帧动画是顺序播放一组事先定义好的图片,类似于电影播放,
系统提供另外一个类AnimationDrawable来使用帧动画,
使用举例:
在代码中使用:

view是你的组件(button。。。)

5.1 view动画的特殊性:
1.LayoutAnimation 作用于ViewGroup,为ViewGroup指定一个动画,这样当他的子元素出场时会有动画效果。(listView)
为viewGroup添加出场效果:
1)定义LayoutAnimation

属性的含义:
delay:表示子元素开始动画的时间延迟,(例如子元素入场动画周期300ms 0.5就表示子元素需要延时150ms)
animationOrder: 表示子元素动画顺序,有三种
1)mormal :表示顺序显示
2)reverse: 表示逆向显示
3)random: 表示随机播放入场动画
animation : 表示要加载哪个动画

2.为子元素指定入场动画

3.为viewGroup指定layoutAnimation属性,

除了在xml中指定LayoutAnimation外,还可以在LayoutAnimationController来实现

5.2 activity的切换效果
Activity有默认的切换效果,但是这个效果我们可以自定义,
overridePendingTransition(int enterAnim,int exitAnim);这个方法,
这个方法必须在startActivity()或者finish()之后调用才能生效。
属性含义:
enterAnim: Activity被打开时(相当于进入的activity),
exitAnim : activity被暂停时(被移除的Activity);
当启动一个Activity时,

当activity退出时,

Fragment也可以添加切换动画,由于Fragment是在API 11中新引入的类,因此需要使用v4包。
这种情况我们可以通过FragmentTransction中setCustomAnimations()来切换动画;
在低版本中无法使用,不具有很高的使用价值;

6.1 属性动画:
补间动画和帧动画的缺陷:
1)他们只能作用在View的视图上,无法在非View的对象进行操作。
2)没有改变view的属性,只改变view对象的效果;
3)动画效果单一,只有平移,旋转等效果。

6.2 属性动画
属性动画弥补了这些不足,效果上不单单就那四种,作用对象也进行了扩展。
不只是view对象,甚至没有对象也可以。

6.3 属性动画的工作原理
在一定时间间隔内,通过改变值,并将值赋值到属性或者对象上来改变动画效果

具体的工作原理:
先设置动画运行时间,动画对应的属性初始值和结束值。
通过差值器和估值器来设置属性值从初始值到结束值的变化逻辑
根据上述的逻辑不断的改变值,每改动一次,就赋值给对象属性值一次,
(通过手动和自动的两种方式:)
每次赋值调用invalidate()不断刷新视图,
不断的重复直到初始值等于结束值,动画结束

6.4 ValueAnimator类
控制值的变化,不断的手动赋值给对象属性,从而实现动画效果。
ValueAnimator类中有三个重要方法
1)ValueAnimator.ofInt(int values);
作用:将初始值以int整数值的形式过渡到结束值
使用:可以分为XML java代码两种方式;
在实际开发中建议使用java代码实现属性动画,因为起始值我们是无法提前确定的。
案例:将button 宽度从150-800动画效果的展示
1.1 java代码的实现
//属性动画实现的功能
private void PropertyAnimation() {
//步骤一
//设置动画属性的初始值和结束值
ValueAnimator anim = ValueAnimator.ofInt(btn.getLayoutParams().width,800);
//步骤二
//设置动画播放的各种属性
//设置动画的播放时间长度
anim.setDuration(5000);
//设置动画的延时时间长度、
anim.setStartDelay(500);
//设置动画的播放次数
//动画播放次数=infinlte时,重复无限播放
anim.setRepeatCount(0);
//设置重复播放动画模式
//REVERSE(倒叙播放)
//RESTART(默认 正序重复)
anim.setRepeatMode(ValueAnimator.RESTART);
//步骤三
//将改变的值手动赋值给对象和属性
//设置动画的更新监听,值每改变一次,就调用一次监听
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//获得改变后的值
int curr =(Integer) animation.getAnimatedValue();
//步骤四 将改变的值赋值给对象和属性
btn.getLayoutParams().width=curr;
//步骤五 刷新视图 重新绘制 完成动画
btn.requestLayout();
}
});
anim.start();
}
1.2 xml布局的实现

在java代码中启动动画
Animator animator = AnimatorInflater.loadAnimator(context, R.animator.set_animation); // 载入XML动画animator.setTarget(view); // 设置动画对象animator.start(); // 启动动画

2) ValueAnimator。oFloat(float value);
将初始值以浮点型的形式过渡到结束值
使用方法同上,只是在差值器上过渡的类型不同
3)估值器(TypeEvaluator)
设置动画如何从初始值过渡到结束值的逻辑
差值器(Interpollator) 决定值的变化模式(匀速 加速blabla)
估值器决定值的具体变化数值
valueAnimator.ofInt(),Value.oFloat()都有默认值,都具备系统内置的估值器
但是ValueAnimator.ofObject(),由于对象动画复杂多样化,系统无法知道如何从初始对象过渡到结束对象,所以没有默认估值器,所以我们需要自定义估值器。
4)valueAnimator.ofObject();
将初始值以对象的形式过渡到结束值
如何自定义?
我们
实现TypeEvaluator接口,重写evaluate()方法,
evaluate()方法参数说明;
1)fration: 动画的完成度(根据计算当前动画值)
2)startValue endValue: 动画的初始值和结束值
实现对象动画过渡逻辑
将对象动画过渡的逻辑计算后的值返回。
案例:实现动画效果:一个圆从一个点移动到另一个点
实现步骤;
步骤一:定义对象类
ValueAnimator.ofObject() 需要自定义对象类
该对象操作圆的点的坐标
步骤二:自定义估值器 实现TypeEvaluator接口
实现如何从初始点坐标过渡到结束点坐标
步骤三:将属性动画作用到自定义view上
步骤四:在布局文件中加入自定义view控件

7.1 ObjectAnimator类
可以直接对对象属性进行改变操作完成动画效果;
1)直接改变view的alpha属性实现透明度效果
2)继承自ValueAnimator类,实现基于ValueAnimator类的动画效果
ObjectAnimator与ValueAnimator类的区别:
ValueAnimator类,先改变值,手动的赋值给对象的属性实现动画,间接对对象属性进行操作。
ObjectAnimator类先改变值,自动的赋值给对象的属性实现动画,直接对对象进行操作;、
7.2 使用:
由于继承ValueAnimator类,实现方法十分类似
1.创建对象实例
ObjectAnimator animator = ObjectAnimator.ofFloat( Object object , String property , float ....values);
参数
说明:
Object: 需要操作的对象
property: 需要操作对象的属性
vlaues:设置初始值和结束值
7.3 实现案例
1)透明度:
ObjectAnimator animator = ObjectAnimator.ofFloat(mButton, "alpha", 1f, 0f, 1f); // 表示的是: // 动画作用对象是mButton // 动画作用的对象的属性是透明度alpha // 动画效果是:常规 - 全透明 - 常规 animator.setDuration(5000); animator.start();
2)旋转 ObjectAnimator animator = ObjectAnimator.ofFloat(mButton, "rotation", 0f, 360f); // 表示的是: // 动画作用对象是mButton // 动画作用的对象的属性是旋转alpha // 动画效果是:0 - 360 animator.setDuration(5000); animator.start();
3)平移
float curTranslationX = mButton.getTranslationX(); // 获得当前按钮的位置 ObjectAnimator animator = ObjectAnimator.ofFloat(mButton, "translationX", curTranslationX, 300,curTranslationX); // 表示的是: // 动画作用对象是mButton // 动画作用的对象的属性是X轴平移(在Y轴上平移同理,采用属性"translationY" // 动画效果是:从当前位置平移到 x=1500 再平移到初始位置 animator.setDuration(5000); animator.start();
4)缩放
ObjectAnimator animator = ObjectAnimator.ofFloat(mButton, "scaleX", 1f, 3f, 1f); // 表示的是: // 动画作用对象是mButton // 动画作用的对象的属性是X轴缩放 // 动画效果是:放大到3倍,再缩小到初始大小 animator.setDuration(5000); animator.start();

5)自定义属性动画效果
实现的效果:一个圆的颜色渐变
实现步骤:
1)设置对象属性的get()set()方法
通过
1.集成原始类,直接给类加上该属性的get(),set(),从而实现给对象加上该属性的get,set
2.通过包装原始动画,间接给对象加上该属性的get,set(用一个类来包装原始对象)
2)在布局文件中加入自定义控件
3)根据需要实现TypeEvaluator接口(估值器)
4)调用ObjectAnimator。ofObject();

通过包装类,间接给对象加上该属性的get,set
public class MainActivity extends AppCompatActivity { Button mButton; ViewWrapper wrapper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButton = (Button) findViewById(R.id.Button); // 创建动画作用对象:此处以Button为例 wrapper = new ViewWrapper(mButton); // 创建包装类,并传入动画作用的对象 mButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ObjectAnimator.ofInt(wrapper, "width", 500).setDuration(3000).start(); // 设置动画的对象是包装类的对象 } }); } // 提供ViewWrapper类,用于包装View对象 // 本例:包装Button对象 private static class ViewWrapper { private View mTarget; // 构造方法:传入需要包装的对象 public ViewWrapper(View target) { mTarget = target; } // 为宽度设置get() & set() public int getWidth() { return mTarget.getLayoutParams().width; } public void setWidth(int width) { mTarget.getLayoutParams().width = width; mTarget.requestLayout(); } }}

8.1 属性动画的监听事件
Animation.addListener(new AnimatorListener() { @Override public void onAnimationStart(Animation animation) { //动画开始时执行 } @Override public void onAnimationRepeat(Animation animation) { //动画重复时执行 } @Override public void onAnimationCancel()(Animation animation) { //动画取消时执行 } @Override public void onAnimationEnd(Animation animation) { //动画结束时执行 } });
//需要注意的是每一次监听,四个方法必须都得重写

9.1 组合动画
当我们需要同时使用多种动画效果时,我们使用组合动画AnimationSet类
paly : 播放当前动画
alter(Long delay) 延迟执行动画
with : 当前动画和传入的动画同时执行
after: 将现有的动画插入到传入动画的后边执行
before : 将现有的动画插入到传入动画之前执行

java代码的实现
// 步骤1:设置需要组合的动画效果ObjectAnimator translation = ObjectAnimator.ofFloat(mButton, "translationX", curTranslationX, 300,curTranslationX); // 平移动画ObjectAnimator rotate = ObjectAnimator.ofFloat(mButton, "rotation", 0f, 360f); // 旋转动画ObjectAnimator alpha = ObjectAnimator.ofFloat(mButton, "alpha", 1f, 0f, 1f); // 透明度动画// 步骤2:创建组合动画的对象AnimatorSet animSet = new AnimatorSet(); // 步骤3:根据需求组合动画animSet.play(translation).with(rotate).before(alpha); animSet.setDuration(5000); // 步骤4:启动动画animSet.start();
android的动画讲解就这么多了,希望对大家有所帮助, 吐舌头

猜你喜欢

转载自blog.csdn.net/wk_beicai/article/details/79407674