安卓動(dòng)畫目前共分為三種動(dòng)畫逐幀動(dòng)畫、補(bǔ)間動(dòng)畫和屬性動(dòng)畫。
一绣夺、逐幀動(dòng)畫(frame-by-frame animation)
逐幀動(dòng)畫就是將一個(gè)完整的動(dòng)畫拆分成一張張單獨(dú)的圖片榨馁,然后再將它們連貫起來進(jìn)行播放薛耻,類似于動(dòng)畫片的工作原理输钩。
- 素材圖片放到drawable文件夾下豺型,mipmap下無法引用
在drawable文件夾下新建wifi-z的xml文件用來存放圖片
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
//oneshot表示是否循環(huán)播放 true只播放一次,false循環(huán)播放买乃,圖片順序不能變否則動(dòng)畫不連貫
<item
android:drawable="@drawable/icon_5"
android:duration="300" />
<item
android:drawable="@drawable/icon_4"
android:duration="300" />
<item
android:drawable="@drawable/icon_3"
android:duration="300" />
<item
android:drawable="@drawable/icon_2"
android:duration="300" />
<item
android:drawable="@drawable/icon_1"
android:duration="300" />
<item
android:drawable="@drawable/icon_0"
android:duration="300" />
</animation-list>-
Activity中引用動(dòng)畫
// 存放動(dòng)畫圖片的imageview
private ImageView mImg;
// 開啟動(dòng)畫的按鈕
private Button mBtn;
// 實(shí)現(xiàn)逐幀動(dòng)畫的類
private AnimationDrawable animationDrawable;mBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mImg.setImageResource(R.drawable.wifi_d); animationDrawable = (AnimationDrawable) mImg.getDrawable(); animationDrawable.start();//停止調(diào)用stop方法 } });
二姻氨、補(bǔ)間動(dòng)畫(tweened animation)
補(bǔ)間動(dòng)畫則是可以對(duì)View進(jìn)行一系列的動(dòng)畫操作,包括淡入淡出剪验、縮放肴焊、平移、旋轉(zhuǎn)四種功戚。
<b>
補(bǔ)間動(dòng)畫只是表面上的View移動(dòng)娶眷,View實(shí)際還在原來位置,而屬性動(dòng)畫則是View也跟著移動(dòng)</b>
-
淡入淡出
AlphaAnimation:透明度(alpha)漸變效果啸臀,對(duì)應(yīng)<alpha/>標(biāo)簽届宠。
外部xml方法
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromAlpha="1.0"
android:fillAfter="false"http://動(dòng)畫結(jié)束時(shí)是否保持在該位置
android:interpolator="@android:anim/accelerate_decelerate_interpolator"http://插值器
android:toAlpha="0.1" />Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha); mImg.startAnimation(animation);
java方式
Animation alphaAnimation = new AlphaAnimation(1.0f, 0.1f);
alphaAnimation.setDuration(2000);
alphaAnimation.setFillAfter(false);
mImg.startAnimation(alphaAnimation); 縮放
ScaleAnimation:縮放漸變,可以指定縮放的參考點(diǎn)乘粒,對(duì)應(yīng)<scale/>標(biāo)簽豌注。
xml方式
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXScale="0.2"
android:fromYScale="0.2"
android:interpolator="@android:anim/accelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%" //動(dòng)畫起始位置,相對(duì)于屏幕的百分比,兩個(gè)都為50%表示動(dòng)畫從自身中間開始
android:toXScale="1.5"
android:toYScale="1.5" />
java方式
Animation scaleAnimation = new ScaleAnimation(0.0f, 1.5f, 0.0f, 1.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(2000);//設(shè)置動(dòng)畫持續(xù)時(shí)間為500毫
scaleAnimation.setInterpolator(this, android.R.anim.accelerate_interpolator);//設(shè)置動(dòng)畫插入器
mImg.startAnimation(scaleAnimation);平移
TranslateAnimation:位移漸變灯萍,需要指定移動(dòng)點(diǎn)的開始和結(jié)束坐標(biāo)幌羞,對(duì)應(yīng)<translate/>標(biāo)簽。
xml方式
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXDelta="0"
android:fromYDelta="0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:toXDelta="320"
android:toYDelta="0" />
java方式
Animation translateAnimation = new TranslateAnimation(0, 320, 0, 0);
translateAnimation.setDuration(2000);
translateAnimation.setInterpolator(this, android.R.accelerate_decelerate_interpolator);//設(shè)置動(dòng)畫插入器
mImg.startAnimation(translateAnimation);旋轉(zhuǎn)
RotateAnimation:旋轉(zhuǎn)漸變竟稳,可以指定旋轉(zhuǎn)的參考點(diǎn)属桦,對(duì)應(yīng)<rotate/>標(biāo)簽。
xml方式
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromDegrees="0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:repeatCount="-1"http://-1代表無限循環(huán) 正數(shù)代表循環(huán)幾次
android:repeatMode="reverse"http://動(dòng)畫重復(fù)的模式他爸,reverse為反向聂宾,當(dāng)?shù)谂即螆?zhí)行時(shí),動(dòng)畫方向會(huì)相反诊笤。restart為重新執(zhí)行系谐,方向不變
android:toDegrees="360" />
java方式
Animation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(1000);
rotateAnimation.setInterpolator(this, android.R.anim.accelerate_decelerate_interpolator);//設(shè)置動(dòng)畫插入器
mImg.startAnimation(rotateAnimation);組合
AnimationSet:組合漸變,支持組合多種漸變效果讨跟,對(duì)應(yīng)<set/>標(biāo)簽纪他。
java方式
AnimationSet animationSet = new AnimationSet(true);
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(scaleAnimation);
mImg.startAnimation(animationSet);動(dòng)畫監(jiān)聽器
alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
//動(dòng)畫開始時(shí)調(diào)用 }
@Override
public void onAnimationEnd(Animation animation) {
//動(dòng)畫結(jié)束時(shí)調(diào)用 }
@Override
public void onAnimationRepeat(Animation animation) {
//動(dòng)畫重復(fù)時(shí)調(diào)用 } });插值器
AccelerateInterpolator 加速,開始時(shí)慢中間加速
DecelerateInterpolator 減速晾匠,開始時(shí)快然后減速
AccelerateDecelerateInterolator 先加速后減速茶袒,開始結(jié)束時(shí)慢,中間加速
AnticipateInterpolator 反向凉馆,先向相反方向改變一段再加速播放
AnticipateOvershootInterpolator 反向加超越薪寓,先向相反方向改變亡资,再加速播放,會(huì)超出目的值然后緩慢移動(dòng)至目的值
BounceInterpolator 跳躍向叉,快到目的值時(shí)值會(huì)跳躍锥腻,如目的值100,后面的值可能依次為85母谎,77瘦黑,70,80奇唤,90幸斥,100
CycleIinterpolator 循環(huán),動(dòng)畫循環(huán)一定次數(shù)冻记,值的改變?yōu)橐徽液瘮?shù):Math.sin(2* mCycles* Math.PI* input)
LinearInterpolator 線性,線性均勻改變
OvershootInterpolator超越来惧,最后超出目的值然后緩慢改變到目的值
三冗栗、屬性動(dòng)畫(property animation)
功能很強(qiáng)大,可以替代逐幀動(dòng)畫與補(bǔ)間動(dòng)畫供搀。
-
ValueAnimator
屬性動(dòng)畫的運(yùn)行機(jī)制是通過不斷地對(duì)值進(jìn)行操作來實(shí)現(xiàn)的隅居,而初始值和結(jié)束值之間的動(dòng)畫過渡就是由ValueAnimator這個(gè)類來負(fù)責(zé)計(jì)算的。它的內(nèi)部使用一種時(shí)間循環(huán)的機(jī)制來計(jì)算值與值之間的動(dòng)畫過渡葛虐,我們只需要將初始值和結(jié)束值提供給ValueAnimator胎源,并且告訴它動(dòng)畫所需運(yùn)行的時(shí)長(zhǎng),那么ValueAnimator就會(huì)自動(dòng)幫我們完成從初始值平滑地過渡到結(jié)束值這樣的效果屿脐。//從0-1-5-1 float 類型 整型可以ofInt ValueAnimator animator = ValueAnimator.ofFloat(0f, 1.0f, 5.0f, 1.0f); animator.setDuration(300); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { float value = (float) valueAnimator.getAnimatedValue(); Log.d(TAG, "onAnimationUpdate: " + value); } }); animator.start();
ObjectAnimator
可以直接對(duì)任意對(duì)象的任意屬性進(jìn)行動(dòng)畫操作的涕蚤,比如說View的alpha屬性。
// 旋轉(zhuǎn):rotation 漸變:alpha 平移:x軸tarnslationX(平移時(shí)需要先獲取當(dāng)前位置的诵,getTranslationX)
//縮放 scaleX/scaleY
ObjectAnimator animator = ObjectAnimator.ofFloat(mProperty, "alpha", 1.f, 0f);
animator.setDuration(1000);
animator.start();AnimatorSet(組合動(dòng)畫)
after(Animator anim) 將現(xiàn)有動(dòng)畫插入到傳入的動(dòng)畫之后執(zhí)行
after(long delay) 將現(xiàn)有動(dòng)畫延遲指定毫秒后執(zhí)行
before(Animator anim) 將現(xiàn)有動(dòng)畫插入到傳入的動(dòng)畫之前執(zhí)行
with(Animator anim) 將現(xiàn)有動(dòng)畫和傳入的動(dòng)畫同時(shí)執(zhí)行
ObjectAnimator translate = ObjectAnimator.ofFloat(mProperty, "translationX", -500f, 0f);
ObjectAnimator rotation = ObjectAnimator.ofFloat(mProperty, "rotation", 0f, 360f);
ObjectAnimator scale = ObjectAnimator.ofFloat(mProperty, "scaleX", 1.0f, 2.0f, 1.0f);
AnimatorSet set = new AnimatorSet();
set.play(rotation).with(scale).after(translate);
set.setDuration(5000);
set.start();Animator監(jiān)聽器
-
監(jiān)聽所有方法
translate.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {} @Override public void onAnimationEnd(Animator animator) { } @Override public void onAnimationCancel(Animator animator) { } @Override public void onAnimationRepeat(Animator animator) { } });
監(jiān)聽單個(gè)方法
rotation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});