編輯:關於Android編程
前面我們已經完整的講述了屬性動畫的實現,我們已經學會了怎麼實現動畫,如果沒有屬性我們也學會了怎麼添加屬性,還學習了用ValueAnimator來實現動畫。
這裡我們來學習剩下的屬性,首先我們來看看Evaluator,Evaluator是什麼?他有什麼用?
Evaluator翻譯為求值器,或者表達式,反正只可意會不可言傳,就是給一個表達式,計算對應的值,他主要有以下屬性:
1, 返回動畫當前時間點的屬性值
2,全部繼承自TypeEvaluator
3,系統實現了IntEvaluator,FloatEvaluator,ArgbEvaluator
4,Api21實現了PointFEvaluator
我們解釋一下上面的屬性,首先表達式可以計算當前時間點的值,並且所有的Evaluator都繼承自TypeEvaluator,從這一點就可以知道,我們可以自己來實現Evaluator,目前已經有幾個默認的實現,我們前面所實現的動畫都是ofFloat,ofInt沒有實現過其他類型的動畫,這是因為float,int的表達式系統已經默認實現,如果有一個新的表達式不屬於上面的任何屬性,我們怎麼辦?
我們可以自定義Evaluator,我們接下來實現一個自定義的Evaluator。我們來實現一個拋物線的效果,效果如下圖:
vcjnz8KjujxiciAvPg0KPG5vYnI+eT0/MTE1MHgyKzR4PC9ub2JyPjxiciAvPg0KztLDx7j5vt3Jz8r2tcSx7bTvyr3AtMq1z9a2r7uto6y2r7utz8K5/cjnz8KjujwvcD4NCjxwcmUgY2xhc3M9"brush:java;">
private void setCustomEvaluator() {
ValueAnimator animator = new ValueAnimator();
float offsetX = love.getX();
float offsetY = love.getY();
animator.setDuration(2000);
animator.setObjectValues(new PointF(offsetX, offsetY), new PointF(TRANS_X + offsetX, offsetY));
animator.setEvaluator(new TypeEvaluator
這裡我們需要注意的幾點是第一個設置好Evaluator,第二設置ObjectValues,之後在onAnimationUpdate回調中獲取得到的值,Evaluator中就是我們根據我們的函數計算得到的值。這樣我們的自定義動畫就已經實現完成了。
這裡的第二個需要講解的知識點是Keyframe,Keyframe的意思如下:
1, KeyFrame是一個時間/值對
2, KeyFrame之間可以定義不同的Interpolator
這裡我們用Keyframe來實現動畫:
private void keyFrame() { Keyframe keyframe1 = Keyframe.ofFloat(0f, 0f); Keyframe keyframe2 = Keyframe.ofFloat(0.5f, 360f); Keyframe keyframe3 = Keyframe.ofFloat(1.0f, 0f); PropertyValuesHolder pvh = PropertyValuesHolder.ofKeyframe("rotation", keyframe1, keyframe2, keyframe3); ObjectAnimator rotate = ObjectAnimator.ofPropertyValuesHolder(love, pvh); rotate.setDuration(2000); rotate.start(); }
我們先定義幾個Keyframe,最後將Keyframe使用到PropertyValuesHolder中,最後又將PropertyValuesHolder使用到ObjectAnimator中,上訴定義了三個Keyframe,比如我們實現一個旋轉的動畫,第一個關鍵幀為Keyframe.ofFloat(0f, 0f)表示第0時角度為0,剩下的一半的時間角度360,最終位置的角度為0度。
其實這裡的Keyframe我們前面已經有過使用,比如:
ObjectAnimator scaleX = ObjectAnimator.ofFloat(love, "scaleX", 1.0f, 2.0f);
這裡的1.0f與2.0f就表示開始的關鍵幀與結束的關鍵幀,只是這裡只有兩幀。
前面我們已經完全用代碼實現了動畫,但是動畫有兩種實現方式,還有一種實現方式就是用xml來實現。接下來我們就用xml來實現一個動畫:
1:首先定義一個動畫資源,放置到res/animator文件夾下,定義一個trans_scale.xml:
這裡如果是set我們需要設置ordering屬性,主要有together並且與sequentially串行,每一屬性需要設置valueType。
2:代碼中進行加載:
private void compositeAnimXml(){ Animator animator = AnimatorInflater.loadAnimator(this, R.animator.trans_scale); animator.setTarget(love); animator.start(); }
這樣我們就用xml實現了動畫。
Layout Animations為布局動畫,控制view加入與刪除自身的動畫與周圍view的動畫。主要有以下五種效果:
1, LayoutTransition.APPEARING,對出現的view設置動畫
2, LayoutTransition.CHANGE_APPEARING,其他view設置動畫
3, LayoutTransition.DISAPPEARING,對消失的view設置動畫
4, LayoutTransition. CHANGE_DISAPPEARING ,其他view設置動畫
5, LayoutTransition. CHANGE ,其他view設置動畫
上面的五種效果,後面都已經分別做了解釋,這裡我們用一個demo來演示一下:
定義布局文件如下:
代碼實現如下:
public class LayoutAnimationActivity extends AppCompatActivity implements View.OnClickListener { public static void start(Context context) { Intent intent = new Intent(); intent.setClass(context, LayoutAnimationActivity.class); context.startActivity(intent); } LinearLayout root; int i = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_layout_animation); findViews(); setViewListener(); } private void findViews() { root = (LinearLayout) findViewById(R.id.root); root.setLayoutTransition(getLayoutTransition()); } private LayoutTransition getLayoutTransition() { LayoutTransition transition = new LayoutTransition(); transition.setAnimator(LayoutTransition.APPEARING, transition.getAnimator(LayoutTransition.APPEARING)); transition.setAnimator(LayoutTransition.CHANGE_APPEARING, transition.getAnimator(LayoutTransition .CHANGE_APPEARING)); transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, transition.getAnimator(LayoutTransition .CHANGE_DISAPPEARING)); transition.setAnimator(LayoutTransition.DISAPPEARING, transition.getAnimator(LayoutTransition.DISAPPEARING)); transition.setAnimator(LayoutTransition.CHANGING, transition.getAnimator(LayoutTransition.CHANGING)); return transition; } private void setViewListener() { findViewById(R.id.add_view).setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.add_view: addViews(); break; } } private void addViews() { final Button button = new Button(this); button.setText("button=" + i++); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { root.removeView(button); } }); root.addView(button); } } private void compositeAnimXml(){ Animator animator = AnimatorInflater.loadAnimator(this, R.animator.love_f); animator.setTarget(love); animator.start(); }
我們對線性布局添加button,對布局設置LayoutTransition,這樣就實現了布局動畫,最常用的效果就是比如listview中加載item時設置動畫。
在文章的最後我們來講述一下轉場動畫,什麼是轉場動畫,通俗的來說,就是頁面切換的效果。
由於不同的手機打開關閉的效果不一致,各個手機都有不同的效果,效果不是很好,我們可以統一來控制頁面打開關閉的效果,保證所有手機效果的統一性,提升用戶體驗。
首先定義進入退出的動畫,第一個種方式就是采用style來實現,主要是來復寫android:windowAnimationStyle節點,系統默認有如下可以設置的屬性:
這裡定義了頁面進入的動畫,頁面退出的動畫等等,由於不同的手機默認實現的效果不同,因此我們可以復寫上述這些屬性,達到統一的效果。
我們首先定義如下三個動畫:
水平進入的動畫base_slide_right_in.xml
水平退出的動畫base_slide_right_out.xml
原地不動的動畫base_stay_orig.xml
之後我們復寫android:windowAnimationStyle屬性,我們定義一個新的style,設置到android:windowAnimationStyle中:
這樣頁面轉場的動畫就已經實現完成了,不過遺憾的是,有的手機不起作用。。。。我們就需要采用另外一種方式來實現了,我們調用overridePendingTransition:
overridePendingTransition函數如下:
public void overridePendingTransition(int enterAnim, int exitAnim) { try { ActivityManagerNative.getDefault().overridePendingTransition( mToken, getPackageName(), enterAnim, exitAnim); } catch (RemoteException e) { } }
定義一個進入的動畫,和一個退出的動畫
這裡需要注意的是overridePendingTransition有非常嚴格的調用條件,它必須在startActivity或者finish之後調用
調用方式如下:
@Override public void finish() { super.finish(); customExit(); } private void customExit() { overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); }
到此屬性動畫就已經實現完成了,我們學習了動畫怎麼實現,怎麼自定義Evaluator,怎麼實現布局動畫。
時間過得很快,明天終於可以拿到房子了,交完這次房租,也可以成為房東了,看看博客也好久沒有更新了,最近一直在整機器人,也沒有太多時間整理博客。今天下午和同事一起遇到了一個問
Android Service服務一直運行: &nb
當Android系統捕獲到用戶的各種輸入事件後,如何准確的傳遞給真正的需要這個事件的控件?Android提供了一整套完善的事件傳遞、處理機制,來幫助開發者完成准確的事件分
AndroidMainfest.xml文件詳解一、關於AndroidManifest.xmlAndroidManifest.xml 是每個android程序中必須的文件。