Translate動畫
這個動畫是最常使用到的,主要就是將控制元件從一個位置移動到另一個位置,並且還可以在這其中增加一定的效果,下面我們將採用兩種方式實現動畫,首選的是利用XML來製作動畫,其次就是利用程式碼。
首先我們在Resources中新建一個名為anim的資料夾,然後在該資料夾下新建兩個xml,分別命名為in_from_bottom和out_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>
對應的程式碼部分改成如下所示:
我們可以看到動畫檔案需要利用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實際上只有fromAlpha和toAlpha屬性,其他的屬性都是公用的,是不是非常的簡單,然後我們再把活動的程式碼改回之前的樣子,使用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>
其中fromDegreses和toDegrees就是從多少度翻轉到多少度,pivotX和pivotY則需要重點介紹,既然是翻轉,自然要有中心。預設情況的中心就是左上角,通過給這兩個值賦上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" />
這裡的pivotY和pivotX跟上上節的使用方式是相同的,對應fromXScale、fromYScale、toXScale和toYScale的作用就是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以及以上才可以(對於破解黨來說又要開始折騰重新安裝了)。