xamarin android实现Toolbar+DrawerLayout完美侧滑导航栏

版权声明:本文为博主原创文章,未经博主允许转载随意。 https://blog.csdn.net/kebi007/article/details/77854178

前言

如果你有关注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
转载随意注明出处

猜你喜欢

转载自blog.csdn.net/kebi007/article/details/77854178