傳統(tǒng)動(dòng)畫Animation
屬性動(dòng)畫Animator
傳統(tǒng)動(dòng)畫Animation
系統(tǒng)不斷的進(jìn)行調(diào)用ondraw方法來實(shí)現(xiàn)重新繪制
屬性動(dòng)畫Animator
是通過對(duì)屬性的get和set方法對(duì)屬性的真是的值進(jìn)行改變
傳統(tǒng)動(dòng)畫的局限性,只是對(duì)動(dòng)畫的位置進(jìn)行了改變,屬于是障眼法,但是根本的最底層的位置還是沒有改變.圖片如下,當(dāng)在初始位置點(diǎn)擊時(shí)候可以彈出Toast,但是在平移了之后,點(diǎn)擊是沒有反應(yīng)的,但是點(diǎn)擊最初的已經(jīng)成為空白的位置的時(shí)候,詭異的事情發(fā)生了.可以彈出Toast.
傳統(tǒng)動(dòng)畫代碼如下:
TranslateAnimation animation = new TranslateAnimation(0, 200, 0, 0);
animation.setDuration(1000);
animation.setFillAfter(true);
ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.startAnimation(animation);
現(xiàn)在用屬性動(dòng)畫來做,代碼如下:
/**
* 一參,操作的對(duì)象
* 二參,操作對(duì)象的屬性
* 三參,操作對(duì)象的屬性的值變化范圍
* 最后設(shè)置時(shí)間,然后start
*/
ImageView imageView = (ImageView) findViewById(R.id.imageView);
ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f)
.setDuration(1000)
.start();
運(yùn)行結(jié)果如下:
屬性動(dòng)畫是真正的改變動(dòng)畫的值
既然能這么用,那就多來幾個(gè)試試效果:
ImageView imageView = (ImageView) findViewById(R.id.imageView);
ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f)
.setDuration(1000)
.start();
ObjectAnimator.ofFloat(imageView, "translationY", 0f, 200f)
.setDuration(1000)
.start();
ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f)
.setDuration(1000)
.start();
可以發(fā)現(xiàn),點(diǎn)擊之間的三個(gè)動(dòng)畫是同步進(jìn)行的.一起完成的.當(dāng)然除了用這種方法之外呢,還有一種方法:
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX", 0f, 200f);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translationY", 0f, 200f);
PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("rotation", 0f, 360f);
ObjectAnimator.ofPropertyValuesHolder(imageView, p1, p2, p3).setDuration(1000).start();
通過PropertyValuesHolder 類來實(shí)現(xiàn)每一個(gè)動(dòng)畫,然后在ObjectAnimator的ofPropertyValuesHolder方法傳入要用動(dòng)畫的對(duì)象,然后start開始即可..
那么這兩種方式有啥區(qū)別呢,很明顯第一種實(shí)現(xiàn)方式代碼量少,第二種方式代碼量多,本著存在即為合理的想法,肯定是第一種對(duì)內(nèi)存來耗好用比較大,第二種對(duì)內(nèi)存來說耗用比較小了.實(shí)際上Google也是這樣說的.
當(dāng)然還有第三種實(shí)現(xiàn)方式:
ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageView, "translationY", 0f, 200f);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f);
AnimatorSet set = new AnimatorSet();
set.playTogether(animator1,animator2,animator3);
set.setDuration(1000);
set.start();
就是用set集合去設(shè)置每個(gè)子元素的添加,然后作用在一起的動(dòng)畫,運(yùn)行之后的效果和之前的是一模一樣的,此處就不貼圖了..
當(dāng)然還有按照順序來執(zhí)行,按照順序來一個(gè)個(gè)依次執(zhí)行,只需要將上方代碼中的playTogether方法替換為playSequentially即可
先X平移,在Y平移,最后旋轉(zhuǎn).
那么還可以怎么玩呢,還可以讓X平移和Y平移一起,它倆完了以后再來個(gè)旋轉(zhuǎn)
ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageView, "translationY", 0f, 200f);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f);
AnimatorSet set = new AnimatorSet();
// set.playSequentially(animator1,animator2,animator3);
set.play(animator1).with(animator2);
set.play(animator3).after(animator1);
set.setDuration(1000);
set.start();
接下來,搞一下屬性動(dòng)畫的監(jiān)聽;
public void click(View view) {
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 0f, 1f);
animator.setDuration(1000);
//此種監(jiān)聽是通過adapter來實(shí)現(xiàn)動(dòng)畫執(zhí)行的過程的中的某一個(gè)階段的監(jiān)聽
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
// TODO: 2017/1/20
}
});
//此種監(jiān)聽是監(jiān)聽整個(gè)動(dòng)畫的開始與結(jié)束以及取消和重復(fù)的模式等監(jiān)聽
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
// TODO:
}
@Override
public void onAnimationEnd(Animator animator) {
// TODO:
}
@Override
public void onAnimationCancel(Animator animator) {
// TODO:
}
@Override
public void onAnimationRepeat(Animator animator) {
// TODO:
}
});
}
衛(wèi)星菜單:
package com.ccstest.activity;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.BounceInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.Toast;
import com.ccstest.R;
import java.util.ArrayList;
import java.util.List;
public class AnimActivity extends AppCompatActivity implements View.OnClickListener {
private int[] res = {R.id.imageView_a, R.id.imageView_b, R.id.imageView_c, R.id.imageView_d,
R.id.imageView_e, R.id.imageView_f, R.id.imageView_g, R.id.imageView_h};
private List<ImageView> mImageViews = new ArrayList<>();
private boolean flag = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_anim);
for (int i = 0; i < res.length; i++) {
ImageView img = (ImageView) findViewById(res[i]);
img.setOnClickListener(this);
mImageViews.add(img);
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.imageView_a:
if (flag) {
startAnim();
} else {
closeAnim();
}
break;
default:
Toast.makeText(AnimActivity.this, "click = " + view.getId(), Toast.LENGTH_SHORT).show();
break;
}
}
private void closeAnim() {
for (int i = 0; i < res.length; i++) {
ObjectAnimator animator = ObjectAnimator.ofFloat(mImageViews.get(i), "translationY", i * 200, 0);
animator.setDuration(500);
animator.setStartDelay(i * 100);
animator.setInterpolator(new BounceInterpolator());
animator.start();
flag = true;
}
}
private void startAnim() {
for (int i = 0; i < res.length; i++) {
ObjectAnimator animator = ObjectAnimator.ofFloat(mImageViews.get(i), "translationY", 0f, i * 300);
animator.setDuration(500);
animator.setInterpolator(new BounceInterpolator());
animator.setStartDelay(i * 100);
animator.start();
flag = false;
}
}
// public void click(View view) {
// Toast.makeText(this, "clicked", Toast.LENGTH_SHORT).show();
// }
//
// public void move(View view) {
// TranslateAnimation animation = new TranslateAnimation(0, 200, 0, 0);
// animation.setDuration(1000);
// animation.setFillAfter(true);
// ImageView imageView = (ImageView) findViewById(R.id.imageView);
// imageView.startAnimation(animation);
/**
* 一參,操作的對(duì)象
* 二參,操作對(duì)象的屬性
* 三參,操作對(duì)象的屬性的值變化范圍
* 最后設(shè)置時(shí)間,然后start
*/
// ImageView imageView = (ImageView) findViewById(R.id.imageView);
// ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f)
// .setDuration(1000)
// .start();
// ObjectAnimator.ofFloat(imageView, "translationY", 0f, 200f)
// .setDuration(1000)
// .start();
// ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f)
// .setDuration(1000)
// .start();
// PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX", 0f, 200f);
// PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translationY", 0f, 200f);
// PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("rotation", 0f, 360f);
// ObjectAnimator.ofPropertyValuesHolder(imageView, p1, p2, p3).setDuration(1000).start();
// ObjectAnimator animator1 = ObjectAnimator.ofFloat(imageView, "translationX", 0f, 200f);
// ObjectAnimator animator2 = ObjectAnimator.ofFloat(imageView, "translationY", 0f, 200f);
// ObjectAnimator animator3 = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f);
// AnimatorSet set = new AnimatorSet();
// set.playSequentially(animator1,animator2,animator3);
// set.play(animator1).with(animator2);
// set.play(animator3).after(animator1);
// set.setDuration(1000);
// set.start();
// ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 0f, 1f);
// animator.setDuration(1000);
// animator.addListener(new AnimatorListenerAdapter() {
// @Override
// public void onAnimationEnd(Animator animation) {
// super.onAnimationEnd(animation);
// //....do something
// }
// });
// animator.addListener(new Animator.AnimatorListener() {
// @Override //動(dòng)畫開始
// public void onAnimationStart(Animator animator) {
//
// }
//
// @Override //動(dòng)畫結(jié)束
// public void onAnimationEnd(Animator animator) {
// ....do something
// }
//
// @Override //動(dòng)畫取消
// public void onAnimationCancel(Animator animator) {
//
// }
//
// @Override //重復(fù)模式
// public void onAnimationRepeat(Animator animator) {
//
// }
// });
// animator.start();
//
// }
}
package com.ccstest.activity;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.graphics.PointF;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.ccstest.R;
public class AnimTimeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_anim_time);
}
public void animTiem(View view){
// final Button button = (Button) view;
// ValueAnimator animator = ValueAnimator.ofInt(0, 100);
// animator.setDuration(5000);
// animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
// @Override
// public void onAnimationUpdate(ValueAnimator valueAnimator) {
// Integer value = (Integer) valueAnimator.getAnimatedValue();
// button.setText(value+"");
// }
// });
// animator.start();
ValueAnimator animator = ValueAnimator.ofObject(new TypeEvaluator<PointF>() {
@Override
public PointF evaluate(float v, PointF pointF, PointF t1) {
return null;
}
});
}
}