动画
2017-05-13 16:58
85 查看
每次绘制View时,ViewGroup中的drawChild函数获取该view的Animation的Transformation值,然后调用canvas.concat(transformToApply.getMatriX()),通过矩阵运算完成帧动画,如果动画没有完成,就继续调用invalidata()函数,启动下次绘制来驱动动画,从而完成整个动画的绘制
安卓动画主要有三类:逐帧动画(Drawable Animation、Frame Animation)、补间动画(View Animaiton、Tweened Animation)、属性动画(Property Animation),其中,View Animation只能修改View组件的部分属性、动画效果是绘制出来的,组件并没有真正改变,而Property Animation可以修改任何对象的任何属性,组件的状态也会跟着改变
Drawable Animation:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:duration="100">
<layer-list>
<item android:drawable="@drawable/login_loading_00" />
<item android:drawable="@drawable/login_loading_10" />
</layer-list>
</item>
<item android:duration="100">
<layer-list>
<item android:drawable="@drawable/login_loading_01" />
<item android:drawable="@drawable/login_loading_11" />
</layer-list>
</item>
</animation-list>
其中,android:oneshot=“true”表示该动画只播放一次,等于false时则循环播放。<item/>标签定义各个帧显示的图片,显示顺序依照<item/>定义顺序,<layer-list/>内包含的图片将层叠起来,在同一帧中一起显示
private AnimationDrawable loadingAnimation;
loadingAnimation.stop();
loadingAnimation.start();
View Animation:
View Animation效果由四个因素决定:1)初始状态;2)结束状态;3)持续时间;4)Interpolator
四大类:AlphaAnimation,RotateAnimation,ScaleAnimation,TranslateAnimation
代码实现View Animation
TranslateAnimation tAnim = new TranslateAnimation(0, 400, 0, 0);
RotateAnimation rAnima = new RotateAnimation(0, 70);
ScaleAnimation sAnima = new ScaleAnimation(0, 5, 0, 5);
AlphaAnimation aAnima = new AlphaAnimation(1.0f, 0.0f);
tAnim.setDuration(2000);
tAnim.setInterpolator(new AccelerateDecelerateInterpolator());
translation.startAnimation(tAnim);
XML文件实现View Animation
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<scale
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="0.6"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="1000" />
<set
android:interpolator="@android:anim/accelerate_interpolator"
android:startOffset="1000">
<scale … />
<rotate
android:fromDegrees="0"
android:toDegrees="60"
android:pivotX="50%"
android:pivotY="50%"
android:duration="400" />
</set>
</set>
android:fillAfter:设置fillAfter为true,动画将保持结束的状态
Animation anim = AnimationUtils.loadAnimation(AnimaXmlActivity.this, R.anim.myanim);
img.startAnimation(anim);
Property Animation:
通过动画的方式改变对象的属性,动画的执行类: ObjectAnimator、ValueAnimator
AnimatorSet用于控制一组动画的执行顺序
AnimatorInflater用于加载属性动画的XML文件
TypeEvaluator类型估值,用于设置动画操作属性的值
PropertyValuesHolder实现一个动画更改多个效果
TimeInterpolator时间插值
ObjectAnimator
ObjectAnimator.ofFloat(view, "rotationX", 0.0F, 360.0F).setDuration(500).start();
1、ObjectAnimator提供了ofInt、ofFloat、ofObject,这几个方法都是设置动画作用的元素、作用的属性、动画开始、结束的属性值,当只设置一个属性值的时候,会认为当然对象的属性值为开始(getPropName<
4000
/span>反射获取),设置的值为终点,如果设置两个,则一个为开始、一个为结束。动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用ObjectAnimator更新的属性,必须得有getter(设置属性值的时候)和setter方法。
2、如果操作的属性方法内部没有调用view的重绘,比如setRotationX,则需要手动调用
anim.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
view.postInvalidate();
view.invalidate();
}
});
3.通过ObjectAnimator让View既缩小、又淡出(属性scaleX,scaleY,alpha)
public void rotateAnimRun(final View view) {
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "zhy", 1.0F, 0.0F).setDuration(500);
anim.start();
anim.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float cVal = (Float) animation.getAnimatedValue();
view.setAlpha(cVal);
view.setScaleX(cVal);
view.setScaleY(cVal);
}
});
}
4.使用propertyValuesHolder实现一个动画更改多个效果:
public void propertyValuesHolder(View view) {
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f, 0f, 1f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);
PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);
ObjectAnimator.ofPropertyValuesHolder
(view, pvhX, pvhY,pvhZ).setDuration(1000).start();
}
ValueAnimator
和ObjectAnimator的区别之处:ValueAnimator本身并没有在属性上做操作,因此,不需要操作对象的属性一定要有getter和setter方法,你可以自己根据当前动画的计算值,来操作任何属性
public void verticalRun( View view) {
ValueAnimator animator =
ValueAnimator.ofFloat(0, mScreenHeight - mBlueBall.getHeight());
animator.setDuration(1000).start();
animator.setInterpolator(value)
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mBlueBall.setTranslationY((Float) animation.getAnimatedValue());
}
});
}
实现抛物线的效果,水平方向100px/s,垂直方向加速度200px/s*s:
public void paowuxian(View view) {
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setObjectValues(new PointF(0, 0));
valueAnimator.setDuration(3000);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setEvaluator(new TypeEvaluator<PointF>() {
// fraction = t / duration
@Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
PointF point = new PointF();
point.x = 200 * fraction * 3;
point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3);
return point;
}
});
valueAnimator.start();
valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
PointF point = (PointF) animation.getAnimatedValue();
mBlueBall.setX(point.x);
mBlueBall.setY(point.y);
}
});
}
监听事件:对于动画,一般都是一些辅助效果,比如我要删除个元素,我可能希望是个淡出的效果,但是最终还是要删掉,并不是你透明度没有了,还占着位置,所以我们需要知道动画如何结束
public void fadeOut(View view) {
ObjectAnimator anim = ObjectAnimator.ofFloat(mBlueBall, "alpha", 0.5f);
anim.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) { }
@Override
public void onAnimationRepeat(Animator animation) { }
@Override
public void onAnimationEnd(Animator animation) { }
@Override
public void onAnimationCancel(Animator animation) { }
});
anim.start();
}
AnimatorListenerAdapter:有时候,我只要监听某个状态,这么长的代码我不能接受
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) { }
});
AnimatorSet
public void togetherRun(View view) {
ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall, "scaleX", 1.0f, 2f);
ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall, "scaleY", 1.0f, 2f);
ObjectAnimator anim3 = ObjectAnimator.ofFloat(mBlueBall, "x", cx , 0f);
ObjectAnimator anim4 = ObjectAnimator.ofFloat(mBlueBall, "x", cx);
//anim1,anim2,anim3,anim4接着执行
AnimatorSet animSet = new AnimatorSet();
animSet.setDuration(2000);
animSet.setInterpolator(new LinearInterpolator());
animSet.playTogether(anim1, anim2);
animSet.start();
//anim1,anim2,anim3同时执行,anim4接着执行
AnimatorSet animSet = new AnimatorSet();
animSet.play(anim1).with(anim2);
animSet.play(anim2).with(anim3);
animSet.play(anim4).after(anim3);
animSet.setDuration(1000);
animSet.start();
}
xml文件实现Property Animation
View Animator 、Drawable Animator在anim文件夹下创建动画。Property Animator在animator文件夹下创建动画
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="1.0"
android:valueTo="0.5">
</objectAnimator>
<objectAnimator
android:duration="1000"
android:propertyName="scaleY"
android:valueFrom="1.0"
android:valueTo="0.5">
</objectAnimator>
</set>
Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale);
mMv.setPivotX(0);
mMv.setPivotY(0);
mMv.invalidate();
anim.setTarget(mMv);
anim.start();
orderring表示播放顺序,还有另一个值:sequentially(表示一个接一个执行),缩放、反转等默认是中心缩放,和对称轴为反转线,本例子以左上角为中心点
布局动画(Layout Animations)
LayoutTransition transition = new LayoutTransition();
transition.setAnimator(LayoutTransition.CHANGE_APPEARING,
transition.getAnimator(LayoutTransition.CHANGE_APPEARING));
transition.setAnimator(LayoutTransition.APPEARING, null);
transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, null);
mGridLayout.setLayoutTransition(transition);
过渡动画类型:
LayoutTransition.APPEARING:当View在ViewGroup中出现时,对此View设置动画
LayoutTransition.CHANGE_APPEARING:当一个View在ViewGroup中出现时,对此View对其他View位置造成影响,对其他View设置的动画
LayoutTransition.DISAPPEARING:当一个View在ViewGroup中消失时,对此View设置的动画
LayoutTransition.CHANGE_DISAPPEARING:当一个View在ViewGroup中消失时,对此View对其他View位置造成影响,对其他View设置的动画
View的anim方法:在SDK11的时候,给View添加了animate方法,更加方便的实现动画效果
public void viewAnim(View view) {
// need API 12
mBlueBall.animate().alpha(0).y(mScreenHeight / 2).setDuration(1000)
// need API 16
.withStartAction(new Runnable() {
public void run() { Log.e(TAG, "START"); }
}).withEndAction(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mBlueBall.setY(0);
mBlueBall.setAlpha(1.0f);
}
});
}
}).start();
}
runOnUiThread:
首先判断是否是UI线程,不是的话就post,如果是的话就正常运行该线程,只要经过主线程中的Handler.post或者postDelayed处理线程runnable则都可以将其转为UI主线程.再说Handler的机制就是来处理线程与UI通讯的
安卓动画主要有三类:逐帧动画(Drawable Animation、Frame Animation)、补间动画(View Animaiton、Tweened Animation)、属性动画(Property Animation),其中,View Animation只能修改View组件的部分属性、动画效果是绘制出来的,组件并没有真正改变,而Property Animation可以修改任何对象的任何属性,组件的状态也会跟着改变
Drawable Animation:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:duration="100">
<layer-list>
<item android:drawable="@drawable/login_loading_00" />
<item android:drawable="@drawable/login_loading_10" />
</layer-list>
</item>
<item android:duration="100">
<layer-list>
<item android:drawable="@drawable/login_loading_01" />
<item android:drawable="@drawable/login_loading_11" />
</layer-list>
</item>
</animation-list>
其中,android:oneshot=“true”表示该动画只播放一次,等于false时则循环播放。<item/>标签定义各个帧显示的图片,显示顺序依照<item/>定义顺序,<layer-list/>内包含的图片将层叠起来,在同一帧中一起显示
private AnimationDrawable loadingAnimation;
loadingAnimation.stop();
loadingAnimation.start();
View Animation:
View Animation效果由四个因素决定:1)初始状态;2)结束状态;3)持续时间;4)Interpolator
四大类:AlphaAnimation,RotateAnimation,ScaleAnimation,TranslateAnimation
代码实现View Animation
TranslateAnimation tAnim = new TranslateAnimation(0, 400, 0, 0);
RotateAnimation rAnima = new RotateAnimation(0, 70);
ScaleAnimation sAnima = new ScaleAnimation(0, 5, 0, 5);
AlphaAnimation aAnima = new AlphaAnimation(1.0f, 0.0f);
tAnim.setDuration(2000);
tAnim.setInterpolator(new AccelerateDecelerateInterpolator());
translation.startAnimation(tAnim);
XML文件实现View Animation
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<scale
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="0.6"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="1000" />
<set
android:interpolator="@android:anim/accelerate_interpolator"
android:startOffset="1000">
<scale … />
<rotate
android:fromDegrees="0"
android:toDegrees="60"
android:pivotX="50%"
android:pivotY="50%"
android:duration="400" />
</set>
</set>
android:fillAfter:设置fillAfter为true,动画将保持结束的状态
Animation anim = AnimationUtils.loadAnimation(AnimaXmlActivity.this, R.anim.myanim);
img.startAnimation(anim);
Property Animation:
通过动画的方式改变对象的属性,动画的执行类: ObjectAnimator、ValueAnimator
AnimatorSet用于控制一组动画的执行顺序
AnimatorInflater用于加载属性动画的XML文件
TypeEvaluator类型估值,用于设置动画操作属性的值
PropertyValuesHolder实现一个动画更改多个效果
TimeInterpolator时间插值
ObjectAnimator
ObjectAnimator.ofFloat(view, "rotationX", 0.0F, 360.0F).setDuration(500).start();
1、ObjectAnimator提供了ofInt、ofFloat、ofObject,这几个方法都是设置动画作用的元素、作用的属性、动画开始、结束的属性值,当只设置一个属性值的时候,会认为当然对象的属性值为开始(getPropName<
4000
/span>反射获取),设置的值为终点,如果设置两个,则一个为开始、一个为结束。动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用ObjectAnimator更新的属性,必须得有getter(设置属性值的时候)和setter方法。
2、如果操作的属性方法内部没有调用view的重绘,比如setRotationX,则需要手动调用
anim.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
view.postInvalidate();
view.invalidate();
}
});
3.通过ObjectAnimator让View既缩小、又淡出(属性scaleX,scaleY,alpha)
public void rotateAnimRun(final View view) {
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "zhy", 1.0F, 0.0F).setDuration(500);
anim.start();
anim.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float cVal = (Float) animation.getAnimatedValue();
view.setAlpha(cVal);
view.setScaleX(cVal);
view.setScaleY(cVal);
}
});
}
4.使用propertyValuesHolder实现一个动画更改多个效果:
public void propertyValuesHolder(View view) {
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f, 0f, 1f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);
PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);
ObjectAnimator.ofPropertyValuesHolder
(view, pvhX, pvhY,pvhZ).setDuration(1000).start();
}
ValueAnimator
和ObjectAnimator的区别之处:ValueAnimator本身并没有在属性上做操作,因此,不需要操作对象的属性一定要有getter和setter方法,你可以自己根据当前动画的计算值,来操作任何属性
public void verticalRun( View view) {
ValueAnimator animator =
ValueAnimator.ofFloat(0, mScreenHeight - mBlueBall.getHeight());
animator.setDuration(1000).start();
animator.setInterpolator(value)
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mBlueBall.setTranslationY((Float) animation.getAnimatedValue());
}
});
}
实现抛物线的效果,水平方向100px/s,垂直方向加速度200px/s*s:
public void paowuxian(View view) {
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setObjectValues(new PointF(0, 0));
valueAnimator.setDuration(3000);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setEvaluator(new TypeEvaluator<PointF>() {
// fraction = t / duration
@Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
PointF point = new PointF();
point.x = 200 * fraction * 3;
point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3);
return point;
}
});
valueAnimator.start();
valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
PointF point = (PointF) animation.getAnimatedValue();
mBlueBall.setX(point.x);
mBlueBall.setY(point.y);
}
});
}
监听事件:对于动画,一般都是一些辅助效果,比如我要删除个元素,我可能希望是个淡出的效果,但是最终还是要删掉,并不是你透明度没有了,还占着位置,所以我们需要知道动画如何结束
public void fadeOut(View view) {
ObjectAnimator anim = ObjectAnimator.ofFloat(mBlueBall, "alpha", 0.5f);
anim.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) { }
@Override
public void onAnimationRepeat(Animator animation) { }
@Override
public void onAnimationEnd(Animator animation) { }
@Override
public void onAnimationCancel(Animator animation) { }
});
anim.start();
}
AnimatorListenerAdapter:有时候,我只要监听某个状态,这么长的代码我不能接受
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) { }
});
AnimatorSet
public void togetherRun(View view) {
ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall, "scaleX", 1.0f, 2f);
ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall, "scaleY", 1.0f, 2f);
ObjectAnimator anim3 = ObjectAnimator.ofFloat(mBlueBall, "x", cx , 0f);
ObjectAnimator anim4 = ObjectAnimator.ofFloat(mBlueBall, "x", cx);
//anim1,anim2,anim3,anim4接着执行
AnimatorSet animSet = new AnimatorSet();
animSet.setDuration(2000);
animSet.setInterpolator(new LinearInterpolator());
animSet.playTogether(anim1, anim2);
animSet.start();
//anim1,anim2,anim3同时执行,anim4接着执行
AnimatorSet animSet = new AnimatorSet();
animSet.play(anim1).with(anim2);
animSet.play(anim2).with(anim3);
animSet.play(anim4).after(anim3);
animSet.setDuration(1000);
animSet.start();
}
xml文件实现Property Animation
View Animator 、Drawable Animator在anim文件夹下创建动画。Property Animator在animator文件夹下创建动画
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="1.0"
android:valueTo="0.5">
</objectAnimator>
<objectAnimator
android:duration="1000"
android:propertyName="scaleY"
android:valueFrom="1.0"
android:valueTo="0.5">
</objectAnimator>
</set>
Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale);
mMv.setPivotX(0);
mMv.setPivotY(0);
mMv.invalidate();
anim.setTarget(mMv);
anim.start();
orderring表示播放顺序,还有另一个值:sequentially(表示一个接一个执行),缩放、反转等默认是中心缩放,和对称轴为反转线,本例子以左上角为中心点
布局动画(Layout Animations)
LayoutTransition transition = new LayoutTransition();
transition.setAnimator(LayoutTransition.CHANGE_APPEARING,
transition.getAnimator(LayoutTransition.CHANGE_APPEARING));
transition.setAnimator(LayoutTransition.APPEARING, null);
transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, null);
mGridLayout.setLayoutTransition(transition);
过渡动画类型:
LayoutTransition.APPEARING:当View在ViewGroup中出现时,对此View设置动画
LayoutTransition.CHANGE_APPEARING:当一个View在ViewGroup中出现时,对此View对其他View位置造成影响,对其他View设置的动画
LayoutTransition.DISAPPEARING:当一个View在ViewGroup中消失时,对此View设置的动画
LayoutTransition.CHANGE_DISAPPEARING:当一个View在ViewGroup中消失时,对此View对其他View位置造成影响,对其他View设置的动画
View的anim方法:在SDK11的时候,给View添加了animate方法,更加方便的实现动画效果
public void viewAnim(View view) {
// need API 12
mBlueBall.animate().alpha(0).y(mScreenHeight / 2).setDuration(1000)
// need API 16
.withStartAction(new Runnable() {
public void run() { Log.e(TAG, "START"); }
}).withEndAction(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mBlueBall.setY(0);
mBlueBall.setAlpha(1.0f);
}
});
}
}).start();
}
runOnUiThread:
首先判断是否是UI线程,不是的话就post,如果是的话就正常运行该线程,只要经过主线程中的Handler.post或者postDelayed处理线程runnable则都可以将其转为UI主线程.再说Handler的机制就是来处理线程与UI通讯的
相关文章推荐
- 使用DirectX让进行Alpha混合的子图形移动(精灵动画)
- 【开机动画】原创-鸟叔PSY -&…
- Android 实现个性的ViewPager切换动画 实战PageTransformer(兼容Android3.0以下)
- 动感的CSS3 Loading加载文字动画特效
- iOS动画 对号和叉叉
- 分析android动画模块之Tween动画(转)
- 【开机动画】原创-火影忍者-旗木卡…
- Android Animations动画使用详解
- 转场动画3-手势返回
- JS动画公式
- Silverlight动画制作之动画概述
- 【开机动画】原创-使命召唤:黑色…
- 那些动画效果很炫的Android及iOS开源项目
- Android官方开发文档Training系列课程中文版:动画视图之转场框架介绍
- 前端动画渲染引擎pixi.js系列(10)骨骼动画实现之DragonBones
- 在as3中Embed(绑定)flash动画元素
- 【开机动画】韩国美女组合 Gi…
- 按钮动画学习2
- 核心动画的接触点滴(一)
- 9中动画插值器