Android的動畫的使用,請參考。Android的動畫,在設計方面,我有點不太理解,以爲這樣搞很怪,由於在控件動畫後,即便設置了停留在動畫結束時的位置,咱們也確實看到了控件停在那個位置,但其實該控件的真實位置仍是在原來動畫前的那裏。舉個例子,若是有個Button,你給它設置了動畫,讓它移動到其餘位置,當移動完成後,你會發現,點擊Button沒有任何效果,而在Button原來的位置,就是動畫前的位置點擊,明明沒有任何控件,卻看到了點擊Button的效果。不知道Google爲何要這樣設計。
解決思路:動畫不設置結束後停留在結束位置,經過setAnimationListener方法設置動畫監聽器,在動畫結束時,即onAnimationEnd方法中,手動用layout或者setLayoutParams方法把控件移動到動畫結束的位置。
範例說明:啓動時以下圖,一個按鈕,按鈕上有一條高10像素的白條,其實這是另外一個View,可是我把它Y軸設爲了負,因此只能看到一部分,另外一部分被隱藏在屏幕上方。
按下下拉顯示按鈕時,那個白色的View會以向下移動,就是下拉動畫的效果,顯示在屏幕上,以下圖:java
當點擊隱藏後,這個View又會上拉,恢復到第一張圖片的樣子,顯示出原來的下拉顯示按鈕。android
源代碼:
佈局 main.xml:app
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?xml version="1.0" encoding="utf-8"?> <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <!-- 由於下面的兩個LinearLayout要覆蓋,就是顯示的位置有重疊,因此,必須使用AbsoluteLayout,絕對佈局 --> <LinearLayout android:orientation="vertical" android:id="@+id/main" android:layout_x="0dp" android:layout_y="0dp" android:layout_width="fill_parent" android:layout_height="fill_parent" android:weightSum="1"> <Button android:layout_width="wrap_content" android:id="@+id/show" android:layout_height="wrap_content" android:text="下拉顯示" /> </LinearLayout> <LinearLayout android:orientation="vertical" android:id="@+id/selection" android:layout_x="0dp" android:layout_y="-190px" android:layout_width="fill_parent" android:layout_height="200px" android:background="@color/white"> <!-- 之因此用 px做單位,是由於設置控件位置的layout方法的參數就是px單位的,單位相同方便計算 高200,y座標-190,還有10個像素能夠看到,是爲了方便演示,固然,你也能夠設爲-200,恰好所有隱藏 --> <Button android:layout_width="wrap_content" android:id="@+id/hidden" android:layout_height="wrap_content" android:text="隱藏" /> </LinearLayout> </AbsoluteLayout> |
兩個描述動畫的xml文件,show.xml與hidden.xml:
show.xml:ide
1 2 3 4 5 6 7 8 9 10 11 |
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0" android:toXDelta="0" android:fromYDelta="0" android:toYDelta="190" android:duration="1000" /> <!-- 座標好像是相對控件的起始位置的,而不是相對父控件 --> </set> |
hidden.xml:佈局
1 2 3 4 5 6 7 8 9 10 |
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0" android:toXDelta="0" android:fromYDelta="0" android:toYDelta="-190" android:duration="1000" /> </set> |
主程序代碼:測試
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
package com.test; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Animation.AnimationListener; import android.widget.AbsoluteLayout; import android.widget.Button; import android.widget.LinearLayout; public class AndroidTestActivity extends Activity { /** Called when the activity is first created. */ LinearLayout main, selection; Button hidden, show; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); main = (LinearLayout) findViewById(R.id.main); selection = (LinearLayout) findViewById(R.id.selection); hidden = (Button) findViewById(R.id.hidden); show = (Button) findViewById(R.id.show); show.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Animation showAnim=AnimationUtils.loadAnimation(AndroidTestActivity.this, R.anim.show); // translate.setFillAfter(true); //若是隻用setFillAfter方法保存移動後的位置,真實位置不會移動 selection.startAnimation(showAnim); //若是下面的View是一個listview,可能須要先執行selection.requestFocusFromTouch();不然第二次不會顯示動畫 //須要把下面的控件 enable設爲false,防止點中下面的控件 show.setEnabled(false); //必須設爲false,由於若是連續點擊兩次,就會連着執行兩次移動位置,並非咱們想要的結果 //等把拉下的view移回去後,再設爲true showAnim.setAnimationListener(new AnimationListener(){ @Override public void onAnimationEnd(Animation animation) { // TODO Auto-generated method stub hidden.setEnabled(true); //當下拉動畫結束後,把隱藏的按鈕設爲可用 selection.clearAnimation(); selection.layout(selection.getLeft(), 0, selection.getRight(), 200); // selection.setLayoutParams(new AbsoluteLayout.LayoutParams(AbsoluteLayout.LayoutParams.FILL_PARENT, 200, 0, 0){}); //上面兩行功能相同 //移動控件到動畫結束的位置,clearAnimation方法能夠清除動畫,屏幕就不會閃,沒有的話會閃 //setFillAfter不能爲true,雖然即便爲true,控件真實位置也不會變,可是咱們看到的位置是會變的,若是再用layout方法,咱們看到的位置還會再變 System.out.println(selection.getLeft()+" "+selection.getTop()+" "+selection.getRight()+" "+selection.getBottom()); //輸出移動後的位置,通過測試,若是不使用layout方法移動控件,動畫前,動畫後,控件的位置都是不變的 //因此,親眼所見並不是真相 } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub System.out.println(selection.getLeft()+" "+selection.getTop()+" "+selection.getRight()+" "+selection.getBottom()); }}); } }); hidden.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub Animation hiddenAnim=AnimationUtils.loadAnimation(AndroidTestActivity.this, R.anim.hidden); selection.startAnimation(hiddenAnim); hidden.setEnabled(false); hiddenAnim.setAnimationListener(new AnimationListener(){ @Override public void onAnimationEnd(Animation animation) { // TODO Auto-generated method stub show.setEnabled(true); selection.clearAnimation(); // selection.layout(selection.getLeft(), -190, selection.getRight(), 10); selection.setLayoutParams(new AbsoluteLayout.LayoutParams(AbsoluteLayout.LayoutParams.FILL_PARENT, 200, 0, -190){}); //以上兩行,功能相同 } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub }}); }}); } } |
源代碼就不傳了,基本上都在上面了,除了一個定義白色的strings.xml動畫