Xamarin.Android之動畫

weixin_34126215發表於2015-01-21

Translate動畫

      這個動畫是最常使用到的,主要就是將控制元件從一個位置移動到另一個位置,並且還可以在這其中增加一定的效果,下面我們將採用兩種方式實現動畫,首選的是利用XML來製作動畫,其次就是利用程式碼。

首先我們在Resources中新建一個名為anim的資料夾,然後在該資料夾下新建兩個xml,分別命名為in_from_bottomout_from_bottom,然後我們將下面的程式碼寫入其中:

 

in_from_bottom:

1 <set xmlns:android="http://schemas.android.com/apk/res/android" 
2      android:interpolator="@android:anim/bounce_interpolator">
3   <translate android:startOffset="500" android:fromYDelta="0" android:toYDelta="80%p" android:duration="1000" />
4 </set>

 

 

out_from_bottom:

1 <set xmlns:android="http://schemas.android.com/apk/res/android"
2      android:interpolator="@android:anim/bounce_interpolator">
3   <translate android:startOffset="500" android:fromYDelta="80%p" android:toYDelta="0" android:duration="1000"/>
4 </set>

 

 

其中set標籤表示一個動畫集合,該標籤下可以包含多個不同的動畫,這樣就可以將他們組合成一個動畫,這裡我們不需要過多的瞭解它,主要是理解translate標籤,這個標籤代表的就是滑動動畫,其中各個屬性的說明如下所示:

Interpolator:表示下面的動畫的過渡形式,比如逐漸變慢或者逐漸變快。

startOffset:表示動畫開始前的延遲(單位毫秒)

fromYDelta:表示動畫開始的位置(其中80%p表示螢幕的80%的高度部分,對應的還有fromXDelta屬性)

toYDelta:表示動畫結束的位置(對應的還有toXDelta屬性)

Duration:表示動畫持續的時間(單位毫秒)

 

介紹完了具體屬性,下面就是利用這個動畫。首先我們新建一個活動,然後將其檢視的xml改成如下所示:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:p1="http://schemas.android.com/apk/res/android"
 3     p1:layout_width="match_parent"
 4     p1:layout_height="match_parent"
 5     p1:id="@+id/relativeLayout1"
 6     p1:padding="5dp">
 7     <TextView
 8         p1:text="會動的TextView"
 9         p1:layout_width="match_parent"
10         p1:layout_height="wrap_content"
11         p1:id="@+id/tvAnim"
12         p1:gravity="center"
13         p1:padding="5dp"
14         p1:background="#00f"
15         p1:textSize="30dp" />
16     <Button
17         p1:text="消 失"
18         p1:layout_width="wrap_content"
19         p1:layout_height="wrap_content"
20         p1:id="@+id/btnHide"
21         p1:layout_alignParentBottom="true" />
22     <Button
23         p1:text="出 現"
24         p1:layout_width="wrap_content"
25         p1:layout_height="wrap_content"
26         p1:layout_toRightOf="@id/btnHide"
27         p1:id="@+id/btnShow"
28         p1:layout_alignParentBottom="true" />
29 </RelativeLayout>
View Code

 

 

對應的程式碼部分改成如下所示:

      我們可以看到動畫檔案需要利用AnimationUtils這個靜態類的LoadAnimation方法讀取,然後將返回值傳遞給控制元件的StartAnimation方法,其中我們多了一行程式碼,就是FillAfter = true,如果不存在這個程式碼,我們會發現動畫在結束後控制元件又回到原來的位置了,有些時候這並不是我們需要的,所以需要將FillAfter設定為True即可。

 

效果展示:

 

 

下面我們利用程式碼的形式實現跟上面一樣的動畫效果,我們直接在OnCreate中建立動畫:

 1         protected override void OnCreate(Bundle bundle)
 2         {
 3             base.OnCreate(bundle);
 4             SetContentView(Resource.Layout.AnimationActivity);
 5 
 6             inAnim = new TranslateAnimation(Dimension.RelativeToParent, 0, Dimension.RelativeToParent, 0,
 7                 Dimension.RelativeToParent, 0, Dimension.RelativeToParent, (float)0.8);
 8             inAnim.FillAfter = true;
 9             inAnim.StartOffset = 500;
10             inAnim.Duration = 1000;
11             inAnim.SetInterpolator(this, Android.Resource.Animation.BounceInterpolator);
12 
13             outAnim = new TranslateAnimation(Dimension.RelativeToParent, 0, Dimension.RelativeToParent, 0,
14                 Dimension.RelativeToParent, (float)0.8, Dimension.RelativeToParent, 0);
15             outAnim.FillAfter = true;
16             outAnim.StartOffset = 500;
17             outAnim.Duration = 1000;
18             outAnim.SetInterpolator(this, Android.Resource.Animation.BounceInterpolator);
19 
20             TvAnim = FindViewById<TextView>(Resource.Id.tvAnim);
21             FindViewById<Button>(Resource.Id.btnHide).Click += (e, s) =>
22                 {
23                     TvAnim.StartAnimation(inAnim);
24                 };
25 
26             FindViewById<Button>(Resource.Id.btnShow).Click += (e, s) =>
27                 {
28                     TvAnim.StartAnimation(outAnim);
29                 };
30         }

 

      我們例項化一個TranslateAnimation物件,後面的屬性跟XML中一摸一樣的,直接就可以使用,唯一的區別就是Interpolator需要通過SetInterpolator方法來進行設定。有時我們需要利用程式碼控制移動的距離,比如在FrameLayout佈局下要讓底層的控制元件呈現,就需要移動我們預想的值,但是TranslateAnimation只能接收px為單位的距離,我們就需要將DP轉換成PX,筆者這裡順便將實現功能的帶麼也貼出來,方面有需要的人:

1         public static int DpToPx(this Context context, float dp)
2         {
3             return (int)(context.Resources.DisplayMetrics.Density * dp + 0.5f);
4         }

 

 

Alpha動畫

      這個動畫比較簡單,所以筆者就不單獨寫了,就跟著上面的例子,直接在XML中增加這個動畫,也正好可以證明set下的多個動畫是可以同步執行的,通過這樣的組合我們就可以作出很多非常炫酷的動畫了。下面我們直接看對應的XML的程式碼:

 

out_from_bottom:

1 <set xmlns:android="http://schemas.android.com/apk/res/android" 
2      android:interpolator="@android:anim/bounce_interpolator">
3   <translate android:startOffset="500" android:fromYDelta="80%p" android:toYDelta="0" android:duration="1000"/>
4   <alpha android:fromAlpha="0" android:startOffset="500" android:duration="1000" android:toAlpha="1" />
5 </set>

 

 

In_from_bottom:

1 <set xmlns:android="http://schemas.android.com/apk/res/android" 
2      android:interpolator="@android:anim/bounce_interpolator">
3   <translate android:startOffset="500" android:fromYDelta="0" android:toYDelta="80%p" android:duration="1000"/>
4   <alpha android:fromAlpha="1" android:startOffset="500" android:duration="1000" android:toAlpha="0" />
5 </set>

 

其中我們可以看到alpha實際上只有fromAlphatoAlpha屬性,其他的屬性都是公用的,是不是非常的簡單,然後我們再把活動的程式碼改回之前的樣子,使用XML中定義的動畫。

 

效果展示:

 

 

對應的程式碼形式,筆者這裡簡單的寫下,不進行舉例了:

1 AlphaAnimation alpha = new AlphaAnimation(0, 1);
2 alpha.Duration = 1000;
3 alpha.StartOffset = 500;

 

 

PS:如果讀者急切的想知道如果利用程式碼製作多個動畫的組合,可以使用AnimationSet類,將對應的動畫新增進去。

 

Rotate動畫

      顧名思義,就是翻轉動畫。這裡為了下面能夠看到動畫的效果,我們需要將活動檢視中的TextView的屬性layout_centerInParent設定為true即可,緊接著我們將對應的XML檔案進行修改:

 

In_from_bottom:

1 <set xmlns:android="http://schemas.android.com/apk/res/android"
2      android:interpolator="@android:anim/bounce_interpolator">
3   <rotate android:fromDegrees="180" android:toDegrees="0" android:startOffset="500" android:duration="1000" android:pivotX="50%" android:pivotY="50%" />
4 </set>

 

 

out_from_bottom:

1 <set xmlns:android="http://schemas.android.com/apk/res/android" 
2      android:interpolator="@android:anim/bounce_interpolator">
3   <rotate android:fromDegrees="0" android:toDegrees="180" android:startOffset="500" android:duration="1000" android:pivotX="50%" android:pivotY="50%" />
4 </set>

 

 

      其中fromDegresestoDegrees就是從多少度翻轉到多少度,pivotXpivotY則需要重點介紹,既然是翻轉,自然要有中心。預設情況的中心就是左上角,通過給這兩個值賦上float型別的值表示中點是根據左上角進行偏移,比如pivotX=5,pivotY=10,左上角的座標是101,50。則最終的中點就是106,60了,當然我們也可以用百分比表示,比如都賦50%就表示中點為控制元件的中心,如果在後面加上p單位就表示中點是父控制元件的中心,明白了這些這個動畫我們就能夠很好的掌握了。

 

效果展示:

 

 

對應的程式碼形式如下所示:

1 RotateAnimation rotate = new RotateAnimation(0, 180, Dimension.RelativeToSelf, 0.5f, Dimension.RelativeToSelf, 0.5f);
2 rotate.Duration = 1000;
3 rotate.StartOffset = 500;

 

 

Scale動畫

      這已經是我們最後一個介紹的動畫了,下面我們不多說廢話,直接修改XML:

 

Out_from_bottom:

1 <scale android:fromXScale="0.2" android:toXScale="1" android:fromYScale="0.2" android:toYScale="1" android:pivotX="50%" android:pivotY="50%" android:duration="1000" />

 

 

In_from_bottom:

1 <scale android:fromXScale="1" android:toXScale="0.2" android:fromYScale="1" android:toYScale="0.2" android:pivotX="50%" android:pivotY="50%" android:duration="1000" />

 

這裡的pivotYpivotX跟上上節的使用方式是相同的,對應fromXScalefromYScaletoXScaletoYScale的作用就是X軸和Y軸上等比縮放的比例了。

 

效果展示:

 

 

對應的程式碼形式如下:

1 ScaleAnimation scale = new ScaleAnimation(1f, 0.2f, 1f, 0.2f, Dimension.RelativeToSelf, 0.5f, Dimension.RelativeToSelf, 0.5f);
2 scale.FillAfter = true;
3 scale.Duration = 1000;

 

 

Interpolator屬性可用參考圖:

 

 

關於Xamarin下如何強制選單在ActionBar中顯示

1             ViewConfiguration config = ViewConfiguration.Get(this);
2             var f = config.Class.GetDeclaredField("sHasPermanentMenuKey");
3             f.Accessible = true;
4             f.SetBoolean(config, false);

      因為Android系統規定存在物理選單鍵的情況下選單是不會顯示到ActionBar中的,所以我們需要通過修改ViewConfiguration中的私有欄位sHasPermanentMenuKey將其改為false即可,但是在實際測試中發現,部分手機必須強制Menu的ActionFlags為Always。

 

關於Xamarin下使用Http報InvalidCastException異常

      通過查閱官方資料發現這個是Xamarin本身的Bug,但是這個Bug實在是太大。會導致整個App的穩定性下降,重點是這個異常無法通過try…catch捕獲,一旦發生就閃退,特別實在短時間內頻繁使用Http的情況下,該解決方案只有將Xamarin.Android升級到4.12.5以及以上才可以(對於破解黨來說又要開始折騰重新安裝了)

 

相關文章