一般情况下,遇到一些复杂的动画效果,我们都会使用自定义view来实现,也就是不停的调用onDraw来达到动画的效果。可是我们会发现,使用postDelay控制时间不是很精确,今天来教大家一个技巧,就是在自定义view里再加入自定义的animation类。
Animation类有两个可以复写的方法:
public void initialize(int width, int height, int parentWidth, int parentHeight)
protected void applyTransformation(float interpolatedTime, Transformation t)
第一个方法是初始化,我们可以在里面设置Animation的Interpolator,这样可以达到动画线性和先快后慢,先慢后快的效果。
最主要的是第二个方法,interpolatedTime是一个从0到1变化的参数,动画开始的时候,它是0,动画结束的时候,它增加到1,所以这个参数就是我们需要使用的,我们可以把view的整个动画过程看成是从0到1,然后使用这个参数来控制view的绘制,这样就能使我们能够精确的控制view的动画时长。
下面是一个小例子:一个textview,里面的数字从0一直增长到我们设置的最大值
public class PercentTextView extends TextView {
private String mPercent;
private BarAnimation animation;
private static final long DEFAULT_DURATION = 500;
public PercentTextView(Context context) {
super(context);
init();
}
public PercentTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public PercentTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setText("0");
}
public void setMaxValue(String value) {
mPercent = value;
}
public void start() {
if (!TextUtils.isEmpty(mPercent)) {
animation = new BarAnimation(this, mPercent);
animation.setDuration(DEFAULT_DURATION);
startAnimation(animation);
}
}
public void start(final long time) {
if (!TextUtils.isEmpty(mPercent)) {
animation = new BarAnimation(this, mPercent);
animation.setDuration(time);
startAnimation(animation);
}
}
public class BarAnimation extends Animation {
private TextView mTextView;
private String maxValue;
public BarAnimation(TextView view, String maxValue) {
mTextView = view;
this.maxValue = maxValue;
}
@Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
setInterpolator(new LinearInterpolator());
super.initialize(width, height, parentWidth, parentHeight);
}
@Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
super.applyTransformation(interpolatedTime, t);
int count = (int) (interpolatedTime * Integer.valueOf(maxValue));
mTextView.setText(count+"");
}
}
}
在这个自定义的textview类里有一个内部类BarAnimation,当外部调用start()的时候textview也startAnimation,interpolatedTime就会在500毫秒的时间里从0增长到1,那我们显示的数字就是interpolatedTime*maxValue。
外部使用的时候先setMaxValue(),然后调用start()就可以了,有一个默认的动画时间,当然也可以自己传入时间。