3个分类
View 动画, 属性动画, 帧动画
View动画(android 3.0以下使用) TranslateAnimation
只支持4种类型的动画, 平移(TranslateAnimation), 缩放(ScaleAnimation), 旋转(RotateAnimation), 透明度(AlphaAnimation). 因此有些效果实现不了.
4种类型共同的父类是: Animation.
在xml中使用, 也可以在代码中使用.
xml的定义位置: res/anim
使用view动画的核心: 每个view都提供了setAnimation API. framework同时提供了工具类AnimationUtils加载xml中的动画文件.
view.startAnimation(animation);
//或者这样
view.setAnimation(animation);
animation.start();
代码:
Popup_menu.java
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
JLog.i();
Animation animation = AnimationUtils.loadAnimation(mContext,R.anim.view_animation_demo);
menu_download.setAnimation(animation);
animation.start();
}
res/anim/view_animation_demo.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="0"
android:toXDelta="200"
android:duration="300" />
</set>
属性动画 ObjectAnimator
为什么叫属性动画? 因为实现原理是在一段时间内通过持续改变一个对象的属性值的方式, 实现动画的效果.
Android 3.0以后新引入的, 对于低版本手机, 可使用兼容包nineoldandroid去使用属性动画.
实现原理是: 给对象指定要改变的属性名字以及开始值和结束值, 因此在类中必须有其对应的get和set方法. ObjectAnimator通过反射的方式, 持续调用这个属性的set方法, 设置新的值给该属性, 从而实现动画的效果.
代码:
TextView menu_download;
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(menu_download, "translationX", 0, 300);
objectAnimator.start();
}
以动画的方式, 持续调用setTranslationX()方法, 改变menu_download对象的"translationX"属性的值.
public class View {
public void setTranslationX(float translationX) {
}
}
ValueAnimator和ObjectAnimator的区别
父子继承关系.
public final class ObjectAnimator extends ValueAnimator
使用区别:
ValueAnimator.ofInt()方法中没有object参数, 动画修改的是"数字", 不直接作用于某个对象.
因此使用ValueAnimator完成动画, 还要配合上update listener才行.
代码:
CircleLoadingView.java
public void startAnim() {
startViewAnim(0.0f, 1.0f, 1000);
}
private ValueAnimator startViewAnim(float startF, final float endF, long time) {
valueAnimator = ValueAnimator.ofFloat(startF, endF);
valueAnimator.setDuration(time);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.setRepeatMode(ValueAnimator.RESTART);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float value = (float) valueAnimator.getAnimatedValue();
startAngle = 360 * value;
invalidate();
}
});
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.argb(0, 0, 0, 0));
canvas.drawCircle(mWidth / 2, mWidth / 2, mWidth / 2 - mPadding, mPaint);
mPaint.setColor(getColor());
rectF = new RectF(mPadding, mPadding, mWidth - mPadding, mWidth - mPadding);
canvas.drawArc(rectF, startAngle, 270, false, mPaint);
}
View动画和属性动画选谁
优先选择属性动画,
因为一是属性动画可以支持更多的动画效果, 只要这个属性名字在类中有set和get方法即可.
例如改变TextView的宽度, 就只有属性动画可以做到. View动画的ScaleAnimation只是缩放, 会把TextView里面的内容也一起进行缩放, 不满足需求.
二是因为View动画实施后并不改变View的实际位置, 因此在新位置点击不到view, view的点击事件还是发生在初始位置, 在大多数情况下, 这么做是不符合用户预期的.
帧动画 AnimationDrawable
耗费内存, 因此不建议使用.
通过给view设置背景的方式实现.
frame.xml中
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/f1" android:duration="300" />
<item android:drawable="@drawable/f2" android:duration="300" />
<item android:drawable="@drawable/f3" android:duration="300" />
<item android:drawable="@drawable/f4" android:duration="300" />
</animation-list>
java代码:
image = (ImageView) findViewById(R.id.frame_image);
image.setBackgroundResource(R.anim.frame);
AnimationDrawable anim = (AnimationDrawable) image.getBackground();
anim.start();
--------DONE.--------------------