标签:
前言:人生总有不平时,无论何时,不后悔就好。
相关文章:
1、《Animation 动画详解(一)——alpha、scale、translate、rotate、set的xml属性及用法》
2、《Animation动画详解(二)——Interpolator插值器》
3、《Animation动画详解(三)—— 代码生成alpha、scale、translate、rotate、set及插值器动画》
4、《Animation动画详解(四)——ValueAnimator基本使用》
5、《Animation动画详解(五)——ValueAnimator高级进阶(一)》
6、《Animation动画详解(六)——ValueAnimator高级进阶(二)》
通过上两篇的讲解,我们对ValueAnimator的动画的整个过程应该都已经有较深入的理解,不过还有两个概念我们还没有讲解关键帧和ofObject(),关键帧的部分涉及问题比较多,我们将其放在系列的末尾再讲,这篇着重讲一下ofObject函数的使用
public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values);它有两个参数,第一个是自定义的Evaluator,第二个是可变长参数,Object类型的;
从效果图中可以看到,按钮上的字母从A变化到Z,刚开始变的慢,后来逐渐加速;
ValueAnimator animator = ValueAnimator.ofObject(new CharEvaluator(),new Character(‘A‘),new Character(‘Z‘));
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
char text = (char)animation.getAnimatedValue();
tv.setText(String.valueOf(text));
}
});
animator.setDuration(10000);
animator.setInterpolator(new AccelerateInterpolator());
animator.start();这里注意三点: ValueAnimator animator = ValueAnimator.ofObject(new CharEvaluator(),new Character(‘A‘),new Character(‘Z‘));我们自定义的一个CharEvaluator,这个类实现,后面会讲;在初始化动画时,传进去的是Character对象,一个是字母A,一个是字母Z;
char text = (char)animation.getAnimatedValue(); tv.setText(String.valueOf(text));通过animation.getAnimatedValue()得到当前动画的字符,然后把字符设置给textview;大家知道我们构造时传进去的值类型是Character对象,所以在动画过程中通过Evaluator返回的值类型必然跟构造时的类型是一致的,也是Character
animator.setInterpolator(new AccelerateInterpolator());我们使用的是加速插值器,加速插值器的特点就是随着动画的进行,速度会越来越快,这点跟我们上面的效果图是一致的。
char temp = (char)65;//得到的temp的值就是大写字母A字符转数字:
char temp = ‘A‘; int num = (int)temp;在这里得到的num值就是对应的ASCII码值65;
public class CharEvaluator implements TypeEvaluator<Character> {
@Override
public Character evaluate(float fraction, Character startValue, Character endValue) {
int startInt = (int)startValue;
int endInt = (int)endValue;
int curInt = (int)(startInt + fraction *(endInt - startInt));
char result = (char)curInt;
return result;
}
}在这里,我们就利用A-Z字符在ASCII码表中对应数字是连续且递增的原理,先求出来对应字符的数字值,然后再转换成对应的字符。代码难度不大,就不再细讲了。 在这里,我们自定义了一个View,在这个view上画一个圆,但这个圆是有动画效果的。从效果中可以看出使用的插值器应该是回弹插值器(BounceInterpolator)
下面就来看看这个动画是怎么做出来的
public class Point {
private int radius;
public Point(int radius){
this.radius = radius;
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
}point类内容很简单,只有一个成员变量:radius表示当前point的半径。public class MyPointView extends View {
private Point mCurPoint;
public MyPointView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mCurPoint != null){
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(300,300,mCurPoint.getRadius(),paint);
}
}
public void doPointAnim(){
ValueAnimator animator = ValueAnimator.ofObject(new PointEvaluator(),new Point(20),new Point(200));
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurPoint = (Point)animation.getAnimatedValue();
invalidate();
}
});
animator.setDuration(1000);
animator.setInterpolator(new BounceInterpolator());
animator.start();
}
}public void doPointAnim(){
ValueAnimator animator = ValueAnimator.ofObject(new PointEvaluator(),new Point(20),new Point(200));
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurPoint = (Point)animation.getAnimatedValue();
invalidate();
}
});
animator.setDuration(1000);
animator.setInterpolator(new BounceInterpolator());
animator.start();
}同样,先来看ofObject的构造动画的方法:ValueAnimator animator = ValueAnimator.ofObject(new PointEvaluator(),new Point(20),new Point(200));在构造动画时,动画所对应的值的类型是Point对象,那说明我们自定义的PointEvaluator中的返回值也必然是Point了。有关PointEvaluator的实现后面再讲
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurPoint = (Point)animation.getAnimatedValue();
invalidate();
}
});在监听过程中,先根据animation.getAnimatedValue()得到当前动画进度所对应的Point实例,保存在mCurPoint中,然后强制刷新 protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mCurPoint != null){
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(300,300,mCurPoint.getRadius(),paint);
}
}onDraw函数没什么难度,就是根据mCurPoint的半径在(300,300)的位置画出来圆形,有关绘图的知识大家可以参考另一个系列《android Graphics(一):概述及基本几何图形绘制》 public class PointEvaluator implements TypeEvaluator<Point> {
@Override
public Point evaluate(float fraction, Point startValue, Point endValue) {
int start = startValue.getRadius();
int end = endValue.getRadius();
int curValue = (int)(start + fraction * (end - start));
return new Point(curValue);
}
}这段代码其实比较容易理解,就是根据初始半径和最终半径求出当前动画进程所对应的半径值,然后新建一个Point对象返回。<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:padding="10dp"
android:text="start anim"
/>
<Button
android:id="@+id/btn_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:padding="10dp"
android:text="cancel anim"
/>
<TextView
android:id="@+id/tv"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center"
android:padding="10dp"
android:background="#ffff00"
android:text="Hello qijian"/>
<com.harvic.BlogValueAnimator4.MyPointView
android:id="@+id/pointview"
android:layout_below="@id/tv"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
其实也没什么难度,就是在原来的布局代码下面加一个MyPointView控件,难度不大,不再细讲了 public class MyActivity extends Activity {
private Button btnStart;
private MyPointView mPointView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnStart = (Button) findViewById(R.id.btn);
mPointView = (MyPointView)findViewById(R.id.pointview);
btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPointView.doPointAnim();
}
});
}
}这段代码没什么难度,就是在点击start anim按钮的时候,调用mPointView.doPointAnim()方法开始动画。 如果本文有帮到你,记得加关注哦
源码下载地址:
csdn:
github:https://github.com/harvic/BlogResForGitHub
请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/50549385 谢谢
Animation动画详解(六)——ValueAnimator高级进阶(二)
标签:
原文地址:http://blog.csdn.net/harvic880925/article/details/50549385