xamarin android實現Toolbar+DrawerLayout完美側滑導航欄

前言

如果你有關注Material Design,會發現國內的一些app也在使用material Design這種設計,我常用的網易有道詞典就使用了Material Design的規範。

Google I/O 2014 發佈 Material Design,1sters 於 2014-09-09 上線中文版,並穩穩佔據百度和
Google material design 關鍵字的第一名。

歷時一年,官方已經新增 20+ 章節,我們再次發力,於「2015-08-16」翻譯校對完畢所有新增章節,重新發布。
極客學院教程鏈接:http://wiki.jikexueyuan.com/project/material-design/

Material Design,中文名:材料設計語言,是由Google推出的全新的設計語言,谷歌表示,這種設計語言旨在爲手機、平板電腦、臺式機和“其他平臺”提供更一致、更廣泛的“外觀和感覺”

17個使用Material Design風格的APP界面作品欣賞:http://www.shejidaren.com/17-apps-using-material-design.html
這裏就不多介紹Material Design了,這篇文章就來實現遵循Material Design規範,當然以下代碼實在xamarin android下實現的,使用DrawerLayout+Toolbar實現側滑動畫效果,兼容android4.3以上版本,以及兼容android4.4以上的“沉浸式”狀態欄的效果,最終實現的效果圖如下
這裏寫圖片描述
1. DrawerLayout的簡單使用
2. DrawerLayout+ToolBar實現側滑切換動畫效果
3. 完美解決沉浸式狀態欄兼容android4.4以上版本

1. DrawerLayout的簡單使用

DrawerLayout是v4包下提供的一種左右側滑的抽屜佈局效果,它是一個佈局控件,和Linearlayout 、RelativeLayout等佈局控件是一個概念,使用起來比較簡單,只需要按照drawerlayout的規定佈局就會有側滑的效果,官方建議Drawerlayout作爲根佈局,的確絕大部分都是這樣做的,qq就是的。一個規範側滑佈局包括:Draerlayout作爲根佈局、側滑佈局(使用layout_gravity=”start/left”標記便是側滑佈局)、主內容佈局。下面最簡單的一個佈局來就能實現最基本的側滑效果。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
   <!--主內容佈局-->
  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button android:id="@+id/btn_show"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="顯示側滑佈局"/>
  </LinearLayout>
  <!--側滑佈局-->
  <LinearLayout
    android:layout_height="match_parent"
    android:layout_width="320dp"
    android:id="@+id/drwerLayout"
    android:background="#ffffff"
    android:layout_gravity="start">
    <TextView android:id="@+id/tv_drawerContent"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:gravity="center_horizontal|center_vertical"
              android:text="側滑內容"/>
  </LinearLayout>
</android.support.v4.widget.DrawerLayout>

效果圖:
這裏寫圖片描述
activity代碼:

    [Activity(Label = "DrawerlayoutAndToolBar", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity, DrawerLayout.IDrawerListener
    {
        private DrawerLayout _drawerLayout;
        private Button btn_openDrawer;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView (Resource.Layout.Main);
            _drawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawerLayout);
            btn_openDrawer = FindViewById<Button>(Resource.Id.btn_openDrawer);

            btn_openDrawer.Click +=(s,e)=> {
                _drawerLayout.OpenDrawer((int)GravityFlags.Start);
            };
        }
        //側邊視圖已經打開時調用
        public void OnDrawerClosed(View drawerView)
        {
            System.Diagnostics.Debug.Write("側邊視圖已經關閉");
        }
        //側邊視圖已經關閉時調用
        public void OnDrawerOpened(View drawerView)
        {
            System.Diagnostics.Debug.Write("側邊視圖已經打開");
        }
        //側邊視圖正在滑動時調用
        public void OnDrawerSlide(View drawerView, float slideOffset)
        {
            System.Diagnostics.Debug.Write("側邊視圖已經關閉");
        }
        //側邊視圖滑動狀態發生改變時被調用
        public void OnDrawerStateChanged(int newState)
        {
            System.Diagnostics.Debug.Write("drawer的狀態"+newState);
            //狀態值STATE_IDLE:0是閒置狀態,STATE_DRAGGING:1拖拽狀態,STATE_SETTLING:2(固定狀態)
        }
    }

要注意以下幾點:

  • DrawerLayout的第一個子佈局必須是主內容佈局,如果第一個子佈局是側滑內容佈局,就會出現問題,這個你可以自己試試看,將這兩個佈局對換,就會發現通過手勢滑動能打開卻不能關閉,點擊才能關閉。
  • 側滑視圖的寬度不建議超過320dp,官方建議是留出一部分能看到主視圖
  • 必須指定側滑視圖,通過屬性layout_gravity來確定,屬性值有start、end或者left 、right。start是從左向右滑出,end是從右向左滑出
  • 繼承接口DrawerLayout.IDrawerListener,實現OnDrawerClosed、OnDrawerOpened、OnDrawerSlide、OnDrawerStateChanged等方法的監聽

2. DrawerLayout+ToolBar實現側滑切換動畫效果

在material design的標準下,我們將使用Drawerlayout+Toolbar實現一個圖標切換動畫的側滑效果。
在剛學習使用Toolbar的時候有很多的需要的點,可以看看這篇文章xamarin android toolbar(踩坑完全入門詳解),所以這裏就不多介紹如何使用Toolbar了。
從開頭的那張效果圖我們可以看出,明顯沒有將DrawerLayout作爲根佈局(官方建議還是作爲根佈局比較好)。
爲了提供的佈局的使用效率,首先我們新建一個toolbar的佈局toolbar_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fitsSystemWindows="true">
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:id="@+id/toolbar_title" />
    </android.support.v7.widget.Toolbar>
</LinearLayout>

然後我們再來新建一個Drawerlayout的規定佈局drawerLayout.xml
側邊的佈局是一個ListView一般都用來放置導航菜單的。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dl_left"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<!--主佈局-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/iv_main"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:gravity="center_horizontal"
            android:text="主佈局" />
    </LinearLayout>
<!--側滑菜單-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#fff"
        android:layout_gravity="start">
        <ListView
            android:id="@+id/left_menu"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:divider="@null"
            android:text="DrawerLayout" />
    </LinearLayout>
</android.support.v4.widget.DrawerLayout>

最後新建一個主佈局:Main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <include layout="@layout/toolbar_main" />
    <include layout="@layout/drawerLayout" />
</LinearLayout>

主題styles.xml

 <?xml version="1.0" encoding="utf-8" ?>
<resources>
  <style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primaryDark</item>
    <item name="drawerArrowStyle">@style/AppTheme.DrawerArrowToggle</item>
  </style>

  <style name="AppTheme.DrawerArrowToggle" parent="Base.Widget.AppCompat.DrawerArrowToggle">
    <item name="color">@android:color/white</item>
  </style>

  <color name="primary">#1e89e7</color>
  <color name="primaryDark">#1976d2</color>
  <color name="red">#ff0000</color>
  <color name="white">#ffffff</color>
</resources>

主要實現代碼MainActivity.cs

 [Activity(Label = "DrawerlayoutAndToolBar", MainLauncher = true, Icon = "@drawable/icon",Theme = "@style/BaseAppTheme")]
    public class MainActivity : AppCompatActivity
    {
        private DrawerLayout _drawerLayout;
        private ListView listview_leftMenu;
        private Android.Support.V7.Widget.Toolbar toolbar;
        private Android.Graphics.Drawables.AnimationDrawable _animationDrawable;
        private ActionBarDrawerToggle _drawerToggle;
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView (Resource.Layout.Main);
            _drawerLayout = FindViewById<DrawerLayout>(Resource.Id.dl_left);
            listview_leftMenu = FindViewById<ListView>(Resource.Id.left_menu);
            toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
            _drawerToggle = new ActionBarDrawerToggle(this, _drawerLayout, toolbar, 0,0);//並沒有起效果性作用
            string[] menus = new string[] { "首頁", "博問", "閃存" };
            ArrayAdapter adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleExpandableListItem1,menus);
            listview_leftMenu.Adapter = adapter;

            toolbar.Title = "Toolbar1";
            SetSupportActionBar(toolbar);//設置兼容toolbar,替代原本的actionbar

            //SupportActionBar.SetDisplayShowHomeEnabled(true);//設置顯示左上角Home圖標
            //SupportActionBar.SetDisplayHomeAsUpEnabled(true);//設置左上角的左箭頭; 這兩個必須同時爲true才能顯示
            SupportActionBar.SetDisplayShowTitleEnabled(true);//設置不顯示標題
            SupportActionBar.SetHomeButtonEnabled(true);//設置返回鍵可用 
            SupportActionBar.Title = "Toolbar";
            toolbar.Title = "Toolbar1";
            toolbar.SetTitleTextColor(Resources.GetColor(Resource.Color.white));

            _drawerLayout.SetDrawerListener(_drawerToggle); //設置側滑監聽
            _drawerToggle.SyncState(); //設置左箭頭與Home圖標的切換與側滑同步
            StatusBarUtil.SetColorStatusBar(this);
        }

        //圖標動畫效切換的關鍵:響應action 按鈕的點擊事件,包括左側系統的home按鈕,left按鈕,右側自定義的菜單等
        public override bool OnOptionsItemSelected(IMenuItem item)
        {
            return base.OnOptionsItemSelected(item) || _drawerToggle.OnOptionsItemSelected(item);
            //_drawerToggle.OnOptionsItemSelected(item)兼容android5.0以下的左側圖標切換的動畫,不加這句android5.0以下的左上側按鈕無效
        }
    }

代碼比較簡單,都註釋了。但最尷尬的是toolbar的標題顯示不出來,這的確是個問題,在SetSupportActionBar(toolbar)前設置toolbar.title還是沒有效果。
ActionBarDrawerToggle是繼承DrawerLayout.IDrawerListener,主要的作用是監聽DrawerLayout的滑動,還帶有切換toolbar左上角的home圖標和向左圖標的動畫效果。

3. 完美解決沉浸式狀態欄兼容android4.4以上版本

兼容android4.4“沉浸式”狀態欄及以上版本無非就是兩種辦法1.填充狀態欄2.MaginTop,詳情參照:http://blog.csdn.net/kebi007/article/details/70215993
這裏給我的完美解決方法,使用的是填充狀態欄。給它做了一個工具類

 public class StatusBarUtil
    {
        private static View _statusBarView;
        /// <summary>
        /// 設置顏色狀態欄
        /// </summary>
        /// <param name="activity"></param>
        public static void SetColorStatusBar(Activity activity)
        {
            if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
            {
                var color = activity.Resources.GetColor(Resource.Color.primary);
                //清除透明狀態欄,使內容不再覆蓋狀態欄  
                activity.Window.ClearFlags(WindowManagerFlags.TranslucentStatus);
                activity.Window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
                activity.Window.SetStatusBarColor(color);
                //透明導航欄部分手機導航欄不是虛擬的
                //activity.Window.AddFlags(WindowManagerFlags.TranslucentNavigation);
                activity.Window.SetNavigationBarColor(color);
            }
            else if (Build.VERSION.SdkInt == BuildVersionCodes.Kitkat )
            {
                SetKKStatusBar(activity,Resource.Color.primary);
            }
        }
        //設置透明狀態欄,android4.4以上都支持透明化狀態
        public static void SetTransparentStausBar(Activity activity)
        {
            if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
            {
                //狀態欄透明  
                activity.Window.AddFlags(WindowManagerFlags.TranslucentStatus);
                //透明導航欄  
                activity.Window.AddFlags(WindowManagerFlags.TranslucentNavigation);
            }
        }
        public static void SetKKStatusBar(Activity activity ,int statusBarColor)
        {
            SetTransparentStausBar(activity);//先透明化("去掉"狀態欄)
            ViewGroup contentView = activity.FindViewById<ViewGroup>(Android.Resource.Id.Content);
            _statusBarView = contentView.GetChildAt(0);
            //防止重複添加statusBarView
            if (_statusBarView != null && _statusBarView.MeasuredHeight == GetStatusBarHeight(activity))
            {
                _statusBarView.SetBackgroundColor(activity.Resources.GetColor(statusBarColor));
                return;
            }
            _statusBarView = new View(activity);
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent,GetStatusBarHeight(activity));
            _statusBarView.SetBackgroundColor(activity.Resources.GetColor(statusBarColor));//填充的到狀態欄的view設置顏色
            contentView.AddView(_statusBarView,lp);
        }
        private static int GetStatusBarHeight(Context context)
        {
            int resourceId = context.Resources.GetIdentifier("status_bar_height", "dimen", "android");
            return context.Resources.GetDimensionPixelSize(resourceId);
        }
    }

總結:toolbar還是無法設置標題。。。。。。。。。

作者:張林
標題:xamarin android實現Toolbar+DrawerLayout完美側滑導航欄
原文地址:http://blog.csdn.net/kebi007/article/details/77854178
轉載隨意註明出處

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章