导语
Android的动画框架包括帧动画、视图动画(又叫补间动画)、属性动画。在Android3.0之前,视图动画一家独大,但随之后属性动画框架被推出。相比属性动画,视图动画一个非常大的缺陷就是不具备交互性。当某个元素发生视图动画后,其响应事件的位置还依然在动画前的地方,所以视图动画只能做普通的动画效果,避免交互发生,且效率较高使用方便。
Animation框架定义了透明度(alpha)、旋转(rotate)、缩放(scale)、位移(translate)四种常见的动画,而且是控制整个View的显示效果。
当View被执行视图动画,每次重复绘制该视图时,View 所在的 ViewGroup 中的 drawChild 函数获取该View的Animation的Transformation(改变值),然后调用 canvas.concat(transformToApply.getMatrix()) ,通过矩阵运算成功画帧。如果动画没有完成,就继续调用 invalidate() 函数,启动下次绘制来驱动动画,从而完成整个动画的绘制。
——————————————————————————————————————
·invalidate| BrE ɪnˈvalɪdeɪt, AmE ɪnˈvæləˌdeɪt | transitive verb①(render void) 使…无效 ‹will, passport, judgement, marriage›; 使…作废 ‹ticket, contract›②(render unsound or erroneous) 证明…错误 ‹argument, conclusion›
——————————————————————————————————————
1、设置View透明度:
AlphaAnimation aa=new AlphaAnimation(0,1);
aa.setDuration(1000);
view.startAnimation(aa);
2、设置View旋转:
RotateAnimation ra = new RotateAnimation(
0,360, RoatateAnimation.RELATIVE_TO_SELF,0.5F,RoatateAnimation.RELATIVE_TO_SELF,0.5F);
ra.setDuration(1000);
view.startAnimation(ra);
3、设置View缩放:
ScaleAnimation sa = new ScaleAnimation(
0,1,0,1,RoatateAnimation.RELATIVE_TO_SELF,0.5F,RoatateAnimation.RELATIVE_TO_SELF,0.5F);
sa.setDuration(1000);
view.startAnimation(sa);
4、设置View位移动画:
TranslateAnimation ta=new TranslateAnimation(0,200,0,300);
ta.setDuraton(1000);
view.startAnimation(ta);
5、设置View动画集合:
AnimationSet as =new AnimationSet(true);
as.setDuration(1000);
AlphaAnimation aa=new AlphaAnimation(0,1);
aa.setDuration(1000);
as.addAnimation(aa);
TranslateAnimation ta=new TranslateAnimation(0,200,0,300);
ta.setDuraton(1000);
as.addAnimation(ta);
view.startAnimation(as);
animation.setAnimationListener(new Animation.AnimationListener(){
@Override
public void onAnimationStart(Animation animation){//动画开始执行
}
@Override
public void onAnimationEnd(Animation animation){//动画执行结束
}
@Override
public void onAnimationRepeat(Animation animation){
//动画重复执行时调用
}
});
ObjectAnimator animator=ObjectAnimator.ofFloat(view,"translationX",300);
animator.setDuration(300);
animator.start();
注意,在使用ObjectAnimator的时候,有一点是非常重要的。那就是要操纵属性必须具有get 和 set方法,不然ObjectAnimator就无法起效。
1、translationX和translationY:
这两个属性作为一种增量来控制着View对象从它布局容器的左上角坐标偏移的位置。
2、rotation/rorationX和rorationY:
这三个属性控制View对象围绕支点进行2D和3D旋转。
3、scaleX和scaleY:
这两个属性控制着View对象围绕它的支点进行2D缩放。
4、pivotX和privotY:
这两个属性控制着View对象的支点位置,围绕这个支点进行旋转和缩放变换处理。默认情况下该支点就是View对象中心点。
5、x和y:
这是两个简单实用的属性,它描述了View对象在它的容器中的最终位置,它是最初的左上角坐标和translationX/translationY值的累积和。
6、alpha:
它表示View对象的alpha透明度。默认值1(不透明),0代表完全透明(不可见)。
ObjectAnimator anima =ObjectAnimator.ofFloat(View,"alpha",0.5f);
anima.addListener(new AnimatorListener(){
@Overrider
public void onAnimationStart(Animator animation){
//开始
}
@Overrider
public void onAnimationRepeat(Animator animation){
//重复
}
@Overrider
public void onAnimationEnd(Animator animation){
//结束
}
@Overrider
public void onAnimationCancel(Animator animation){
//取消
}
});
anima.start();
选择性进行监听:
anima.addListener(new AnimatorListenerAdapter(){
@Override
public void onAnimationEnd(Animator animation){
//结束
}
});
ObjectAnimator animator1 =ObjecteAnimator.ofFloat(view,"translation",300f);
ObjectAnimator animator1 =ObjecteAnimator.ofFloat(view,"scaleX",1);
ObjectAnimator animator1 =ObjecteAnimator.ofFloat(view,"scaleY",1);
AnimatorSet set=new AnimatorSet();
set.setDuration(1000);
set.playTogether(animator1,animator2,animator3);//一起播放动画
set.start();
在属性动画中,AnimatoSet 可以通过 playTogether()、playSequentially()、animSet.play().with()、before()、after()这些方法来控制多个动画的协同工作方式,从而做到对动画播放顺序的精确控制。
applyTransformation(float interpolatedTime ,transformation t)
————————————————————————————————
transformation| BrE ˌtransfəˈmeɪʃ(ə)n,ˌtrɑːnsfəˈmeɪʃ(ə)n,ˌtranzfəˈmeɪʃ(ə)n,ˌtrɑːnzfəˈmeɪʃ(ə)n, AmE ˌtræn(t)sfərˈmeɪʃ(ə)n | noun①countable(change) 变化 ▸ the change in his appearance was a real transformation! 他看上去真是判若两人! ②uncountable(action) 改变 ③uncountablePhysics 形态变化 ④countableMathematics 变换 ————————————————————————————————
如效果图,先通过模拟电视机关闭效果的动画来初步了解自定义动画。代码实现如下:
/**
* Created by aiyang on 2018/5/28.
*/
public class CustomTV extends Animation {
private int mCenterWidth;
private int mCenterHeight;
private float mRotateY=0.0f;
private Camera camera=new Camera();
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
//设置默认时长
setDuration(2000);
//动画结束后保留状态
setFillAfter(false);
setRepeatCount(3);
//设置默认插值器
setInterpolator(new AccelerateInterpolator());
mCenterWidth=width/2;
mCenterHeight=height/2;
}
//暴露接口,设置旋转角度
public void setRotateY(float rotateY){
mRotateY=rotateY;
}
/**
* @param interpolatedTime 插值器的时间因子,这个因子是由动画当前完成的百分比和当前时间所对应的插值所计算得来的,取值范围为0到1.0
* @param t 它是矩阵的封装类,一般使用这个类来获取当前的矩阵对象
*/
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final Matrix matrix=t.getMatrix();
//让一个图像纵向比例不断缩小就能实现电视机关闭的效果
matrix.preScale(1,1-interpolatedTime,mCenterWidth,mCenterHeight);
}
}
CustomTV tv = new CustomTV();
textview.setText("关闭电视");
textview.startAnimation(tv);
实现代码如下:
/**
* Created by aiyang on 2018/5/28.
*/
public class CustomAnim extends Animation {
private int mCenterWidth;
private int mCenterHeight;
private Camera mCamera = new Camera();
private float mRotateY = 0.0f;
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
// 设置默认时长
setDuration(3000);
// 动画结束后保留状态
setFillAfter(true);
setRepeatCount(3);
// 设置默认插值器
setInterpolator(new BounceInterpolator());
mCenterWidth = width / 2;
mCenterHeight = height / 2;
}
//暴露接口,设置旋转角度
public void setRotateY(float rotateY){
mRotateY=rotateY;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final Matrix matrix=t.getMatrix();
mCamera.save();
//使用Camera设置旋转的角度
mCamera.rotateY(mRotateY*interpolatedTime);
//将旋转变换作用到Matrix上
mCamera.getMatrix(matrix);
mCamera.restore();
//通过pre方法设置矩阵作用前的偏移量来改变旋转中心
matrix.preTranslate(mCenterWidth,mCenterHeight);
matrix.postTranslate(-mCenterWidth,-mCenterHeight);
}
}
CustomAnim anim = new CustomAnim();
anim.setRotateY(10);
textView.setText("推开门");
textView.startAnimation(anim);
————————欢迎入群————————