天天看点

属性动画

  • 视图动画与属性动画的区别:
    • 引入时间不同
      • 视图动画API1引入发,属性动画在API11
    • 所在包名不同
      • 视图动画: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实例:
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()于ofFloat()函数:
//都是可变长函数,所以可以传入任何数量的值,比如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();
           

继续阅读