編輯:關於Android編程
Android中動畫大概分為3類:
TweenAnimation(補間動畫)
TranslateAnimation ScaleAnimation RotateAnimation AlphaAnimationFrameAnimation(幀動畫)
PropertyAnimation(屬性動畫)先來看屬性動畫,這是潮流,也是google推薦使用的。
屬性動畫和一般的View動畫的重要區別在於:
1. 屬性動畫控制的是實實在在的屬性,但是View動畫只是產生一個動畫,並沒有改變控件的屬性。
2. View動畫只能控制View的屬性,屬性動畫可以控制所有屬性,只要這個屬性有get/set 方法,是什麼意思呢?
例如 我們查看ImageView的源碼,可以看到它有一個私有屬性叫 alpha,表示透明度,同時有 setAlpha()/getAlpha() 方法,所有我們就可以通過屬性動畫來修改ImageView的Alpha的值來完成動畫。
那麼問題來了,到底動畫是怎麼產生的呢?簡單的說就是,在動畫執行前你需要為動畫設置初始值,結束值,動畫時間(這是3個最基本的值),那麼ValueAnimator類就可以通過這3個值計算出一串連續的數字,表示動畫的過程。
例如:alpha值 from 0 to 255,如果時間設置成 255秒,那麼 ValueAnimator產生的值將為每秒變化1,0,1,2,3,4,5,6…,然後將這些值通過 setAlpha() 設置給ImageView,就完成了動畫。 當然這個例子比較奇葩,但是我覺得比較好理解。
那麼怎麼來實踐我說的呢?我們來看一個例子:
這是ValueAnimator的初級用法,通過 ofFloat() 方法設置起始x坐標,起始x+100,起始x坐標,就是一個在x軸上一個來回100px的動畫。區間是1000ms,注意為了將動畫與控件相關聯(動畫都是需要應用到控件上),需要添加一個 AnimatorUpdateListener,這個回調就是用來產生一系列的中間值,然後我們在回調中將中間值設置給我們的ImageView,那麼動畫就完成了。
最後我們還是用Log將中間值都打印了出來,就更容易理解ValueAnimator就是用來產生一個值變化的序列的作用。當然這裡使用的是默認的線性插值器,變化率是均勻的,如果使用其他插值器,還可以產生不均勻的效果。
float fromX = ivLogo.getTranslationX(); ValueAnimator va = ValueAnimator.ofFloat(fromX, fromX + 100f, fromX); va.setDuration(1000); va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float v = (float) animation.getAnimatedValue(); ivLogo.setTranslationX(v); Log.d(TAG, "v:" + v); } }); va.start();
效果圖:
打印出來的Log:
D/ANIMATION: v:0.0 D/ANIMATION: v:0.14258027 D/ANIMATION: v:0.53691864 D/ANIMATION: v:1.2311637 D/ANIMATION: v:2.2070706 D/ANIMATION: v:3.3803642 D/ANIMATION: v:4.894352 ... D/ANIMATION: v:84.35657 D/ANIMATION: v:89.65131 D/ANIMATION: v:94.66184 D/ANIMATION: v:100.0 D/ANIMATION: v:94.66184 D/ANIMATION: v:89.651306 D/ANIMATION: v:84.35657 ... D/ANIMATION: v:6.679535 D/ANIMATION: v:4.894348 D/ANIMATION: v:3.380371 D/ANIMATION: v:2.2070618 D/ANIMATION: v:1.2311707 D/ANIMATION: v:0.53691864 D/ANIMATION: v:0.14257813 D/ANIMATION: v:0.0
理解了這個,我們就可以來看看下一個更加使用的類
public final class ObjectAnimator extends ValueAnimator{...}
查看源碼就知道,ObjectAnimator是繼承於ValueAnimator的,ObjectAnimator使用起來更加簡單,因為ValueAnimator還需要我們自己去回調,ObjectAnimator不需要寫回調,只需要把要設置的屬性,控件,區間等內容告訴它,它自己幫我們完成動畫。
例子:
float fromX = ivLogo.getTranslationX(); ObjectAnimator oa = ObjectAnimator.ofFloat(ivLogo, "translationX", fromX, fromX + 100f, fromX); oa.setDuration(300); oa.start(); oa.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); } });
效果和使用 ValueAnimator 是一樣的,所以就不貼圖了。剛剛我們說不需要回調,但是這裡又寫了一個回調的Listener是什麼意思呢?大家大可把這個刪掉,我這裡加上主要是為了說明如果想監聽 動畫結束,動畫開始… 等中間過程,ObjectAnimator也可以做到。只需要添加這個 AnimatorListenerAdapter 抽象類。至於這裡為什麼是抽象類,大家打開源碼就可以明白,為了不實現回調的所有方法,特別加了一個抽象類實現 AnimatorListener 接口,這樣就可以想覆蓋什麼方法就覆蓋什麼方法,不需要全部都覆蓋。這也可以理解為 設計模式中的適配器模式吧,原接口不符合我的要求,我需要一個適配器來完成轉換
如果上面兩個都理解了,那麼這個就好理解了。AnimatorSet顧名思義就是動畫的集合,我們要將幾個屬性動畫放在一起運行,或者按照序列執行,或者按任意順序執行都可以實現,看看例子:
ObjectAnimator oaScaleX = ObjectAnimator.ofFloat(ivLogo, "scaleX", 0, 1); ObjectAnimator oaScaleY = ObjectAnimator.ofFloat(ivLogo, "scaleY", 0, 1); ObjectAnimator oaRotation = ObjectAnimator.ofFloat(ivLogo, "rotation", 0, 360); ObjectAnimator oaAlpha = ObjectAnimator.ofFloat(ivLogo, "alpha", 1, 0); AnimatorSet as = new AnimatorSet(); as.play(oaScaleX).with(oaScaleY).with(oaRotation); as.play(oaAlpha).after(oaRotation); as.setDuration(1000); as.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); ivLogo.setAlpha(1.0f); Log.d(TAG, "finish:" + ivLogo.getAlpha()); } }); as.start();
首先構造了4個 ObjectAnimator對象,分別是沿X軸變形,沿Y軸變形,旋轉,透明度,然後我們讓前3個一起執行,之後在執行漸變,最後添加一個動畫結束回調,將Alpha設置為1,表示不透明,否則我們的控件就看不見了。
效果圖:
android的套路,一定會允許你使用xml的方式來配置動畫,所以我們看看怎麼配置:
res 文件夾下新建文件夾 animator, 然後創建一個 動畫xml文件:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">
android:ordering="sequentially"表示依次執行,
android:propertyName="rotation"表示修改的屬性值
android:valueType="floatType"表示屬性值類型
其他的都好理解了。
然後在代碼中使用:
Animator animator = AnimatorInflater.loadAnimator(PropertyActivity.this, R.animator.animator_1);
animator.setTarget(ivLogo);
animator.start();
效果圖:
使用插值器
我們知道 ValueAnimator就是用來產生一些動畫屬性中間值,但是默認是均勻變化的,插值器就是要使得產生的中間序列非均勻化,當然不僅是非均勻這麼簡單,還有很多特效:
下面是官網提供的一些插值器,大家都可以試試,我這裡只是拋磚引玉,展示最簡單的用法:
使用方法:
float fromX = ivLogo.getTranslationX();
ObjectAnimator oa = ObjectAnimator.ofFloat(ivLogo, "translationX", fromX, fromX + 100, fromX);
oa.setInterpolator(new BounceInterpolator());
oa.setDuration(1000);
oa.start();
只比前面多了一行:
oa.setInterpolator(new BounceInterpolator());
效果圖:
TweenAnimation補間動畫
如果上面的屬性動畫你都理解了,那麼補間動畫就更好理解了:
通過代碼,和xml配置創建Animation
btnAnimation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Animation animation = new TranslateAnimation(0, 200, 0, 200);
animation.setDuration(1000);
animation.setFillAfter(true);
ivLogo.startAnimation(animation);
}
});
btnXml.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Animation animation = AnimationUtils.loadAnimation(TweenActivity.this, R.anim.anim1);
animation.setDuration(1000);
animation.setFillAfter(true);
ivLogo.startAnimation(animation);
}
});
ivLogo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick");
}
});
anim1.xml
代碼很簡單,看一下就明白了,這裡給 ivLogo添加了一個onclick事件,是為了說明tween動畫修改的不是view的真實屬性,怎麼說呢?如果點擊第一個動畫,ivLogo的位置相對於原來的位置已經偏離到 (+200, +200) 的位置,但是這個時候如果依然點擊 ivLog原位置,依然會打印 “onClick”, 所以其實View的位置屬性是沒有變化的。所以Tween動畫修改的不是屬性值,而只是產生的一個動畫效果而已。
效果圖:
學習Animation的話,關注比較多的應該是Animation的一些屬性設置,大家感興趣可以參考官網。
FrameAnimation幀動畫
上面兩個動畫都與控件相關,但是幀動畫就完全是圖片的疊加。原理和 gif 動畫 或者電影一樣,是因為每一幀過的速度太快,眼睛來不及反應所以我們覺得是動畫。
anim_frame.xml
-
-
-
-
-
-
" data-snippet-id="ext.f98ecf9b620c3910fca173d8eb93cd45" data-snippet-saved="false" data-codota-status="done">
-
-
-
-
-
-
根元素為 animation-list android:oneshot=”false” 表示動畫一直循環執行
代碼調用:
btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ivWifi.setImageResource(R.drawable.anim_frame);
AnimationDrawable animationDrawable = (AnimationDrawable) ivWifi.getDrawable();
if (isRun) {
animationDrawable.stop();
} else {
animationDrawable.start();
}
isRun = !isRun;
}
});
一個全局變量表示動畫是否在執行,然後點擊按鈕時更換狀態。
效果圖:
總結
Android中提供了3種動畫,以後的趨勢還是屬性動畫,所以大家不要猶豫,快來鑽研屬性動畫吧!
一、需求:標題可能寫的不夠全部,下面來看下圖片,大家就明白是什麼意思了。視頻與票的圖標跟在標題後面顯示,當標題過長時icon顯示到省略號…後(textview省略號顯示,
本文實例為大家分享了Android ImageLoader框架的使用方法,供大家參考,具體內容如下1.准備工作1)導入universal-image-loader-1.9
在Android Volley分析(一)——結構中主要分析了Volley的基本組件和框架結構,組件主要是定義的接口,也就是說我們可以實現這些接口來定制自己的Volley版
一、簡介本節演示如何在安卓系統中通過用戶配置文件(user profile)讀取和更新該手機的所有聯系人信息,以及如何導航到用戶配置文件中的這些聯系人。二、基本概念&nb