一、前言
有位網友在評論中希望能夠出個在Xamarin.Android下實現SlidingMenu效果的隨筆,剛好昨天在觀看官網示例項目的時候也看到這個SlidingMenu,但是最終的效果並不是我們所期待的,至此筆者就在官方的論壇中尋找,最后也成功的尋找到的答案,下面筆者將帶領帶領大家實現SlidingMenu。
二、准備工作
實現SlidingMenu重點是需要一個第三方的類庫,筆者已經把部分重要的方法注釋了,下面是下載地址:
注:我們的項目不僅僅需要引用這個類庫還需要引用自帶的Mono.Android.Support.v4類庫,可從 圖 1.1 找到該類庫。
圖 1.1
三、正文
新建項目筆者就不多說了,然后我們按照第二步的要求引用需要的類庫后在Resource/layout下新建一個視圖並命名為menu,然后在其中拖放幾個Button控件,而這個視圖將是我們滑動菜單的界面,最后我們就可以打開MainActivity.cs並在其中寫入如下代碼:
1 protected override void OnCreate(Bundle bundle) 2 { 3 base.OnCreate(bundle); 4 SetContentView(Resource.Layout.Main); 5 //實例化 6 var sm = new SlidingMenu(this); 7 //指定滑動菜單的視圖 8 sm.SetMenu(Resource.Layout.menu); 9 //將滑動菜單附加到Activity上 10 sm.AttachToActivity(this, SlidingMenuSharp.SlideStyle.Window); 11 }
其中需要說明的是AttachToActivity方法的第二個參數,這個參數指定了SlidingMenu如何附加到Activity上,在視覺效果上指定了Window則當滑動的時候ActionBar也會跟着滑動,如果是Content則ActionBar不會跟着滑動,我們可以查看圖 1.2 和 1.3 分別是Window和Content情況下的效果(默認需要從邊框開始滑動才可以,並不是全屏)。
圖1.2
圖1.3
但是上面的這種SlidingMenu可不是我們所希望的那種SlidingMenu,況且Xamarin的官方示例里面也有這種效果,所以下面我們要讓滑動菜單只顯示部分,並且可以通過滑動全屏的任意部分呼出菜單,所以我們將代碼改寫成如下所示:
1 protected override void OnCreate(Bundle bundle) 2 { 3 base.OnCreate(bundle); 4 SetContentView(Resource.Layout.Main); 5 var sm = new SlidingMenu(this); 6 sm.SetMenu(Resource.Layout.menu); 7 //指定主界面顯示的寬度 8 sm.BehindOffset = 100; 9 sm.TouchModeAbove = TouchMode.Fullscreen; 10 sm.AttachToActivity(this, SlidingMenuSharp.SlideStyle.Content); 11 }
其中需要說明的是BehindOffset屬性,通過注釋我們可以知道它是用來指定滑動菜單完全顯示后主界面的可視部分的寬度,也可以BehindOffsetRes來指定,只是這個屬性必須使用資源的標識符來賦值。我們除了可以指定主界面也可以指定滑動菜單顯示的寬度,對應的屬性就是BehindWidth和BehindWidthRes。
現在我們的SlidingMenu已經有點樣子了,但是還沒有完全結束,后面我們將會不斷的美化它,讓它更加符合實際項目的需要。
首先我們需要講解的是BehindScrollScale屬性,它的效果就是控制滑動菜單在划出時滑動的強度,取值范圍為0~1,我們可以通過圖 1.4 和 1.5 看出取值為0和1時候的滑動效果。
圖1.4
圖 1.5
通過圖1.4和圖1.5我們可以清楚的看到這個屬性的作用,你會發現當設置為1的時候跟ViewPager很相似了。
還有另一個屬性就是FadeDegree和FadeEnabled,第一個是控制漸變效果的強度,第二個則決定是否使用漸變效果,我們還是通過圖片來演示FadeDegree在0和1的情況下分別是什么樣的效果,圖 1.6 和 圖 1.7分別對應取值為0和1時的效果。
圖1.6
圖1.7
通過圖1.6和1.7我們可以清楚的看出在剛滑動的時候他們的顏色是不同的,並且在不斷滑動的過程中會漸漸變淡,而這個屬性的作用就是用來控制它。然而還有一個比較嚴重的問題就是滑動菜單和我們的主界面之間沒有分割線,但是我們又不能直接用一條線,這樣顯的很不美觀,那么我們就可以自己設置一個漸變效果,首先我們需要在Resource/drawable下新建一個xml文件,並命名為shadow,在其中寫入如下內容:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <shape xmlns:android="http://schemas.android.com/apk/res/android"> 3 <gradient 4 android:endColor="#00000000" 5 android:centerColor="#11000000" 6 android:startColor="#33000000" ></gradient> 7 </shape>
通過以上內容我們指定了一個漸變效果的,剩下的我們需要使用這個資源:
1 var sm = new SlidingMenu(this); 2 sm.SetMenu(Resource.Layout.menu); 3 4 sm.FadeEnabled = true; 5 sm.FadeDegree = 1f; 6 sm.BehindOffset = 100; 7 sm.ShadowDrawableRes = Resource.Drawable.shadow; 8 sm.ShadowWidth = 15; 9 sm.BehindScrollScale = 0f; 10 sm.TouchModeAbove = TouchMode.Fullscreen; 11 sm.AttachToActivity(this, SlidingMenuSharp.SlideStyle.Content); 12 }
這里我們通過ShadowDrawableRes屬性使用這個資源,並通過ShadowWidth屬性控制它的寬度,最后我們運行程序就可以看到一個漸變的分割線了圖1.8:
圖1.8
上面我們只是把滑動菜單都放在了左邊,實際上我們可以將滑動菜單放在右邊或者兩邊都有,比如在原本的代碼上加上這句代碼后就可以在左邊呈現了。
1 sm.Mode = MenuMode.Right; 2 sm.SetSecondaryMenu(Resource.Layout.menu);
第一個屬性用來控制滑動菜單的模式,第二個就是指定右邊的滑動菜單的內容。講到這里大家獲取會疑惑怎么才好監聽滑動菜單里的事件呢?其實滑動菜單就是整個Activity的一部分,所以在其中的控件都是可以通過FindViewById獲取到的,當然筆者建議讀者采用Fragment將代碼分離,SlidingMenu的SetContent方法可以直接改變主界面的視圖。
除了我們自己新建SlidingMenu,我們還可以讓活動繼承SlidingFragmentActivity類,這樣我們就直接可以通過控制SlidingMenu屬性,而不需要實例化一個,也不需要調用AttachToActivity附加到Activity上,比如我們將上面的代碼改寫成如下所示
1 protected override void OnCreate(Bundle bundle) 2 { 3 base.OnCreate(bundle); 4 SetContentView(Resource.Layout.Main); 5 SetBehindContentView(Resource.Layout.menu); 6 SlidingMenu.FadeEnabled = true; 7 SlidingMenu.FadeDegree = 1f; 8 SlidingMenu.BehindOffset = 100; 9 SlidingMenu.ShadowDrawableRes = Resource.Drawable.shadow; 10 SlidingMenu.ShadowWidth = 15; 11 SlidingMenu.BehindScrollScale = 0f; 12 SlidingMenu.Mode = MenuMode.Right; 13 SlidingMenu.SetSecondaryMenu(Resource.Layout.menu); 14 SlidingMenu.TouchModeAbove = TouchMode.Fullscreen; 15 }
我們需要注意SetBehindContentView方法,這個方法必須調用,但是它的功能實際上跟SetMenu是一樣的,是用來設置滑動菜單的界面的,讀者通過查看最終的結果可以發現ActionBar又跟着主界面動了,但是我們沒了AttachToActivity方法就不好指定枚舉了,這個時候我們需要使用SetSlidingActionBarEnabled方法,並傳入false即可。
讀者在使用實際的app中一定會發現SlidingMenu呈現的動畫會有許多中,當然我們也有許多種呈現方式,只需要給BehindCanvasTransformer屬性賦值即可,內置的動畫有ZoomTransformer、SlideTransformer和ScaleTransformer,當然他們都是類,是需要初始化的,我們通過下圖來演示不同的動畫效果如何:
ZoomTransformer動畫
SlideTransformer動畫
ScaleTransformer動畫
最后還要介紹的就是我們可以通過Toggle、ShowContent和ShowMenu手動控制SlidingMenu的呈現。