- 视图动画与属性动画的区别:
- 引入时间不同
- 所在包名不同
- 视图动画:android.view.animation
- 属性动画:android.animation
- 动画类名不同
- 视图动画:XXXXAnimation
- 属性动画:XXXXAnimator
- 视图动画我们可以发现如果给TextView设置一个向下移动的效果,在给他一个点击事件,就会发现TextView移动后无法点击,所以说视图动画无法改变动画属性
public class ViewAnimationWrongActivity extends AppCompatActivity {
private Button button; private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_animation_wrong);
button = (Button)findViewById(R.id.move_text);
textView = (TextView)findViewById(R.id.text_click);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TranslateAnimation translateAnimation = new
TranslateAnimation(Animation.ABSOLUTE, 0,
Animation.ABSOLUTE,0,Animation.ABSOLUTE, 0, Animation.ABSOLUTE,400);
translateAnimation.setDuration(1000);
translateAnimation.setFillAfter(true);
textView.startAnimation(translateAnimation);
}
});
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(ViewAnimationWrongActivity.this,
textView.getText(), Toast.LENGTH_SHORT).show();
}
});
}
}
- 属性动画的功能:
- 对指定区间进行动画运算,我们通过对运算过程进行监听来操作控件
- ValueAnimator只负责对指定区间进行动画运算
- 我们需要对运算过程进行监听,然后自己对控件执行动画操作
- 初步使用ValueAnimator:
ValueAnimator valueAnimmator = ValueAnimator.ofInt(0, 400);
valueAnimator.setDuration(1000);
valueAnimator.start();
* 但是从上述的代码可以看出ValueAnimator没有跟任何控件进行关联,他只针对值进行动画运算,而不是针对空间的
//correct
public class ViewAnimationWrongActivity extends AppCompatActivity {
private Button button;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_animation_wrong);
button = (Button)findViewById(R.id.move_text);
textView = (TextView)findViewById(R.id.text_click);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//进行属性动画
doAnimation();
}
});
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(ViewAnimationWrongActivity.this,
textView.getText(), Toast.LENGTH_SHORT).show();
}
});
}
private void doAnimation(){
final ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 400);
valueAnimator.setDuration(1000);
//对ValueAnimator进行监听,并将当前的监听结果返回,让TextView重新绘制,也就是将TextView的那块画布一起移走
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int curValue = (int) valueAnimator.getAnimatedValue();
textView.layout(0, curValue+button.getHeight(), textView.getWidth(),
curValue+textView.getHeight());
}
});
valueAnimator.start();
}
}
//都是可变长函数,所以可以传入任何数量的值,比如ofInt(2, 90,45)从数字2变化到数字90再变化到45,传进去的数字越多,动画变化就越复杂,两者传入的数据类型不同
public static ValueAnimator ofInt(int.... values)
public static ValueAnimator ofFloat(float..... values)
- Object getAnimatedValue():
这个函数的返回值类型通过上述的函数使用的类型进行控制,比如上述函数使用ofInt()就会返回int类型
//设置动画时长
ValueAnimator setDuration(long duration);
//获取运动时点的值
Object getAnimatedValue();
//开始动画
void start();
//设置循环次数,设置位INFINITE表示无限循环
void setRepeatCount(int value);
//设置循环模式
void setRepeatMode(int value);
//取消动画
void cancel();
- 注意:重复次数为INFINITE的动画,当Activity结束时,必须调用cancel()函数取消动画,否则动画将无限循环,从而导致View无法释放,最终引起内存泄漏
- 执行效果的监听器:
//添加执行情况的监听器
valueAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
Log.d(TAG, "Start");
}
@Override
public void onAnimationEnd(Animator animation) {
Log.d(TAG, "End");
}
@Override
public void onAnimationCancel(Animator animation){
Log.d(TAG, "Cancel");
}
@Override
public void onAnimationRepeat(Animator animation) {
Log.d(TAG, "Repeat");
}
});
//对于每一个监听器都有两种方法来移除
//移除所有的监听器
removeAllListeners();
//移除指定的监听器
removeListener(AnimatorListener listener);
//延时多久开始,单位是毫秒
public void setStartDelay(long startDelay);
//完全克隆一个ValueAnimator实例,包括它所有设置以及所有对监听器代码的处理, 注意 克隆出来的监听器对象是一个独立的个体,可以自己重新设置属性
public ValueAnimator clone();