引言

说起这个侧滑菜单,自从QQ改版以后,这个功能是我们每天必见的了,对吧!手势贴最左边,向右滑动就会呼出侧滑菜单的各种功能入口,比如头像资料、钱包、文件、设置等等,还有知乎首页从右往左可以呼出最近浏览记录,很多APP都有这种功能~~


概述

我们都知道Google从发布Android M后,增加一个全新的支持库Android Design Support Library,其中包含了多个重要的 Material Design 组件,可用于将 Material Design 向下兼容到 Android 2.1 (API 7) 。

(1)
在Material Design中,NavigationView 可以方便地创建导航抽屉,被设计于应用导航,它提供了一种通用的导航方式,体现了 Google 设计的一致性。
NavigationView 的典型用途就是配合之前v4包的 DrawerLayout,作为其中的Drawer部分,即导航菜单的本体部分。它只需要接收两个重要的参数:一个用于显示头部的 header 布局(可选),另一个是用于建立导向选项的 menu 菜单。添加完之后,设置监听事件就可以了,更简单高效的实现了导航菜单。
当然,它还提供了不错的默认样式、选中项高亮、分组单选、分组子标题。

(2)
Toolbar 也是在 Android M 开始推出的一个 Material Design 风格的导航控件 ,Google 非常推荐大家使用 Toolbar 来作为客户端的导航栏,以此来取代之前的 Actionbar 。
Toolbar与 Actionbar 相比明显要灵活,它不一定要固定在顶部,可以放到界面的任意位置、还可以设置导航栏图标、设置 APP 的 Logo、支持设置标题和子标题、支持添加一个或多个的自定义控件、支持 Action Menu等等吧。


展示

那么今天就简单介绍一下使用 NavigationView 和 DrawerLayout ,当然还有 Toolbar 绘制最简单的侧滑菜单,效果展示如下:

android侧滑栏菜单 安卓侧边栏快捷应用_android侧滑栏菜单


开撸

1、既然使用 Design Support Library,首先需要在工程中添加依赖:

compile 'com.android.support:design:24.2.1'

2、 添加后,我们开始写主界面的 Activity,activity_main.xml代码如下:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout_drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/drawer_coord"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <include layout="@layout/layout_tab" />

    </android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/view_nav"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/activity_main_header"
        app:menu="@menu/activity_main_drawer" />

</android.support.v4.widget.DrawerLayout>

正如你所见,最外层是 DrawerLayout,它分为侧边菜单和主内容区两部分,侧边菜单可以根据手势展开与隐藏(DrawerLayout 自身特性),注意的是CoordinatorLayout作用是协调其他组件, 实现联动,怎么具体实现的我暂时也不懂~~ 它里面仅仅 include了一个 Toolbar,当然还有 NavigationView 实现抽屉,里面有俩重要的属性,app:headerLayout 是头布局,app:menu 是菜单资源。

3、附上 include 的 layout_tab.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="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:layout_scrollFlags="scroll|enterAlways"
        app:tabIndicatorColor="@android:color/white"
        app:tabIndicatorHeight="4dp" />
    
</LinearLayout>

4、activity_main_header.xml 设置了背景图一张,如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:background="@mipmap/header"
    android:gravity="top">

</RelativeLayout>

5、还有 activity_main_drawer.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <group android:checkableBehavior="single">
        <item android:title="@string/app_name">
            <menu>
                <item
                    android:id="@+id/select_city"
                    android:icon="@drawable/ic_location"
                    android:title="@string/select_city" />
                <item
                    android:id="@+id/manage_cities"
                    android:icon="@drawable/ic_manage_cities"
                    android:title="@string/manage_cities" />
            </menu>
        </item>
    </group>

    <item android:title="@string/app_name">
        <menu>
            <item
                android:id="@+id/weather_set"
                android:icon="@drawable/ic_set"
                android:title="@string/weather_set" />
            <item
                android:id="@+id/weather_about"
                android:icon="@drawable/ic_about"
                android:title="@string/weather_about" />
        </menu>
    </item>
</menu>

易见,这是 menu 资源文件,其中,加一层 group 会有分割线将 group 包裹的内容隔开。

6、最后,就是我们的 MainActivity.java 代码了,如下:

public class MainActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener {

    Toolbar toolbar;
    NavigationView navView;
    DrawerLayout drawerLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        navView = (NavigationView) findViewById(R.id.view_nav);
        drawerLayout = (DrawerLayout) findViewById(R.id.layout_drawer);
        initDrawer();
    }


    /**
     * 初始化抽屉
     */
    private void initDrawer() {
        setSupportActionBar(toolbar);//设定 Toolbar 取代原本的 actionbar
        if (navView != null) {
            navView.setNavigationItemSelectedListener(this);//设置监听
            navView.setItemIconTintList(null);//保持图标本色

            //比如布局完成滑出、布局隐藏或者布局正在滑动的时候都会有一个回调的监听事件,
            //而ActionBarDrawerToggle就是DrawerLayout事件的监听器
            ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                    this,
                    drawerLayout,
                    toolbar,
                    R.string.navigation_drawer_open,
                    R.string.navigation_drawer_close
            );
            //该方法会自动和actionBar关联, 将开关的图片显示在了actionBar上
            toggle.syncState();
            drawerLayout.addDrawerListener(toggle);

        }
    }


    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.select_city:
                //跳转测试
                Intent intentSetting = new Intent(MainActivity.this, Main2Activity.class);
                startActivity(intentSetting);
                break;
        }

        drawerLayout.closeDrawer(GravityCompat.START);
        return true;
    }

}

逻辑很清晰,首先初始化组件和抽屉设置,最关键的实现接口、重写了 onNavigationItemSelected 方法,通过 getItemId 进行判断点击了 menu 资源布局的哪一个,然后进行相应逻辑处理,最后关闭 drawerLayout。这里仅仅测试了一下 Activity 跳转,Main2Activity 就不说了,更多的按需定制。

7、更多小细节

1)当然 AppTheme 我设置成了 Theme.AppCompat.DayNight.NoActionBar

2)图标资源我是从 阿里巴巴矢量库


普及姿势:

Android M 发布的时候,Google 提供了 Vector 的支持,但是 Vector 图像刚发布的时候,是只支持 Android 5.0+ 的,所以说那时候并没有什么卵用。不过自从 AppCompat 23.2 之后,Google 兼容了 Android 2.1 以上的所有系统,只需要引用 com.android.support:appcompat-v7:23.2.0 以上的版本就可以了。这时候,Vector应该算是迎来了它的春天。

Vector Drawable 相对于普通的 Drawable 来说,大概有以下好处:
1、可以自动进行适配。不需要通过分辨率来设置不同的图片。
2、可以大幅减少图像的体积。同样一张图,用 Vector 来实现,可能只有 PNG 的几十分之一。
3、使用简单方便。很多站点、设计工具,都可以直接导出 SVG 图像,从而转换成 Vector 图像。
4、功能强大。少量代码可以实现非常复杂的动画。
5、成熟、稳定,前端使用非常广泛。

SVG 和 Vector Drawable 就说这么一点点,心里有个数就好了,网上好多资源,想深入的可以继续搜索学习。


结束语

哈哈! 技术革新太快了,得紧紧跟着啊,虽然慢了不是一点两点,但是得有向上的心啊~~