Android 使用動畫效果後的控件位置處理 相似系統通知欄下拉動畫

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動畫

相關文章
相關標籤/搜索