Xamarin.Android之SlidingMenu
一、前言
有位網友在評論中希望能夠出個在Xamarin.Android下實作SlidingMenu效果的随筆,剛好昨天在觀看官網示例項目的時候也看到這個SlidingMenu,但是最終的效果并不是我們所期待的,至此筆者就在官方的論壇中尋找,最後也成功的尋找到的答案,下面筆者将帶領帶領大家實作SlidingMenu。
二、準備工作
實作SlidingMenu重點是需要一個第三方的類庫,筆者已經把部分重要的方法注釋了,下面是下載下傳位址:
從Github下載下傳
從百度網盤下載下傳
注:我們的項目不僅僅需要引用這個類庫還需要引用自帶的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動畫